@@ -41,6 +41,9 @@ func (s AGPLIDPSync) SyncGroups(ctx context.Context, db database.Store, user dat
41
41
return nil
42
42
}
43
43
44
+ // nolint:gocritic // all syncing is done as a system user
45
+ ctx = dbauthz .AsSystemRestricted (ctx )
46
+
44
47
// Only care about the default org for deployment settings if the
45
48
// legacy deployment settings exist.
46
49
defaultOrgID := uuid .Nil
@@ -53,9 +56,6 @@ func (s AGPLIDPSync) SyncGroups(ctx context.Context, db database.Store, user dat
53
56
defaultOrgID = defaultOrganization .ID
54
57
}
55
58
56
- // nolint:gocritic // all syncing is done as a system user
57
- ctx = dbauthz .AsSystemRestricted (ctx )
58
-
59
59
err := db .InTx (func (tx database.Store ) error {
60
60
userGroups , err := tx .GetGroups (ctx , database.GetGroupsParams {
61
61
HasMemberID : user .ID ,
@@ -86,12 +86,12 @@ func (s AGPLIDPSync) SyncGroups(ctx context.Context, db database.Store, user dat
86
86
}
87
87
88
88
// Legacy deployment settings will override empty settings.
89
- if orgID == defaultOrgID && settings .GroupField == "" {
89
+ if orgID == defaultOrgID && settings .Field == "" {
90
90
settings = & GroupSyncSettings {
91
- GroupField : s .Legacy .GroupField ,
92
- LegacyGroupNameMapping : s .Legacy .GroupMapping ,
93
- RegexFilter : s .Legacy .GroupFilter ,
94
- AutoCreateMissingGroups : s .Legacy .CreateMissingGroups ,
91
+ Field : s .Legacy .GroupField ,
92
+ LegacyNameMapping : s .Legacy .GroupMapping ,
93
+ RegexFilter : s .Legacy .GroupFilter ,
94
+ AutoCreateMissing : s .Legacy .CreateMissingGroups ,
95
95
}
96
96
}
97
97
orgSettings [orgID ] = * settings
@@ -102,7 +102,7 @@ func (s AGPLIDPSync) SyncGroups(ctx context.Context, db database.Store, user dat
102
102
groupIDsToRemove := make ([]uuid.UUID , 0 )
103
103
// For each org, determine which groups the user should land in
104
104
for orgID , settings := range orgSettings {
105
- if settings .GroupField == "" {
105
+ if settings .Field == "" {
106
106
// No group sync enabled for this org, so do nothing.
107
107
continue
108
108
}
@@ -231,17 +231,25 @@ func (s AGPLIDPSync) ApplyGroupDifference(ctx context.Context, tx database.Store
231
231
}
232
232
233
233
type GroupSyncSettings struct {
234
- GroupField string `json:"field"`
235
- // GroupMapping maps from an OIDC group --> Coder group ID
236
- GroupMapping map [string ][]uuid.UUID `json:"mapping"`
237
- RegexFilter * regexp.Regexp `json:"regex_filter"`
238
- AutoCreateMissingGroups bool `json:"auto_create_missing_groups"`
239
- // LegacyGroupNameMapping is deprecated. It remaps an IDP group name to
234
+ // Field selects the claim field to be used as the created user's
235
+ // groups. If the group field is the empty string, then no group updates
236
+ // will ever come from the OIDC provider.
237
+ Field string `json:"field"`
238
+ // Mapping maps from an OIDC group --> Coder group ID
239
+ Mapping map [string ][]uuid.UUID `json:"mapping"`
240
+ // RegexFilter is a regular expression that filters the groups returned by
241
+ // the OIDC provider. Any group not matched by this regex will be ignored.
242
+ // If the group filter is nil, then no group filtering will occur.
243
+ RegexFilter * regexp.Regexp `json:"regex_filter"`
244
+ // AutoCreateMissing controls whether groups returned by the OIDC provider
245
+ // are automatically created in Coder if they are missing.
246
+ AutoCreateMissing bool `json:"auto_create_missing_groups"`
247
+ // LegacyNameMapping is deprecated. It remaps an IDP group name to
240
248
// a Coder group name. Since configuration is now done at runtime,
241
249
// group IDs are used to account for group renames.
242
250
// For legacy configurations, this config option has to remain.
243
- // Deprecated: Use GroupMapping instead.
244
- LegacyGroupNameMapping map [string ]string `json:"legacy_group_name_mapping,omitempty"`
251
+ // Deprecated: Use Mapping instead.
252
+ LegacyNameMapping map [string ]string `json:"legacy_group_name_mapping,omitempty"`
245
253
}
246
254
247
255
func (s * GroupSyncSettings ) Set (v string ) error {
@@ -275,7 +283,7 @@ type ExpectedGroup struct {
275
283
// We have to keep names because group sync supports syncing groups by name if
276
284
// the external IDP group name matches the Coder one.
277
285
func (s GroupSyncSettings ) ParseClaims (orgID uuid.UUID , mergedClaims jwt.MapClaims ) ([]ExpectedGroup , error ) {
278
- groupsRaw , ok := mergedClaims [s .GroupField ]
286
+ groupsRaw , ok := mergedClaims [s .Field ]
279
287
if ! ok {
280
288
return []ExpectedGroup {}, nil
281
289
}
@@ -290,7 +298,7 @@ func (s GroupSyncSettings) ParseClaims(orgID uuid.UUID, mergedClaims jwt.MapClai
290
298
group := group
291
299
292
300
// Legacy group mappings happen before the regex filter.
293
- mappedGroupName , ok := s .LegacyGroupNameMapping [group ]
301
+ mappedGroupName , ok := s .LegacyNameMapping [group ]
294
302
if ok {
295
303
group = mappedGroupName
296
304
}
@@ -302,7 +310,7 @@ func (s GroupSyncSettings) ParseClaims(orgID uuid.UUID, mergedClaims jwt.MapClai
302
310
}
303
311
}
304
312
305
- mappedGroupIDs , ok := s .GroupMapping [group ]
313
+ mappedGroupIDs , ok := s .Mapping [group ]
306
314
if ok {
307
315
for _ , gid := range mappedGroupIDs {
308
316
gid := gid
@@ -338,7 +346,7 @@ func (s GroupSyncSettings) HandleMissingGroups(ctx context.Context, tx database.
338
346
}
339
347
}
340
348
341
- if s .AutoCreateMissingGroups && len (missingGroups ) > 0 {
349
+ if s .AutoCreateMissing && len (missingGroups ) > 0 {
342
350
// Insert any missing groups. If the groups already exist, this is a noop.
343
351
_ , err := tx .InsertMissingGroups (ctx , database.InsertMissingGroupsParams {
344
352
OrganizationID : orgID ,
0 commit comments