Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit601652c

Browse files
committed
test enterprise parse
1 parent5d0f729 commit601652c

File tree

4 files changed

+238
-7
lines changed

4 files changed

+238
-7
lines changed

‎coderd/idpsync/role.go‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,19 @@ func (s AGPLIDPSync) syncSiteWideRoles(ctx context.Context, tx database.Store, u
214214
)
215215
}
216216

217-
_,err:=tx.UpdateUserRoles(ctx, database.UpdateUserRolesParams{
218-
GrantedRoles:filtered,
219-
ID:user.ID,
220-
})
221-
iferr!=nil {
222-
returnxerrors.Errorf("set site wide roles: %w",err)
217+
filtered=slice.Unique(filtered)
218+
slices.Sort(filtered)
219+
220+
existing:=slice.Unique(user.RBACRoles)
221+
slices.Sort(existing)
222+
if!slices.Equal(existing,filtered) {
223+
_,err:=tx.UpdateUserRoles(ctx, database.UpdateUserRolesParams{
224+
GrantedRoles:filtered,
225+
ID:user.ID,
226+
})
227+
iferr!=nil {
228+
returnxerrors.Errorf("set site wide roles: %w",err)
229+
}
223230
}
224231
returnnil
225232
}

‎coderd/idpsync/role_test.go‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package idpsync_test
22

33
import (
4+
"context"
5+
"database/sql"
6+
"encoding/json"
47
"testing"
58

69
"github.com/golang-jwt/jwt/v4"
710
"github.com/google/uuid"
811
"github.com/stretchr/testify/require"
12+
"go.uber.org/mock/gomock"
913
"golang.org/x/exp/slices"
1014

1115
"cdr.dev/slog/sloggers/slogtest"
1216
"github.com/coder/coder/v2/coderd/database"
1317
"github.com/coder/coder/v2/coderd/database/dbauthz"
1418
"github.com/coder/coder/v2/coderd/database/dbgen"
19+
"github.com/coder/coder/v2/coderd/database/dbmock"
1520
"github.com/coder/coder/v2/coderd/database/dbtestutil"
1621
"github.com/coder/coder/v2/coderd/idpsync"
1722
"github.com/coder/coder/v2/coderd/rbac"
@@ -281,6 +286,7 @@ func TestRoleSyncTable(t *testing.T) {
281286
allRoleIDs,err:=allRoles.RoleNames()
282287
require.NoError(t,err)
283288

289+
// Remove the org roles
284290
siteRoles:=slices.DeleteFunc(allRoleIDs,func(r rbac.RoleIdentifier)bool {
285291
returnr.IsOrgRole()
286292
})
@@ -290,3 +296,76 @@ func TestRoleSyncTable(t *testing.T) {
290296
},siteRoles)
291297
})
292298
}
299+
300+
// TestNoopNoDiff verifies if no role change occurs, no database call is taken
301+
// per organization. This limits the number of db calls to O(1) if there
302+
// are no changes. Which is the usual case, as user's roles do not change often.
303+
funcTestNoopNoDiff(t*testing.T) {
304+
ctx:=context.Background()
305+
ctrl:=gomock.NewController(t)
306+
mDB:=dbmock.NewMockStore(ctrl)
307+
308+
mgr:=runtimeconfig.NewManager()
309+
s:=idpsync.NewAGPLSync(slogtest.Make(t,&slogtest.Options{}),mgr, idpsync.DeploymentSyncSettings{
310+
SiteRoleField:"",
311+
SiteRoleMapping:nil,
312+
SiteDefaultRoles:nil,
313+
})
314+
315+
userID:=uuid.New()
316+
orgID:=uuid.New()
317+
siteRoles:= []string{rbac.RoleTemplateAdmin().Name,rbac.RoleAuditor().Name}
318+
orgRoles:= []string{rbac.RoleOrgAuditor(),rbac.RoleOrgAdmin()}
319+
// The DB mock expects.
320+
// If this test fails, feel free to add more expectations.
321+
// The primary expectations to avoid is 'UpdateUserRoles'
322+
// and 'UpdateMemberRoles'.
323+
mDB.EXPECT().InTx(
324+
gomock.Any(),gomock.Any(),
325+
).DoAndReturn(func(ffunc(database.Store)error,_*sql.TxOptions)error {
326+
err:=f(mDB)
327+
returnerr
328+
})
329+
330+
mDB.EXPECT().OrganizationMembers(gomock.Any(), database.OrganizationMembersParams{
331+
UserID:userID,
332+
}).Return([]database.OrganizationMembersRow{
333+
{
334+
OrganizationMember: database.OrganizationMember{
335+
UserID:userID,
336+
OrganizationID:orgID,
337+
Roles:orgRoles,
338+
},
339+
},
340+
},nil)
341+
342+
mDB.EXPECT().GetRuntimeConfig(gomock.Any(),gomock.Any()).Return(
343+
string(must(json.Marshal(idpsync.RoleSyncSettings{
344+
Field:"roles",
345+
Mapping:nil,
346+
}))),nil)
347+
348+
err:=s.SyncRoles(ctx,mDB, database.User{
349+
ID:userID,
350+
Email:"alice@email.com",
351+
Username:"alice",
352+
Status:database.UserStatusActive,
353+
RBACRoles:siteRoles,
354+
LoginType:database.LoginTypePassword,
355+
}, idpsync.RoleParams{
356+
SyncEnabled:true,
357+
SyncSiteWide:true,
358+
SiteWideRoles:siteRoles,
359+
MergedClaims: jwt.MapClaims{
360+
"roles":orgRoles,
361+
},
362+
})
363+
require.NoError(t,err)
364+
}
365+
366+
funcmust[Tany](valueT,errerror)T {
367+
iferr!=nil {
368+
panic(err)
369+
}
370+
returnvalue
371+
}

‎enterprise/coderd/enidpsync/role.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"cdr.dev/slog"
1111
"github.com/coder/coder/v2/coderd/idpsync"
12+
"github.com/coder/coder/v2/coderd/util/slice"
1213
"github.com/coder/coder/v2/codersdk"
1314
)
1415

@@ -61,7 +62,7 @@ func (e EnterpriseIDPSync) ParseRoleClaims(ctx context.Context, mergedClaims jwt
6162
return idpsync.RoleParams{
6263
SyncEnabled:e.RoleSyncEnabled(),
6364
SyncSiteWide:e.AGPLIDPSync.SiteRoleField!="",
64-
SiteWideRoles:siteRoles,
65+
SiteWideRoles:slice.Unique(siteRoles),
6566
MergedClaims:mergedClaims,
6667
},nil
6768
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package enidpsync_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/golang-jwt/jwt/v4"
8+
"github.com/stretchr/testify/require"
9+
10+
"cdr.dev/slog/sloggers/slogtest"
11+
"github.com/coder/coder/v2/coderd/entitlements"
12+
"github.com/coder/coder/v2/coderd/idpsync"
13+
"github.com/coder/coder/v2/coderd/rbac"
14+
"github.com/coder/coder/v2/coderd/runtimeconfig"
15+
"github.com/coder/coder/v2/codersdk"
16+
"github.com/coder/coder/v2/enterprise/coderd/enidpsync"
17+
)
18+
19+
funcTestEnterpriseParseRoleClaims(t*testing.T) {
20+
t.Parallel()
21+
22+
entitled:=entitlements.New()
23+
entitled.Update(func(en*codersdk.Entitlements) {
24+
en.Features[codersdk.FeatureUserRoleManagement]= codersdk.Feature{
25+
Entitlement:codersdk.EntitlementEntitled,
26+
Enabled:true,
27+
}
28+
})
29+
30+
t.Run("NotEntitled",func(t*testing.T) {
31+
t.Parallel()
32+
33+
mgr:=runtimeconfig.NewManager()
34+
s:=enidpsync.NewSync(slogtest.Make(t,nil),mgr,entitlements.New(), idpsync.DeploymentSyncSettings{})
35+
36+
params,err:=s.ParseRoleClaims(context.Background(), jwt.MapClaims{})
37+
require.Nil(t,err)
38+
require.False(t,params.SyncEnabled)
39+
require.False(t,params.SyncSiteWide)
40+
})
41+
42+
t.Run("NotEntitledButEnabled",func(t*testing.T) {
43+
t.Parallel()
44+
// Since it is not entitled, it should not be enabled
45+
46+
mgr:=runtimeconfig.NewManager()
47+
s:=enidpsync.NewSync(slogtest.Make(t,nil),mgr,entitlements.New(), idpsync.DeploymentSyncSettings{
48+
SiteRoleField:"roles",
49+
})
50+
51+
params,err:=s.ParseRoleClaims(context.Background(), jwt.MapClaims{})
52+
require.Nil(t,err)
53+
require.False(t,params.SyncEnabled)
54+
require.False(t,params.SyncSiteWide)
55+
})
56+
57+
t.Run("SiteDisabled",func(t*testing.T) {
58+
t.Parallel()
59+
60+
mgr:=runtimeconfig.NewManager()
61+
s:=enidpsync.NewSync(slogtest.Make(t,nil),mgr,entitled, idpsync.DeploymentSyncSettings{})
62+
63+
params,err:=s.ParseRoleClaims(context.Background(), jwt.MapClaims{})
64+
require.Nil(t,err)
65+
require.True(t,params.SyncEnabled)
66+
require.False(t,params.SyncSiteWide)
67+
})
68+
69+
t.Run("SiteEnabled",func(t*testing.T) {
70+
t.Parallel()
71+
72+
mgr:=runtimeconfig.NewManager()
73+
s:=enidpsync.NewSync(slogtest.Make(t,nil),mgr,entitled, idpsync.DeploymentSyncSettings{
74+
SiteRoleField:"roles",
75+
SiteRoleMapping:map[string][]string{},
76+
SiteDefaultRoles: []string{rbac.RoleTemplateAdmin().Name},
77+
})
78+
79+
params,err:=s.ParseRoleClaims(context.Background(), jwt.MapClaims{
80+
"roles": []string{rbac.RoleAuditor().Name},
81+
})
82+
require.Nil(t,err)
83+
require.True(t,params.SyncEnabled)
84+
require.True(t,params.SyncSiteWide)
85+
require.ElementsMatch(t, []string{
86+
rbac.RoleTemplateAdmin().Name,
87+
rbac.RoleAuditor().Name,
88+
},params.SiteWideRoles)
89+
})
90+
91+
t.Run("SiteMapping",func(t*testing.T) {
92+
t.Parallel()
93+
94+
mgr:=runtimeconfig.NewManager()
95+
s:=enidpsync.NewSync(slogtest.Make(t,nil),mgr,entitled, idpsync.DeploymentSyncSettings{
96+
SiteRoleField:"roles",
97+
SiteRoleMapping:map[string][]string{
98+
"foo": {rbac.RoleAuditor().Name,rbac.RoleUserAdmin().Name},
99+
"bar": {rbac.RoleOwner().Name},
100+
},
101+
SiteDefaultRoles: []string{rbac.RoleTemplateAdmin().Name},
102+
})
103+
104+
params,err:=s.ParseRoleClaims(context.Background(), jwt.MapClaims{
105+
"roles": []string{"foo","bar","random"},
106+
})
107+
require.Nil(t,err)
108+
require.True(t,params.SyncEnabled)
109+
require.True(t,params.SyncSiteWide)
110+
require.ElementsMatch(t, []string{
111+
rbac.RoleTemplateAdmin().Name,
112+
rbac.RoleAuditor().Name,
113+
rbac.RoleUserAdmin().Name,
114+
rbac.RoleOwner().Name,
115+
// Invalid claims are still passed at this point
116+
"random",
117+
},params.SiteWideRoles)
118+
})
119+
120+
t.Run("DuplicateRoles",func(t*testing.T) {
121+
t.Parallel()
122+
123+
mgr:=runtimeconfig.NewManager()
124+
s:=enidpsync.NewSync(slogtest.Make(t,nil),mgr,entitled, idpsync.DeploymentSyncSettings{
125+
SiteRoleField:"roles",
126+
SiteRoleMapping:map[string][]string{
127+
"foo": {rbac.RoleOwner().Name,rbac.RoleAuditor().Name},
128+
"bar": {rbac.RoleOwner().Name},
129+
},
130+
SiteDefaultRoles: []string{rbac.RoleAuditor().Name},
131+
})
132+
133+
params,err:=s.ParseRoleClaims(context.Background(), jwt.MapClaims{
134+
"roles": []string{"foo","bar",rbac.RoleAuditor().Name,rbac.RoleOwner().Name},
135+
})
136+
require.Nil(t,err)
137+
require.True(t,params.SyncEnabled)
138+
require.True(t,params.SyncSiteWide)
139+
require.ElementsMatch(t, []string{
140+
rbac.RoleAuditor().Name,
141+
rbac.RoleOwner().Name,
142+
},params.SiteWideRoles)
143+
})
144+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp