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

Commit0ad5f60

Browse files
authored
chore: prevent removing members from the default organization (#14094)
* chore: prevent removing members from the default organizationUntil multi-organizations is released outside an experiment, theexperiment should be backwards compatible.
1 parent173dc0e commit0ad5f60

File tree

5 files changed

+127
-74
lines changed

5 files changed

+127
-74
lines changed

‎cli/organizationmembers_test.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -34,49 +34,3 @@ func TestListOrganizationMembers(t *testing.T) {
3434
require.Contains(t,buf.String(),owner.UserID.String())
3535
})
3636
}
37-
38-
funcTestRemoveOrganizationMembers(t*testing.T) {
39-
t.Parallel()
40-
41-
t.Run("OK",func(t*testing.T) {
42-
t.Parallel()
43-
44-
ownerClient:=coderdtest.New(t,&coderdtest.Options{})
45-
owner:=coderdtest.CreateFirstUser(t,ownerClient)
46-
orgAdminClient,_:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID,rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
47-
_,user:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID)
48-
49-
ctx:=testutil.Context(t,testutil.WaitMedium)
50-
51-
inv,root:=clitest.New(t,"organization","members","remove","-O",owner.OrganizationID.String(),user.Username)
52-
clitest.SetupConfig(t,orgAdminClient,root)
53-
54-
buf:=new(bytes.Buffer)
55-
inv.Stdout=buf
56-
err:=inv.WithContext(ctx).Run()
57-
require.NoError(t,err)
58-
59-
members,err:=orgAdminClient.OrganizationMembers(ctx,owner.OrganizationID)
60-
require.NoError(t,err)
61-
62-
require.Len(t,members,2)
63-
})
64-
65-
t.Run("UserNotExists",func(t*testing.T) {
66-
t.Parallel()
67-
68-
ownerClient:=coderdtest.New(t,&coderdtest.Options{})
69-
owner:=coderdtest.CreateFirstUser(t,ownerClient)
70-
orgAdminClient,_:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID,rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
71-
72-
ctx:=testutil.Context(t,testutil.WaitMedium)
73-
74-
inv,root:=clitest.New(t,"organization","members","remove","-O",owner.OrganizationID.String(),"random_name")
75-
clitest.SetupConfig(t,orgAdminClient,root)
76-
77-
buf:=new(bytes.Buffer)
78-
inv.Stdout=buf
79-
err:=inv.WithContext(ctx).Run()
80-
require.ErrorContains(t,err,"must be an existing uuid or username")
81-
})
82-
}

‎coderd/members.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request
106106
aReq.Old=member.OrganizationMember.Auditable(member.Username)
107107
defercommitAudit()
108108

109+
iforganization.IsDefault {
110+
// Multi-organizations is currently an experiment, which means it is feasible
111+
// for a deployment to enable, then disable this. To maintain backwards
112+
// compatibility, this safety is necessary.
113+
// TODO: Remove this check when multi-organizations is fully supported.
114+
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
115+
Message:"Removing members from the default organization is not supported.",
116+
Detail:"Multi-organizations is currently an experiment, and until it is fully supported, the default org should be protected.",
117+
Validations:nil,
118+
})
119+
return
120+
}
121+
109122
ifmember.UserID==apiKey.UserID {
110123
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{Message:"cannot remove self from an organization"})
111124
return

‎coderd/members_test.go

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,54 +30,41 @@ func TestAddMember(t *testing.T) {
3030
})
3131
}
3232

33-
funcTestListMembers(t*testing.T) {
33+
funcTestDeleteMember(t*testing.T) {
3434
t.Parallel()
3535

36-
t.Run("OK",func(t*testing.T) {
36+
t.Run("NotAllowed",func(t*testing.T) {
3737
t.Parallel()
3838
owner:=coderdtest.New(t,nil)
3939
first:=coderdtest.CreateFirstUser(t,owner)
40+
_,user:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID)
4041

41-
client,user:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID))
42-
43-
ctx:=testutil.Context(t,testutil.WaitShort)
44-
members,err:=client.OrganizationMembers(ctx,first.OrganizationID)
45-
require.NoError(t,err)
46-
require.Len(t,members,2)
47-
require.ElementsMatch(t,
48-
[]uuid.UUID{first.UserID,user.ID},
49-
db2sdk.List(members,onlyIDs))
42+
ctx:=testutil.Context(t,testutil.WaitMedium)
43+
// Deleting members from the default org is not allowed.
44+
// If this behavior changes, and we allow deleting members from the default org,
45+
// this test should be updated to check there is no error.
46+
// nolint:gocritic // must be an owner to see the user
47+
err:=owner.DeleteOrganizationMember(ctx,first.OrganizationID,user.Username)
48+
require.ErrorContains(t,err,"Multi-organizations is currently an experiment")
5049
})
5150
}
5251

53-
funcTestRemoveMember(t*testing.T) {
52+
funcTestListMembers(t*testing.T) {
5453
t.Parallel()
5554

5655
t.Run("OK",func(t*testing.T) {
5756
t.Parallel()
5857
owner:=coderdtest.New(t,nil)
5958
first:=coderdtest.CreateFirstUser(t,owner)
60-
orgAdminClient,orgAdmin:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID))
61-
_,user:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID)
6259

63-
ctx:=testutil.Context(t,testutil.WaitMedium)
64-
// Verify the org of 3 members
65-
members,err:=orgAdminClient.OrganizationMembers(ctx,first.OrganizationID)
66-
require.NoError(t,err)
67-
require.Len(t,members,3)
68-
require.ElementsMatch(t,
69-
[]uuid.UUID{first.UserID,user.ID,orgAdmin.ID},
70-
db2sdk.List(members,onlyIDs))
71-
72-
// Delete a member
73-
err=orgAdminClient.DeleteOrganizationMember(ctx,first.OrganizationID,user.Username)
74-
require.NoError(t,err)
60+
client,user:=coderdtest.CreateAnotherUser(t,owner,first.OrganizationID,rbac.ScopedRoleOrgAdmin(first.OrganizationID))
7561

76-
members,err=orgAdminClient.OrganizationMembers(ctx,first.OrganizationID)
62+
ctx:=testutil.Context(t,testutil.WaitShort)
63+
members,err:=client.OrganizationMembers(ctx,first.OrganizationID)
7764
require.NoError(t,err)
7865
require.Len(t,members,2)
7966
require.ElementsMatch(t,
80-
[]uuid.UUID{first.UserID,orgAdmin.ID},
67+
[]uuid.UUID{first.UserID,user.ID},
8168
db2sdk.List(members,onlyIDs))
8269
})
8370
}

‎enterprise/cli/organizationmembers_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,64 @@ import (
1515
"github.com/coder/coder/v2/testutil"
1616
)
1717

18+
funcTestRemoveOrganizationMembers(t*testing.T) {
19+
t.Parallel()
20+
21+
t.Run("OK",func(t*testing.T) {
22+
t.Parallel()
23+
dv:=coderdtest.DeploymentValues(t)
24+
dv.Experiments= []string{string(codersdk.ExperimentMultiOrganization)}
25+
26+
ownerClient,_:=coderdenttest.New(t,&coderdenttest.Options{
27+
Options:&coderdtest.Options{
28+
DeploymentValues:dv,
29+
},
30+
LicenseOptions:&coderdenttest.LicenseOptions{
31+
Features: license.Features{
32+
codersdk.FeatureMultipleOrganizations:1,
33+
},
34+
},
35+
})
36+
37+
secondOrganization:=coderdenttest.CreateOrganization(t,ownerClient, coderdenttest.CreateOrganizationOptions{})
38+
orgAdminClient,_:=coderdtest.CreateAnotherUser(t,ownerClient,secondOrganization.ID,rbac.ScopedRoleOrgAdmin(secondOrganization.ID))
39+
_,user:=coderdtest.CreateAnotherUser(t,ownerClient,secondOrganization.ID)
40+
41+
ctx:=testutil.Context(t,testutil.WaitMedium)
42+
43+
inv,root:=clitest.New(t,"organization","members","remove","-O",secondOrganization.ID.String(),user.Username)
44+
clitest.SetupConfig(t,orgAdminClient,root)
45+
46+
buf:=new(bytes.Buffer)
47+
inv.Stdout=buf
48+
err:=inv.WithContext(ctx).Run()
49+
require.NoError(t,err)
50+
51+
members,err:=orgAdminClient.OrganizationMembers(ctx,secondOrganization.ID)
52+
require.NoError(t,err)
53+
54+
require.Len(t,members,2)
55+
})
56+
57+
t.Run("UserNotExists",func(t*testing.T) {
58+
t.Parallel()
59+
60+
ownerClient:=coderdtest.New(t,&coderdtest.Options{})
61+
owner:=coderdtest.CreateFirstUser(t,ownerClient)
62+
orgAdminClient,_:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID,rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
63+
64+
ctx:=testutil.Context(t,testutil.WaitMedium)
65+
66+
inv,root:=clitest.New(t,"organization","members","remove","-O",owner.OrganizationID.String(),"random_name")
67+
clitest.SetupConfig(t,orgAdminClient,root)
68+
69+
buf:=new(bytes.Buffer)
70+
inv.Stdout=buf
71+
err:=inv.WithContext(ctx).Run()
72+
require.ErrorContains(t,err,"must be an existing uuid or username")
73+
})
74+
}
75+
1876
funcTestEnterpriseListOrganizationMembers(t*testing.T) {
1977
t.Parallel()
2078

‎enterprise/members_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,47 @@ import (
1818
funcTestEnterpriseMembers(t*testing.T) {
1919
t.Parallel()
2020

21+
t.Run("Remove",func(t*testing.T) {
22+
t.Parallel()
23+
dv:=coderdtest.DeploymentValues(t)
24+
dv.Experiments= []string{string(codersdk.ExperimentMultiOrganization)}
25+
owner,first:=coderdenttest.New(t,&coderdenttest.Options{
26+
Options:&coderdtest.Options{
27+
DeploymentValues:dv,
28+
},
29+
LicenseOptions:&coderdenttest.LicenseOptions{
30+
Features: license.Features{
31+
codersdk.FeatureMultipleOrganizations:1,
32+
},
33+
},
34+
})
35+
36+
secondOrg:=coderdenttest.CreateOrganization(t,owner, coderdenttest.CreateOrganizationOptions{})
37+
38+
orgAdminClient,orgAdmin:=coderdtest.CreateAnotherUser(t,owner,secondOrg.ID,rbac.ScopedRoleOrgAdmin(secondOrg.ID))
39+
_,user:=coderdtest.CreateAnotherUser(t,owner,secondOrg.ID)
40+
41+
ctx:=testutil.Context(t,testutil.WaitMedium)
42+
// Verify the org of 3 members
43+
members,err:=orgAdminClient.OrganizationMembers(ctx,secondOrg.ID)
44+
require.NoError(t,err)
45+
require.Len(t,members,3)
46+
require.ElementsMatch(t,
47+
[]uuid.UUID{first.UserID,user.ID,orgAdmin.ID},
48+
db2sdk.List(members,onlyIDs))
49+
50+
// Delete a member
51+
err=orgAdminClient.DeleteOrganizationMember(ctx,secondOrg.ID,user.Username)
52+
require.NoError(t,err)
53+
54+
members,err=orgAdminClient.OrganizationMembers(ctx,secondOrg.ID)
55+
require.NoError(t,err)
56+
require.Len(t,members,2)
57+
require.ElementsMatch(t,
58+
[]uuid.UUID{first.UserID,orgAdmin.ID},
59+
db2sdk.List(members,onlyIDs))
60+
})
61+
2162
t.Run("PostUser",func(t*testing.T) {
2263
t.Parallel()
2364

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp