mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat: add template setting to require active template version (#10277)
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@ -101,9 +102,10 @@ type querier struct {
|
||||
db database.Store
|
||||
auth rbac.Authorizer
|
||||
log slog.Logger
|
||||
acs *atomic.Pointer[AccessControlStore]
|
||||
}
|
||||
|
||||
func New(db database.Store, authorizer rbac.Authorizer, logger slog.Logger) database.Store {
|
||||
func New(db database.Store, authorizer rbac.Authorizer, logger slog.Logger, acs *atomic.Pointer[AccessControlStore]) database.Store {
|
||||
// If the underlying db store is already a querier, return it.
|
||||
// Do not double wrap.
|
||||
if slices.Contains(db.Wrappers(), wrapname) {
|
||||
@ -113,6 +115,7 @@ func New(db database.Store, authorizer rbac.Authorizer, logger slog.Logger) data
|
||||
db: db,
|
||||
auth: authorizer,
|
||||
log: logger,
|
||||
acs: acs,
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,7 +510,7 @@ func (q *querier) Ping(ctx context.Context) (time.Duration, error) {
|
||||
func (q *querier) InTx(function func(querier database.Store) error, txOpts *sql.TxOptions) error {
|
||||
return q.db.InTx(func(tx database.Store) error {
|
||||
// Wrap the transaction store in a querier.
|
||||
wrapped := New(tx, q.auth, q.log)
|
||||
wrapped := New(tx, q.auth, q.log, q.acs)
|
||||
return function(wrapped)
|
||||
}, txOpts)
|
||||
}
|
||||
@ -2200,7 +2203,7 @@ func (q *querier) InsertWorkspaceAppStats(ctx context.Context, arg database.Inse
|
||||
func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertWorkspaceBuildParams) error {
|
||||
w, err := q.db.GetWorkspaceByID(ctx, arg.WorkspaceID)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("get workspace by id: %w", err)
|
||||
}
|
||||
|
||||
var action rbac.Action = rbac.ActionUpdate
|
||||
@ -2209,7 +2212,28 @@ func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertW
|
||||
}
|
||||
|
||||
if err = q.authorizeContext(ctx, action, w.WorkspaceBuildRBAC(arg.Transition)); err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("authorize context: %w", err)
|
||||
}
|
||||
|
||||
// If we're starting a workspace we need to check the template.
|
||||
if arg.Transition == database.WorkspaceTransitionStart {
|
||||
t, err := q.db.GetTemplateByID(ctx, w.TemplateID)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get template by id: %w", err)
|
||||
}
|
||||
|
||||
accessControl := (*q.acs.Load()).GetTemplateAccessControl(t)
|
||||
|
||||
// If the template requires the active version we need to check if
|
||||
// the user is a template admin. If they aren't and are attempting
|
||||
// to use a non-active version then we must fail the request.
|
||||
if accessControl.RequireActiveVersion {
|
||||
if arg.TemplateVersionID != t.ActiveVersionID {
|
||||
if err = q.authorizeContext(ctx, rbac.ActionUpdate, t); err != nil {
|
||||
return xerrors.Errorf("cannot use non-active version: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return q.db.InsertWorkspaceBuild(ctx, arg)
|
||||
@ -2442,6 +2466,13 @@ func (q *querier) UpdateTemplateACLByID(ctx context.Context, arg database.Update
|
||||
return fetchAndExec(q.log, q.auth, rbac.ActionCreate, fetch, q.db.UpdateTemplateACLByID)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateTemplateAccessControlByID(ctx context.Context, arg database.UpdateTemplateAccessControlByIDParams) error {
|
||||
fetch := func(ctx context.Context, arg database.UpdateTemplateAccessControlByIDParams) (database.Template, error) {
|
||||
return q.db.GetTemplateByID(ctx, arg.ID)
|
||||
}
|
||||
return update(q.log, q.auth, fetch, q.db.UpdateTemplateAccessControlByID)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateTemplateActiveVersionByID(ctx context.Context, arg database.UpdateTemplateActiveVersionByIDParams) error {
|
||||
fetch := func(ctx context.Context, arg database.UpdateTemplateActiveVersionByIDParams) (database.Template, error) {
|
||||
return q.db.GetTemplateByID(ctx, arg.ID)
|
||||
|
Reference in New Issue
Block a user