@@ -26,7 +26,7 @@ type Renderer interface {
26
26
}
27
27
28
28
var (
29
- ErrorTemplateVersionNotReady error = xerrors .New ("template version job not finished" )
29
+ ErrorTemplateVersionNotReady = xerrors .New ("template version job not finished" )
30
30
)
31
31
32
32
// Loader is used to load the necessary coder objects for rendering a template
@@ -144,10 +144,11 @@ func (r *Loader) dynamicRenderer(ctx context.Context, db database.Store, cache *
144
144
}
145
145
146
146
return & DynamicRenderer {
147
- data : r ,
148
- templateFS : templateFS ,
149
- db : db ,
150
- plan : plan ,
147
+ data : r ,
148
+ templateFS : templateFS ,
149
+ db : db ,
150
+ plan : plan ,
151
+ failedOwners : make (map [uuid.UUID ]error ),
151
152
close : func () {
152
153
cache .Release (r .job .FileID )
153
154
if moduleFilesFS != nil {
@@ -171,8 +172,14 @@ type DynamicRenderer struct {
171
172
}
172
173
173
174
func (r * DynamicRenderer ) Render (ctx context.Context , ownerID uuid.UUID , values map [string ]string ) (* preview.Output , hcl.Diagnostics ) {
174
- err := r .getWorkspaceOwnerData (ctx , ownerID )
175
- if err != nil || r .currentOwner == nil {
175
+ // Always start with the cached error, if we have one.
176
+ ownerErr := r .failedOwners [ownerID ]
177
+ if ownerErr == nil {
178
+ ownerErr = r .getWorkspaceOwnerData (ctx , ownerID )
179
+ }
180
+
181
+ if ownerErr != nil || r .currentOwner == nil {
182
+ r .failedOwners [ownerID ] = ownerErr
176
183
return nil , hcl.Diagnostics {
177
184
{
178
185
Severity : hcl .DiagError ,
@@ -199,16 +206,24 @@ func (r *DynamicRenderer) getWorkspaceOwnerData(ctx context.Context, ownerID uui
199
206
return nil // already fetched
200
207
}
201
208
202
- if r .failedOwners [ownerID ] != nil {
203
- // previously failed, do not try again
204
- return r .failedOwners [ownerID ]
205
- }
206
-
207
209
var g errgroup.Group
208
210
209
- // TODO: @emyrk we should only need read access on the org member, not the
210
- // site wide user object. Figure out a better way to handle this.
211
- user , err := r .db .GetUserByID (ctx , ownerID )
211
+ // You only need to be able to read the organization member to get the owner
212
+ // data. Only the terraform files can therefore leak more information than the
213
+ // caller should have access to. All this info should be public assuming you can
214
+ // read the user though.
215
+ mem , err := database .ExpectOne (r .db .OrganizationMembers (ctx , database.OrganizationMembersParams {
216
+ OrganizationID : r .data .templateVersion .OrganizationID ,
217
+ UserID : ownerID ,
218
+ IncludeSystem : false ,
219
+ }))
220
+ if err != nil {
221
+ return err
222
+ }
223
+
224
+ // User data is required for the form. Org member is checked above
225
+ // nolint:gocritic
226
+ user , err := r .db .GetUserByID (dbauthz .AsProvisionerd (ctx ), mem .OrganizationMember .UserID )
212
227
if err != nil {
213
228
return xerrors .Errorf ("fetch user: %w" , err )
214
229
}
@@ -218,7 +233,7 @@ func (r *DynamicRenderer) getWorkspaceOwnerData(ctx context.Context, ownerID uui
218
233
// nolint:gocritic // This is kind of the wrong query to use here, but it
219
234
// matches how the provisioner currently works. We should figure out
220
235
// something that needs less escalation but has the correct behavior.
221
- row , err := r .db .GetAuthorizationUserRoles (dbauthz .AsSystemRestricted (ctx ), ownerID )
236
+ row , err := r .db .GetAuthorizationUserRoles (dbauthz .AsProvisionerd (ctx ), ownerID )
222
237
if err != nil {
223
238
return err
224
239
}
@@ -248,7 +263,7 @@ func (r *DynamicRenderer) getWorkspaceOwnerData(ctx context.Context, ownerID uui
248
263
// The correct public key has to be sent. This will not be leaked
249
264
// unless the template leaks it.
250
265
// nolint:gocritic
251
- key , err := r .db .GetGitSSHKey (dbauthz .AsSystemRestricted (ctx ), ownerID )
266
+ key , err := r .db .GetGitSSHKey (dbauthz .AsProvisionerd (ctx ), ownerID )
252
267
if err != nil {
253
268
return err
254
269
}
@@ -262,7 +277,7 @@ func (r *DynamicRenderer) getWorkspaceOwnerData(ctx context.Context, ownerID uui
262
277
// user, unless the template does it through the parameters. Regardless, we need
263
278
// the correct groups, and a user might not have read access.
264
279
// nolint:gocritic
265
- groups , err := r .db .GetGroups (dbauthz .AsSystemRestricted (ctx ), database.GetGroupsParams {
280
+ groups , err := r .db .GetGroups (dbauthz .AsProvisionerd (ctx ), database.GetGroupsParams {
266
281
OrganizationID : r .data .templateVersion .OrganizationID ,
267
282
HasMemberID : ownerID ,
268
283
})
@@ -282,10 +297,10 @@ func (r *DynamicRenderer) getWorkspaceOwnerData(ctx context.Context, ownerID uui
282
297
}
283
298
284
299
r .currentOwner = & previewtypes.WorkspaceOwner {
285
- ID : user . ID .String (),
286
- Name : user .Username ,
287
- FullName : user .Name ,
288
- Email : user .Email ,
300
+ ID : mem . OrganizationMember . UserID .String (),
301
+ Name : mem .Username ,
302
+ FullName : mem .Name ,
303
+ Email : mem .Email ,
289
304
LoginType : string (user .LoginType ),
290
305
RBACRoles : ownerRoles ,
291
306
SSHPublicKey : publicKey ,
0 commit comments