@@ -83,41 +83,53 @@ type provisionerDaemonAuth struct {
83
83
authorizer rbac.Authorizer
84
84
}
85
85
86
- // authorize returns mutated tags and true if the given HTTP request is authorized to access the provisioner daemon
87
- // protobuf API, and returns nil, false otherwise.
88
- func (p * provisionerDaemonAuth ) authorize (r * http.Request , orgID uuid.UUID , tags map [string ]string ) (map [string ]string , bool ) {
86
+ // authorize returns mutated tags if the given HTTP request is authorized to access the provisioner daemon
87
+ // protobuf API, and returns nil, err otherwise.
88
+ func (p * provisionerDaemonAuth ) authorize (r * http.Request , orgID uuid.UUID , tags map [string ]string ) (map [string ]string , error ) {
89
89
ctx := r .Context ()
90
- apiKey , ok := httpmw .APIKeyOptional (r )
91
- if ok {
90
+ apiKey , apiKeyOK := httpmw .APIKeyOptional (r )
91
+ pk , pkOK := httpmw .ProvisionerKeyAuthOptional (r )
92
+ provAuth := httpmw .ProvisionerDaemonAuthenticated (r )
93
+ if ! provAuth && ! apiKeyOK {
94
+ return nil , xerrors .New ("no API key or provisioner key provided" )
95
+ }
96
+ if apiKeyOK && pkOK {
97
+ return nil , xerrors .New ("Both API key and provisioner key authentication provided. Only one is allowed." )
98
+ }
99
+
100
+ if apiKeyOK {
92
101
tags = provisionersdk .MutateTags (apiKey .UserID , tags )
93
102
if tags [provisionersdk .TagScope ] == provisionersdk .ScopeUser {
94
103
// Any authenticated user can create provisioner daemons scoped
95
104
// for jobs that they own,
96
- return tags , true
105
+ return tags , nil
97
106
}
98
107
ua := httpmw .UserAuthorization (r )
99
- if err := p .authorizer .Authorize (ctx , ua , policy .ActionCreate , rbac .ResourceProvisionerDaemon .InOrg (orgID )); err == nil {
100
- // User is allowed to create provisioner daemons
101
- return tags , true
108
+ err := p .authorizer .Authorize (ctx , ua , policy .ActionCreate , rbac .ResourceProvisionerDaemon .InOrg (orgID ))
109
+ if err != nil {
110
+ if ! provAuth {
111
+ return nil , xerrors .New ("user unauthorized" )
112
+ }
113
+
114
+ // If using provisioner key / PSK auth, the daemon is, by definition, scoped to the organization.
115
+ tags = provisionersdk .MutateTags (uuid .Nil , tags )
116
+ return tags , nil
102
117
}
103
- }
104
118
105
- // Check for provisioner key or PSK auth.
106
- provAuth := httpmw .ProvisionerDaemonAuthenticated (r )
107
- if ! provAuth {
108
- return nil , false
119
+ // User is allowed to create provisioner daemons
120
+ return tags , nil
109
121
}
110
122
111
123
pk , ok := httpmw .ProvisionerKeyAuthOptional (r )
112
124
if ok {
113
125
if pk .OrganizationID != orgID {
114
- return nil , false
126
+ return nil , xerrors . New ( "provisioner key unauthorized" )
115
127
}
116
128
}
117
129
118
130
// If using provisioner key / PSK auth, the daemon is, by definition, scoped to the organization.
119
131
tags = provisionersdk .MutateTags (uuid .Nil , tags )
120
- return tags , true
132
+ return tags , nil
121
133
}
122
134
123
135
// Serves the provisioner daemon protobuf API over a WebSocket.
@@ -180,12 +192,13 @@ func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request)
180
192
api .Logger .Warn (ctx , "unnamed provisioner daemon" )
181
193
}
182
194
183
- tags , authorized := api .provisionerDaemonAuth .authorize (r , organization .ID , tags )
184
- if ! authorized {
185
- api .Logger .Warn (ctx , "unauthorized provisioner daemon serve request" , slog .F ("tags" , tags ))
195
+ tags , err := api .provisionerDaemonAuth .authorize (r , organization .ID , tags )
196
+ if err != nil {
197
+ api .Logger .Warn (ctx , "unauthorized provisioner daemon serve request" , slog .F ("tags" , tags ), slog . Error ( err ) )
186
198
httpapi .Write (ctx , rw , http .StatusForbidden ,
187
199
codersdk.Response {
188
200
Message : fmt .Sprintf ("You aren't allowed to create provisioner daemons with scope %q" , tags [provisionersdk .TagScope ]),
201
+ Detail : err .Error (),
189
202
},
190
203
)
191
204
return
0 commit comments