MCPcopy Index your code
hub / github.com/coder/coder / authorize

Method authorize

coderd/wsbuilder/wsbuilder.go:1254–1328  ·  view source on GitHub ↗

authorize performs build authorization pre-checks using the provided authFunc

(authFunc func(action policy.Action, object rbac.Objecter) bool)

Source from the content-addressed store, hash-verified

1252
1253// authorize performs build authorization pre-checks using the provided authFunc
1254func (b *Builder) authorize(authFunc func(action policy.Action, object rbac.Objecter) bool) error {
1255 // Doing this up front saves a lot of work if the user doesn't have permission.
1256 // This is checked again in the dbauthz layer, but the check is cached
1257 // and will be a noop later.
1258 var action policy.Action
1259 switch b.trans {
1260 case database.WorkspaceTransitionDelete:
1261 action = policy.ActionDelete
1262 case database.WorkspaceTransitionStart:
1263 action = policy.ActionWorkspaceStart
1264 if b.workspace.DormantAt.Valid {
1265 // Dormant workspaces can't be started directly; they are
1266 // first "woken" by unsetting dormancy, which makes the
1267 // workspace.start permission apply.
1268 action = policy.ActionUpdate
1269 }
1270 case database.WorkspaceTransitionStop:
1271 action = policy.ActionWorkspaceStop
1272 default:
1273 msg := fmt.Sprintf("Transition %q not supported.", b.trans)
1274 return BuildError{http.StatusBadRequest, msg, xerrors.New(msg)}
1275 }
1276
1277 // Try default workspace authorization first
1278 authorized := authFunc(action, b.workspace)
1279
1280 // Special handling for prebuilt workspace deletion
1281 if !authorized && action == policy.ActionDelete && b.workspace.IsPrebuild() {
1282 authorized = authFunc(action, b.workspace.AsPrebuild())
1283 }
1284
1285 if !authorized {
1286 if authFunc(policy.ActionRead, b.workspace) {
1287 // If the user can read the workspace, but not delete/create/update. Show
1288 // a more helpful error. They are allowed to know the workspace exists.
1289 return BuildError{
1290 Status: http.StatusForbidden,
1291 Message: fmt.Sprintf("You do not have permission to %s this workspace.", action),
1292 Wrapped: xerrors.New(httpapi.ResourceForbiddenResponse.Detail),
1293 }
1294 }
1295 // We use the same wording as the httpapi to avoid leaking the existence of the workspace
1296 return BuildError{http.StatusNotFound, httpapi.ResourceNotFoundResponse.Message, xerrors.New(httpapi.ResourceNotFoundResponse.Message)}
1297 }
1298
1299 template, err := b.getTemplate()
1300 if err != nil {
1301 return BuildError{http.StatusInternalServerError, "failed to fetch template", err}
1302 }
1303
1304 // If custom state, deny request since user could be corrupting or leaking
1305 // cloud state.
1306 if b.state.explicit != nil || b.state.orphan {
1307 if !authFunc(policy.ActionUpdate, template.RBACObject()) {
1308 return BuildError{http.StatusForbidden, "Only template managers may provide custom state", xerrors.New("Only template managers may provide custom state")}
1309 }
1310 }
1311

Callers 1

buildTxMethod · 0.95

Calls 5

getTemplateMethod · 0.95
NewMethod · 0.65
IsPrebuildMethod · 0.65
AsPrebuildMethod · 0.65
RBACObjectMethod · 0.65

Tested by

no test coverage detected