Skip to content

Commit b2c7bdd

Browse files
committed
chore: improve code quality and add clarifying comments
1 parent afc5359 commit b2c7bdd

File tree

6 files changed

+54
-33
lines changed

6 files changed

+54
-33
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,30 @@ func (q *querier) authorizeContext(ctx context.Context, action policy.Action, ob
150150
return nil
151151
}
152152

153+
// authorizeWorkspace handles authorization for workspace resource types.
154+
// prebuilt_workspaces are a subset of workspaces, currently limited to
155+
// supporting delete operations. Therefore, if the action is delete or
156+
// update and the workspace is a prebuild, a prebuilt-specific authorization
157+
// is attempted first. If that fails, it falls back to normal workspace
158+
// authorization.
159+
// Note: Delete operations of workspaces requires both update and delete
160+
// permissions.
161+
func (q *querier) authorizeWorkspace(ctx context.Context, action policy.Action, workspace database.Workspace) error {
162+
var prebuiltErr error
163+
// Special handling for prebuilt_workspace deletion authorization check
164+
if (action == policy.ActionUpdate || action == policy.ActionDelete) && workspace.IsPrebuild() {
165+
// Try prebuilt-specific authorization first
166+
if prebuiltErr = q.authorizeContext(ctx, action, workspace.AsPrebuild()); prebuiltErr == nil {
167+
return nil
168+
}
169+
}
170+
// Fallback to normal workspace authorization check
171+
if err := q.authorizeContext(ctx, action, workspace); err != nil {
172+
return xerrors.Errorf("authorize context: %w", errors.Join(prebuiltErr, err))
173+
}
174+
return nil
175+
}
176+
153177
type authContextKey struct{}
154178

155179
// ActorFromContext returns the authorization subject from the context.
@@ -3915,15 +3939,9 @@ func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertW
39153939
action = policy.ActionWorkspaceStop
39163940
}
39173941

3918-
if action == policy.ActionDelete && w.IsPrebuild() {
3919-
if err := q.authorizeContext(ctx, action, w.PrebuildRBAC()); err != nil {
3920-
// Fallback to normal workspace auth check
3921-
if err = q.authorizeContext(ctx, action, w); err != nil {
3922-
return xerrors.Errorf("authorize context: %w", err)
3923-
}
3924-
}
3925-
} else if err = q.authorizeContext(ctx, action, w); err != nil {
3926-
return xerrors.Errorf("authorize context: %w", err)
3942+
// Special handling for prebuilt workspace deletion
3943+
if err := q.authorizeWorkspace(ctx, action, w); err != nil {
3944+
return err
39273945
}
39283946

39293947
// If we're starting a workspace we need to check the template.
@@ -3962,16 +3980,8 @@ func (q *querier) InsertWorkspaceBuildParameters(ctx context.Context, arg databa
39623980
return err
39633981
}
39643982

3965-
if workspace.IsPrebuild() {
3966-
err = q.authorizeContext(ctx, policy.ActionUpdate, workspace.PrebuildRBAC())
3967-
// Fallback to normal workspace auth check
3968-
if err != nil {
3969-
err = q.authorizeContext(ctx, policy.ActionUpdate, workspace)
3970-
}
3971-
} else {
3972-
err = q.authorizeContext(ctx, policy.ActionUpdate, workspace)
3973-
}
3974-
if err != nil {
3983+
// Special handling for prebuilt workspace deletion
3984+
if err := q.authorizeWorkspace(ctx, policy.ActionUpdate, workspace); err != nil {
39753985
return err
39763986
}
39773987

coderd/database/modelmethods.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,22 @@ func (w Workspace) WorkspaceTable() WorkspaceTable {
227227

228228
func (w Workspace) RBACObject() rbac.Object {
229229
// if w.IsPrebuild() {
230-
// return w.PrebuildRBAC()
230+
// return w.AsPrebuild()
231231
//}
232232
return w.WorkspaceTable().RBACObject()
233233
}
234234

235+
// IsPrebuild returns true if the workspace is a prebuild workspace.
236+
// A workspace is considered a prebuild if its owner is the prebuild system user.
235237
func (w Workspace) IsPrebuild() bool {
236238
// TODO: avoid import cycle
237239
return w.OwnerID == uuid.MustParse("c42fdf75-3097-471c-8c33-fb52454d81c0")
238240
}
239241

240-
func (w Workspace) PrebuildRBAC() rbac.Object {
242+
// AsPrebuild returns the RBAC object corresponding to the workspace type.
243+
// If the workspace is a prebuild, it returns a prebuilt_workspace RBAC object.
244+
// Otherwise, it returns a normal workspace RBAC object.
245+
func (w Workspace) AsPrebuild() rbac.Object {
241246
if w.IsPrebuild() {
242247
return rbac.ResourcePrebuiltWorkspace.WithID(w.ID).
243248
InOrg(w.OrganizationID).

coderd/rbac/object_gen.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/rbac/policy/policy.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,15 @@ var RBACPermissions = map[string]PermissionDefinition{
103103
Actions: workspaceActions,
104104
},
105105
"prebuilt_workspace": {
106-
Actions: map[Action]ActionDefinition{
107-
ActionRead: actDef("read prebuilt workspace"),
108-
ActionUpdate: actDef("update prebuilt workspace"),
106+
// Prebuilt_workspace actions currently apply only to delete operations.
107+
// To successfully delete a workspace, a user must have the following permissions:
108+
// * read: to read the current workspace state
109+
// * update: to modify workspace metadata and related resources during deletion
110+
// (e.g., updating the deleted field in the database)
111+
// * delete: to perform the actual deletion of the workspace
112+
Actions: map[Action]ActionDefinition{
113+
ActionRead: actDef("read prebuilt workspace data"),
114+
ActionUpdate: actDef("update prebuilt workspace settings"),
109115
ActionDelete: actDef("delete prebuilt workspace"),
110116
},
111117
},

coderd/workspacebuilds.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,16 +404,16 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
404404
ctx,
405405
tx,
406406
func(action policy.Action, object rbac.Objecter) bool {
407+
// Special handling for prebuilt workspace deletion
407408
if object.RBACObject().Type == rbac.ResourceWorkspace.Type && action == policy.ActionDelete {
408-
workspaceObj, ok := object.(database.Workspace)
409-
if ok {
410-
prebuild := workspaceObj.PrebuildRBAC()
411-
// Fallback to normal workspace auth check
412-
if auth := api.Authorize(r, action, prebuild); auth {
409+
if workspaceObj, ok := object.(database.Workspace); ok {
410+
// Try prebuilt-specific authorization first
411+
if auth := api.Authorize(r, action, workspaceObj.AsPrebuild()); auth {
413412
return auth
414413
}
415414
}
416415
}
416+
// Fallback to default authorization
417417
return api.Authorize(r, action, object)
418418
},
419419
audit.WorkspaceBuildBaggageFromRequest(r),

site/src/api/rbacresourcesGenerated.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ export const RBACResourceActions: Partial<
125125
},
126126
prebuilt_workspace: {
127127
delete: "delete prebuilt workspace",
128-
read: "read prebuilt workspace",
129-
update: "update prebuilt workspace",
128+
read: "read prebuilt workspace data",
129+
update: "update prebuilt workspace settings",
130130
},
131131
provisioner_daemon: {
132132
create: "create a provisioner daemon/key",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy