@@ -100,7 +100,7 @@ func (p *DBTokenProvider) Issue(ctx context.Context, rw http.ResponseWriter, r *
100
100
// Lookup workspace app details from DB.
101
101
dbReq , err := appReq .getDatabase (dangerousSystemCtx , p .Database )
102
102
if xerrors .Is (err , sql .ErrNoRows ) {
103
- WriteWorkspaceApp404 (p .Logger , p .DashboardURL , rw , r , & appReq , err .Error ())
103
+ WriteWorkspaceApp404 (p .Logger , p .DashboardURL , rw , r , & appReq , nil , err .Error ())
104
104
return nil , "" , false
105
105
} else if err != nil {
106
106
WriteWorkspaceApp500 (p .Logger , p .DashboardURL , rw , r , & appReq , err , "get app details from database" )
@@ -114,15 +114,15 @@ func (p *DBTokenProvider) Issue(ctx context.Context, rw http.ResponseWriter, r *
114
114
}
115
115
116
116
// Verify the user has access to the app.
117
- authed , err := p .authorizeRequest (r .Context (), authz , dbReq )
117
+ authed , warnings , err := p .authorizeRequest (r .Context (), authz , dbReq )
118
118
if err != nil {
119
119
WriteWorkspaceApp500 (p .Logger , p .DashboardURL , rw , r , & appReq , err , "verify authz" )
120
120
return nil , "" , false
121
121
}
122
122
if ! authed {
123
123
if apiKey != nil {
124
124
// The request has a valid API key but insufficient permissions.
125
- WriteWorkspaceApp404 (p .Logger , p .DashboardURL , rw , r , & appReq , "insufficient permissions" )
125
+ WriteWorkspaceApp404 (p .Logger , p .DashboardURL , rw , r , & appReq , warnings , "insufficient permissions" )
126
126
return nil , "" , false
127
127
}
128
128
@@ -218,7 +218,12 @@ func (p *DBTokenProvider) Issue(ctx context.Context, rw http.ResponseWriter, r *
218
218
return & token , tokenStr , true
219
219
}
220
220
221
- func (p * DBTokenProvider ) authorizeRequest (ctx context.Context , roles * httpmw.Authorization , dbReq * databaseRequest ) (bool , error ) {
221
+ // authorizeRequest returns true/false if the request is authorized. The returned []string
222
+ // are warnings that aid in debugging. These messages do not prevent authorization,
223
+ // but may indicate that the request is not configured correctly.
224
+ // If an error is returned, the request should be aborted with a 500 error.
225
+ func (p * DBTokenProvider ) authorizeRequest (ctx context.Context , roles * httpmw.Authorization , dbReq * databaseRequest ) (bool , []string , error ) {
226
+ var warnings []string
222
227
accessMethod := dbReq .AccessMethod
223
228
if accessMethod == "" {
224
229
accessMethod = AccessMethodPath
@@ -233,14 +238,15 @@ func (p *DBTokenProvider) authorizeRequest(ctx context.Context, roles *httpmw.Au
233
238
// Dangerous.AllowPathAppSiteOwnerAccess flag is enabled in the check below.
234
239
sharingLevel := dbReq .AppSharingLevel
235
240
if isPathApp && ! p .DeploymentValues .Dangerous .AllowPathAppSharing .Value () {
241
+ warnings = append (warnings , fmt .Sprintf ("path-based app sharing is disabled (see --dangerous-allow-path-app-sharing), forcing sharing level to \" owner\" , was %q" , sharingLevel ))
236
242
sharingLevel = database .AppSharingLevelOwner
237
243
}
238
244
239
245
// Short circuit if not authenticated.
240
246
if roles == nil {
241
247
// The user is not authenticated, so they can only access the app if it
242
248
// is public.
243
- return sharingLevel == database .AppSharingLevelPublic , nil
249
+ return sharingLevel == database .AppSharingLevelPublic , warnings , nil
244
250
}
245
251
246
252
// Block anyone from accessing workspaces they don't own in path-based apps
@@ -254,7 +260,8 @@ func (p *DBTokenProvider) authorizeRequest(ctx context.Context, roles *httpmw.Au
254
260
sharingLevel == database .AppSharingLevelOwner &&
255
261
dbReq .Workspace .OwnerID .String () != roles .Actor .ID &&
256
262
! p .DeploymentValues .Dangerous .AllowPathAppSiteOwnerAccess .Value () {
257
- return false , nil
263
+ warnings = append (warnings , "path-based apps with \" owner\" share level are only accessible by the workspace owner (see --dangerous-allow-path-app-site-owner-access)" )
264
+ return false , warnings , nil
258
265
}
259
266
260
267
// Figure out which RBAC resource to check. For terminals we use execution
@@ -280,7 +287,7 @@ func (p *DBTokenProvider) authorizeRequest(ctx context.Context, roles *httpmw.Au
280
287
// scope allows it).
281
288
err := p .Authorizer .Authorize (ctx , roles .Actor , rbacAction , rbacResource )
282
289
if err == nil {
283
- return true , nil
290
+ return true , warnings , nil
284
291
}
285
292
286
293
switch sharingLevel {
@@ -293,15 +300,15 @@ func (p *DBTokenProvider) authorizeRequest(ctx context.Context, roles *httpmw.Au
293
300
// to connect to the actor's own workspace. This enforces scopes.
294
301
err := p .Authorizer .Authorize (ctx , roles .Actor , rbacAction , rbacResourceOwned )
295
302
if err == nil {
296
- return true , nil
303
+ return true , warnings , nil
297
304
}
298
305
case database .AppSharingLevelPublic :
299
306
// We don't really care about scopes and stuff if it's public anyways.
300
307
// Someone with a restricted-scope API key could just not submit the API
301
308
// key cookie in the request and access the page.
302
- return true , nil
309
+ return true , warnings , nil
303
310
}
304
311
305
312
// No checks were successful.
306
- return false , nil
313
+ return false , warnings , nil
307
314
}
0 commit comments