@@ -14,6 +14,7 @@ import (
14
14
15
15
"cdr.dev/slog"
16
16
"github.com/coder/coder/coderd/database"
17
+ "github.com/coder/coder/coderd/database/dbauthz"
17
18
"github.com/coder/coder/coderd/httpapi"
18
19
"github.com/coder/coder/coderd/httpmw"
19
20
"github.com/coder/coder/coderd/rbac"
@@ -38,6 +39,12 @@ const (
38
39
//
39
40
// Upstream code should avoid any database calls ever.
40
41
func (p * Provider ) ResolveRequest (rw http.ResponseWriter , r * http.Request , appReq Request ) (* Ticket , bool ) {
42
+ // nolint:gocritic // We need to make a number of database calls. Setting a system context here
43
+ // // is simpler than calling dbauthz.AsSystemRestricted on every call.
44
+ // // dangerousSystemCtx is only used for database calls. The actual authentication
45
+ // // logic is handled in Provider.authorizeWorkspaceApp which directly checks the actor's
46
+ // // permissions.
47
+ dangerousSystemCtx := dbauthz .AsSystemRestricted (r .Context ())
41
48
err := appReq .Validate ()
42
49
if err != nil {
43
50
p .writeWorkspaceApp500 (rw , r , & appReq , err , "invalid app request" )
@@ -108,13 +115,14 @@ func (p *Provider) ResolveRequest(rw http.ResponseWriter, r *http.Request, appRe
108
115
userErr error
109
116
)
110
117
if userID , uuidErr := uuid .Parse (appReq .UsernameOrID ); uuidErr == nil {
111
- user , userErr = p .Database .GetUserByID (r . Context () , userID )
118
+ user , userErr = p .Database .GetUserByID (dangerousSystemCtx , userID )
112
119
} else {
113
- user , userErr = p .Database .GetUserByEmailOrUsername (r . Context () , database.GetUserByEmailOrUsernameParams {
120
+ user , userErr = p .Database .GetUserByEmailOrUsername (dangerousSystemCtx , database.GetUserByEmailOrUsernameParams {
114
121
Username : appReq .UsernameOrID ,
115
122
})
116
123
}
117
124
if xerrors .Is (userErr , sql .ErrNoRows ) {
125
+ // TODO: add coverage
118
126
p .writeWorkspaceApp404 (rw , r , & appReq , fmt .Sprintf ("user %q not found" , appReq .UsernameOrID ))
119
127
return nil , false
120
128
} else if userErr != nil {
@@ -129,9 +137,9 @@ func (p *Provider) ResolveRequest(rw http.ResponseWriter, r *http.Request, appRe
129
137
workspaceErr error
130
138
)
131
139
if workspaceID , uuidErr := uuid .Parse (appReq .WorkspaceNameOrID ); uuidErr == nil {
132
- workspace , workspaceErr = p .Database .GetWorkspaceByID (r . Context () , workspaceID )
140
+ workspace , workspaceErr = p .Database .GetWorkspaceByID (dangerousSystemCtx , workspaceID )
133
141
} else {
134
- workspace , workspaceErr = p .Database .GetWorkspaceByOwnerIDAndName (r . Context () , database.GetWorkspaceByOwnerIDAndNameParams {
142
+ workspace , workspaceErr = p .Database .GetWorkspaceByOwnerIDAndName (dangerousSystemCtx , database.GetWorkspaceByOwnerIDAndNameParams {
135
143
OwnerID : user .ID ,
136
144
Name : appReq .WorkspaceNameOrID ,
137
145
Deleted : false ,
@@ -153,15 +161,16 @@ func (p *Provider) ResolveRequest(rw http.ResponseWriter, r *http.Request, appRe
153
161
trustAgent = false
154
162
)
155
163
if agentID , uuidErr := uuid .Parse (appReq .AgentNameOrID ); uuidErr == nil {
156
- agent , agentErr = p .Database .GetWorkspaceAgentByID (r . Context () , agentID )
164
+ agent , agentErr = p .Database .GetWorkspaceAgentByID (dangerousSystemCtx , agentID )
157
165
} else {
158
- build , err := p .Database .GetLatestWorkspaceBuildByWorkspaceID (r . Context () , workspace .ID )
166
+ build , err := p .Database .GetLatestWorkspaceBuildByWorkspaceID (dangerousSystemCtx , workspace .ID )
159
167
if err != nil {
160
168
p .writeWorkspaceApp500 (rw , r , & appReq , err , "get latest workspace build" )
161
169
return nil , false
162
170
}
163
171
164
- resources , err := p .Database .GetWorkspaceResourcesByJobID (r .Context (), build .JobID )
172
+ // nolint:gocritic // We need to fetch the agent to authenticate the request. This is a system function.
173
+ resources , err := p .Database .GetWorkspaceResourcesByJobID (dangerousSystemCtx , build .JobID )
165
174
if err != nil {
166
175
p .writeWorkspaceApp500 (rw , r , & appReq , err , "get workspace resources" )
167
176
return nil , false
@@ -171,7 +180,8 @@ func (p *Provider) ResolveRequest(rw http.ResponseWriter, r *http.Request, appRe
171
180
resourcesIDs = append (resourcesIDs , resource .ID )
172
181
}
173
182
174
- agents , err := p .Database .GetWorkspaceAgentsByResourceIDs (r .Context (), resourcesIDs )
183
+ // nolint:gocritic // We need to fetch the agent to authenticate the request. This is a system function.
184
+ agents , err := p .Database .GetWorkspaceAgentsByResourceIDs (dangerousSystemCtx , resourcesIDs )
175
185
if err != nil {
176
186
p .writeWorkspaceApp500 (rw , r , & appReq , err , "get workspace agents" )
177
187
return nil , false
@@ -209,12 +219,13 @@ func (p *Provider) ResolveRequest(rw http.ResponseWriter, r *http.Request, appRe
209
219
210
220
// Verify the agent belongs to the workspace.
211
221
if ! trustAgent {
212
- agentResource , err := p .Database .GetWorkspaceResourceByID (r .Context (), agent .ResourceID )
222
+ //nolint:gocritic // We need to fetch the agent to authenticate the request. This is a system function.
223
+ agentResource , err := p .Database .GetWorkspaceResourceByID (dangerousSystemCtx , agent .ResourceID )
213
224
if err != nil {
214
225
p .writeWorkspaceApp500 (rw , r , & appReq , err , "get agent resource" )
215
226
return nil , false
216
227
}
217
- build , err := p .Database .GetWorkspaceBuildByJobID (r . Context () , agentResource .JobID )
228
+ build , err := p .Database .GetWorkspaceBuildByJobID (dangerousSystemCtx , agentResource .JobID )
218
229
if err != nil {
219
230
p .writeWorkspaceApp500 (rw , r , & appReq , err , "get agent workspace build" )
220
231
return nil , false
@@ -324,7 +335,8 @@ func (p *Provider) ResolveRequest(rw http.ResponseWriter, r *http.Request, appRe
324
335
// error while looking it up, an HTML error page is returned and false is
325
336
// returned so the caller can return early.
326
337
func (p * Provider ) lookupWorkspaceApp (rw http.ResponseWriter , r * http.Request , agentID uuid.UUID , appSlug string ) (database.WorkspaceApp , bool ) {
327
- app , err := p .Database .GetWorkspaceAppByAgentIDAndSlug (r .Context (), database.GetWorkspaceAppByAgentIDAndSlugParams {
338
+ // nolint:gocritic // We need to fetch the workspace app to authorize the request.
339
+ app , err := p .Database .GetWorkspaceAppByAgentIDAndSlug (dbauthz .AsSystemRestricted (r .Context ()), database.GetWorkspaceAppByAgentIDAndSlugParams {
328
340
AgentID : agentID ,
329
341
Slug : appSlug ,
330
342
})
0 commit comments