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

Commit979b3d8

Browse files
committed
chore: implement assign organization roles from the cli
Basic functionality to assign roles to an organization member via cli.
1 parente605d37 commit979b3d8

File tree

3 files changed

+115
-5
lines changed

3 files changed

+115
-5
lines changed

‎cli/organizationmembers.go

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"strings"
56

67
"golang.org/x/xerrors"
78

@@ -11,16 +12,71 @@ import (
1112
)
1213

1314
func (r*RootCmd)organizationMembers()*serpent.Command {
15+
cmd:=&serpent.Command{
16+
Use:"members",
17+
Aliases: []string{"member"},
18+
Short:"Manage organization members",
19+
Children: []*serpent.Command{
20+
r.listOrganizationMembers(),
21+
r.assignOrganizationRoles(),
22+
},
23+
}
24+
25+
returncmd
26+
}
27+
28+
func (r*RootCmd)assignOrganizationRoles()*serpent.Command {
29+
client:=new(codersdk.Client)
30+
31+
cmd:=&serpent.Command{
32+
Use:"edit-roles <username | user_id> [roles...]",
33+
Aliases: []string{"edit-role"},
34+
Short:"Edit organization member's roles",
35+
Middleware:serpent.Chain(
36+
r.InitClient(client),
37+
),
38+
Handler:func(inv*serpent.Invocation)error {
39+
ctx:=inv.Context()
40+
organization,err:=CurrentOrganization(r,inv,client)
41+
iferr!=nil {
42+
returnerr
43+
}
44+
45+
iflen(inv.Args)<1 {
46+
returnxerrors.Errorf("user_id or username is required as the first argument")
47+
}
48+
userIdentifier:=inv.Args[0]
49+
50+
member,err:=client.UpdateOrganizationMemberRoles(ctx,organization.ID,userIdentifier, codersdk.UpdateRoles{
51+
Roles:inv.Args[1:],
52+
})
53+
iferr!=nil {
54+
returnxerrors.Errorf("update member roles: %w",err)
55+
}
56+
57+
updatedTo:=make([]string,0)
58+
for_,role:=rangemember.Roles {
59+
updatedTo=append(updatedTo,role.String())
60+
}
61+
62+
_,_=fmt.Fprintf(inv.Stdout,"Member roles updated to [%s]\n",strings.Join(updatedTo,", "))
63+
returnnil
64+
},
65+
}
66+
67+
returncmd
68+
}
69+
70+
func (r*RootCmd)listOrganizationMembers()*serpent.Command {
1471
formatter:=cliui.NewOutputFormatter(
1572
cliui.TableFormat([]codersdk.OrganizationMemberWithName{}, []string{"username","organization_roles"}),
1673
cliui.JSONFormat(),
1774
)
1875

1976
client:=new(codersdk.Client)
2077
cmd:=&serpent.Command{
21-
Use:"members",
22-
Short:"List all organization members",
23-
Aliases: []string{"member"},
78+
Use:"list",
79+
Short:"List all organization members",
2480
Middleware:serpent.Chain(
2581
serpent.RequireNArgs(0),
2682
r.InitClient(client),

‎cli/organizationmembers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func TestListOrganizationMembers(t *testing.T) {
2323
client,user:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID,rbac.RoleUserAdmin())
2424

2525
ctx:=testutil.Context(t,testutil.WaitMedium)
26-
inv,root:=clitest.New(t,"organization","members","-c","user_id,username,roles")
26+
inv,root:=clitest.New(t,"organization","members","list","-c","user_id,username,roles")
2727
clitest.SetupConfig(t,client,root)
2828

2929
buf:=new(bytes.Buffer)

‎enterprise/cli/organizationmembers_test.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func TestEnterpriseListOrganizationMembers(t *testing.T) {
5353
OrganizationID:owner.OrganizationID,
5454
},rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
5555

56-
inv,root:=clitest.New(t,"organization","members","-c","user_id,username,organization_roles")
56+
inv,root:=clitest.New(t,"organization","members","list","-c","user_id,username,organization_roles")
5757
clitest.SetupConfig(t,client,root)
5858

5959
buf:=new(bytes.Buffer)
@@ -66,3 +66,57 @@ func TestEnterpriseListOrganizationMembers(t *testing.T) {
6666
require.Contains(t,buf.String(),customRole.DisplayName)
6767
})
6868
}
69+
70+
funcTestAssignOrganizationMemberRole(t*testing.T) {
71+
t.Parallel()
72+
73+
t.Run("OK",func(t*testing.T) {
74+
t.Parallel()
75+
dv:=coderdtest.DeploymentValues(t)
76+
dv.Experiments= []string{string(codersdk.ExperimentCustomRoles)}
77+
78+
ownerClient,owner:=coderdenttest.New(t,&coderdenttest.Options{
79+
Options:&coderdtest.Options{
80+
DeploymentValues:dv,
81+
},
82+
LicenseOptions:&coderdenttest.LicenseOptions{
83+
Features: license.Features{
84+
codersdk.FeatureCustomRoles:1,
85+
},
86+
},
87+
})
88+
_,user:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID,rbac.RoleUserAdmin())
89+
90+
ctx:=testutil.Context(t,testutil.WaitMedium)
91+
// nolint:gocritic // requires owner role to create
92+
customRole,err:=ownerClient.PatchOrganizationRole(ctx,owner.OrganizationID, codersdk.Role{
93+
Name:"custom-role",
94+
OrganizationID:owner.OrganizationID.String(),
95+
DisplayName:"Custom Role",
96+
SitePermissions:nil,
97+
OrganizationPermissions:codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
98+
codersdk.ResourceWorkspace: {codersdk.ActionRead},
99+
}),
100+
UserPermissions:nil,
101+
})
102+
require.NoError(t,err)
103+
104+
inv,root:=clitest.New(t,"organization","members","edit-roles",user.Username,codersdk.RoleOrganizationAdmin,customRole.Name)
105+
// nolint:gocritic // you cannot change your own roles
106+
clitest.SetupConfig(t,ownerClient,root)
107+
108+
buf:=new(bytes.Buffer)
109+
inv.Stdout=buf
110+
err=inv.WithContext(ctx).Run()
111+
require.NoError(t,err)
112+
require.Contains(t,buf.String(),must(rbac.RoleByName(rbac.ScopedRoleOrgAdmin(owner.OrganizationID))).DisplayName)
113+
require.Contains(t,buf.String(),customRole.DisplayName)
114+
})
115+
}
116+
117+
funcmust[Vany](vV,errerror)V {
118+
iferr!=nil {
119+
panic(err)
120+
}
121+
returnv
122+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp