chore: reorder prebuilt workspace authorization logic (#18506)

## Description

Follow-up from PR https://github.com/coder/coder/pull/18333
Related with:
https://github.com/coder/coder/pull/18333#discussion_r2159300881

This changes the authorization logic to first try the normal workspace
authorization check, and only if the resource is a prebuilt workspace,
fall back to the prebuilt workspace authorization check. Since prebuilt
workspaces are a subset of workspaces, the normal workspace check is
more likely to succeed. This is a small optimization to reduce
unnecessary prebuilt authorization calls.
This commit is contained in:
Susana Ferreira
2025-06-24 16:33:21 +01:00
committed by GitHub
parent 341b54e604
commit f44969b689
5 changed files with 55 additions and 29 deletions

View File

@ -5650,7 +5650,17 @@ func (s *MethodTestSuite) TestAuthorizePrebuiltWorkspace() {
Reason: database.BuildReasonInitiator,
TemplateVersionID: tv.ID,
JobID: pj.ID,
}).Asserts(w.AsPrebuild(), policy.ActionDelete)
}).
// Simulate a fallback authorization flow:
// - First, the default workspace authorization fails (simulated by returning an error).
// - Then, authorization is retried using the prebuilt workspace object, which succeeds.
// The test asserts that both authorization attempts occur in the correct order.
WithSuccessAuthorizer(func(ctx context.Context, subject rbac.Subject, action policy.Action, obj rbac.Object) error {
if obj.Type == rbac.ResourceWorkspace.Type {
return xerrors.Errorf("not authorized for workspace type")
}
return nil
}).Asserts(w, policy.ActionDelete, w.AsPrebuild(), policy.ActionDelete)
}))
s.Run("PrebuildUpdate/InsertWorkspaceBuildParameters", s.Subtest(func(db database.Store, check *expects) {
u := dbgen.User(s.T(), db, database.User{})
@ -5679,6 +5689,16 @@ func (s *MethodTestSuite) TestAuthorizePrebuiltWorkspace() {
})
check.Args(database.InsertWorkspaceBuildParametersParams{
WorkspaceBuildID: wb.ID,
}).Asserts(w.AsPrebuild(), policy.ActionUpdate)
}).
// Simulate a fallback authorization flow:
// - First, the default workspace authorization fails (simulated by returning an error).
// - Then, authorization is retried using the prebuilt workspace object, which succeeds.
// The test asserts that both authorization attempts occur in the correct order.
WithSuccessAuthorizer(func(ctx context.Context, subject rbac.Subject, action policy.Action, obj rbac.Object) error {
if obj.Type == rbac.ResourceWorkspace.Type {
return xerrors.Errorf("not authorized for workspace type")
}
return nil
}).Asserts(w, policy.ActionUpdate, w.AsPrebuild(), policy.ActionUpdate)
}))
}