Skip to content

Commit 73aa1aa

Browse files
committed
user show, invite, delete, list
1 parent 01eca3f commit 73aa1aa

File tree

15 files changed

+395
-86
lines changed

15 files changed

+395
-86
lines changed

astra-shell/src/main/java/com/datastax/astra/shell/AstraCli.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
import com.datastax.astra.shell.cmd.db.OperationsDb;
1616
import com.datastax.astra.shell.cmd.iam.RoleListCli;
1717
import com.datastax.astra.shell.cmd.iam.RoleShowCli;
18+
import com.datastax.astra.shell.cmd.iam.UserDeleteCli;
19+
import com.datastax.astra.shell.cmd.iam.UserInviteCli;
1820
import com.datastax.astra.shell.cmd.iam.UserListCli;
21+
import com.datastax.astra.shell.cmd.iam.UserShowCli;
1922
import com.datastax.astra.shell.cmd.shell.ShellCommand;
2023
import com.datastax.astra.shell.utils.LoggerShell;
2124
import com.github.rvesse.airline.annotations.Cli;
@@ -54,7 +57,10 @@
5457
RoleShowCli.class
5558
}),
5659
@Group(name= "user", description = "Manage the users permissions", commands = {
57-
UserListCli.class
60+
UserListCli.class,
61+
UserShowCli.class,
62+
UserInviteCli.class,
63+
UserDeleteCli.class
5864
}),
5965
@Group(name= "token", description = "Manage the security tokens", commands = {
6066

astra-shell/src/main/java/com/datastax/astra/shell/AstraShell.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import com.datastax.astra.shell.cmd.db.OperationsDb;
1010
import com.datastax.astra.shell.cmd.iam.RoleListShell;
1111
import com.datastax.astra.shell.cmd.iam.RoleShowCli;
12+
import com.datastax.astra.shell.cmd.iam.UserInviteShell;
1213
import com.datastax.astra.shell.cmd.iam.UserListShell;
14+
import com.datastax.astra.shell.cmd.iam.UserShowShell;
1315
import com.datastax.astra.shell.cmd.shell.ConnectCommand;
1416
import com.datastax.astra.shell.cmd.shell.CqlShCommand;
1517
import com.datastax.astra.shell.cmd.shell.EmptyCommand;
@@ -48,7 +50,9 @@
4850
RoleShowCli.class
4951
}),
5052
@Group(name= "user", description = "Manage the users permission", commands = {
51-
UserListShell.class
53+
UserListShell.class,
54+
UserShowShell.class,
55+
UserInviteShell.class
5256
}),
5357
@Group(name = "use", description = "Focus on an entity (context & prompt changed)", commands = {
5458
UseDb.class

astra-shell/src/main/java/com/datastax/astra/shell/ExitCode.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public enum ExitCode {
1919
/** conflict. */
2020
CONFLICT(409),
2121

22+
/** conflict. */
23+
ALREADY_EXIST(409),
24+
2225
/** code. */
2326
PARSE_ERROR(-1),
2427

astra-shell/src/main/java/com/datastax/astra/shell/cmd/BaseCommand.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ public void outputError(ExitCode code, String msg) {
6969
}
7070
}
7171

72+
/**
73+
* Exit program with no operation
74+
*
75+
* @param code
76+
* error code
77+
* @param msg
78+
* error message
79+
*/
80+
public void outputWarning(ExitCode code, String msg) {
81+
switch(format) {
82+
case json:
83+
LoggerShell.json(new JsonOutput(code, code.name() + ": " + msg));
84+
break;
85+
case csv:
86+
LoggerShell.csv(new CsvOutput(code, code.name() + ": " + msg));
87+
break;
88+
case human:
89+
default:
90+
LoggerShell.warning( code.name() + ": " + msg);
91+
break;
92+
}
93+
}
94+
7295
/**
7396
* Exit program with error.
7497
*

astra-shell/src/main/java/com/datastax/astra/shell/cmd/iam/OperationIam.java

Lines changed: 162 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package com.datastax.astra.shell.cmd.iam;
22

33
import java.util.HashMap;
4+
import java.util.List;
45
import java.util.Map;
56
import java.util.Optional;
7+
import java.util.stream.Collectors;
68

9+
import com.datastax.astra.sdk.organizations.OrganizationsClient;
710
import com.datastax.astra.sdk.organizations.domain.Role;
11+
import com.datastax.astra.sdk.organizations.domain.User;
12+
import com.datastax.astra.sdk.utils.IdUtils;
813
import com.datastax.astra.shell.ExitCode;
914
import com.datastax.astra.shell.ShellContext;
1015
import com.datastax.astra.shell.cmd.BaseCommand;
@@ -88,7 +93,8 @@ public static ExitCode listUsers(BaseCommand cmd) {
8893
}
8994

9095
/**
91-
* Show Role details
96+
* Show Role details.
97+
*
9298
* @param cmd
9399
* command
94100
* @param role
@@ -103,7 +109,7 @@ public static ExitCode showRole(BaseCommand cmd, String role) {
103109
.getApiDevopsOrganizations()
104110
.findRoleByName(role);
105111

106-
if (!optRole.isPresent()) {
112+
if (!optRole.isPresent() && IdUtils.isUUID(role)) {
107113
optRole = ShellContext
108114
.getInstance()
109115
.getApiDevopsOrganizations()
@@ -122,18 +128,25 @@ public static ExitCode showRole(BaseCommand cmd, String role) {
122128
sht.addPropertyRow("Name", r.getName());
123129
sht.addPropertyRow("Description", r.getPolicy().getDescription());
124130
sht.addPropertyRow("Effect", r.getPolicy().getEffect());
125-
sht.addPropertyListRows("Resources", r.getPolicy().getResources());
126-
sht.addPropertyListRows("Actions", r.getPolicy().getActions());
127131
switch(cmd.getFormat()) {
128-
case human:
129-
sht.show();
132+
case csv:
133+
sht.addPropertyRow("Resources", r.getPolicy().getResources().toString());
134+
sht.addPropertyRow("Actions", r.getPolicy().getActions().toString());
135+
ShellPrinter.printShellTable(sht, cmd.getFormat());
136+
break;
130137
case json:
131138
LoggerShell.json(new JsonOutput(ExitCode.SUCCESS, "role show " + role, r));
132-
case csv:
139+
break;
140+
case human:
133141
default:
142+
sht.addPropertyListRows("Resources", r.getPolicy().getResources());
143+
sht.addPropertyListRows("Actions", r.getPolicy().getActions());
144+
ShellPrinter.printShellTable(sht, cmd.getFormat());
134145
break;
135146
}
136147

148+
149+
137150
} catch(RuntimeException e) {
138151
cmd.outputError(ExitCode.INTERNAL_ERROR,"Cannot show role, technical error " + e.getMessage());
139152
return ExitCode.INTERNAL_ERROR;
@@ -142,5 +155,147 @@ public static ExitCode showRole(BaseCommand cmd, String role) {
142155
return ExitCode.SUCCESS;
143156
}
144157

158+
/**
159+
* Show User details.
160+
*
161+
* @param cmd
162+
* command
163+
* @param user
164+
* user email
165+
* @return
166+
* exit code
167+
*/
168+
public static ExitCode showUser(BaseCommand cmd, String user) {
169+
try {
170+
Optional<User> optUser = ShellContext
171+
.getInstance()
172+
.getApiDevopsOrganizations()
173+
.findUserByEmail(user);
174+
175+
if (!optUser.isPresent() && IdUtils.isUUID(user)) {
176+
optUser = ShellContext
177+
.getInstance()
178+
.getApiDevopsOrganizations()
179+
.user(user)
180+
.find();
181+
}
182+
183+
if (!optUser.isPresent()) {
184+
cmd.outputError(ExitCode.NOT_FOUND, "User '" + user + "' has not been found.");
185+
return ExitCode.NOT_FOUND;
186+
}
187+
188+
User r = optUser.get();
189+
ShellTable sht = ShellTable.propertyTable(15, 40);
190+
sht.addPropertyRow("Identifier", r.getUserId());
191+
sht.addPropertyRow("Email", r.getEmail());
192+
sht.addPropertyRow("Status", r.getStatus().name());
193+
194+
List<String> roleNames = r.getRoles()
195+
.stream()
196+
.map(Role::getName)
197+
.collect(Collectors.toList());
198+
199+
switch(cmd.getFormat()) {
200+
case csv:
201+
sht.addPropertyRow("Roles", roleNames.toString());
202+
ShellPrinter.printShellTable(sht, cmd.getFormat());
203+
break;
204+
case json:
205+
LoggerShell.json(new JsonOutput(ExitCode.SUCCESS, "user show " + user, r));
206+
break;
207+
case human:
208+
default:
209+
sht.addPropertyListRows("Roles", roleNames);
210+
ShellPrinter.printShellTable(sht, cmd.getFormat());
211+
break;
212+
}
213+
214+
} catch(RuntimeException e) {
215+
cmd.outputError(ExitCode.INTERNAL_ERROR,"Cannot show user, technical error " + e.getMessage());
216+
return ExitCode.INTERNAL_ERROR;
217+
}
218+
219+
return ExitCode.SUCCESS;
220+
}
221+
222+
/**
223+
* Invite User.
224+
*
225+
* @param cmd
226+
* command
227+
* @param user
228+
* user email
229+
* @param role
230+
* target role for the user
231+
* @return
232+
* exit code
233+
*/
234+
public static ExitCode inviteUser(BaseCommand cmd, String user, String role) {
235+
try {
236+
OrganizationsClient oc = ShellContext.getInstance().getApiDevopsOrganizations();
237+
Optional<User> optUser = oc.findUserByEmail(user);
238+
239+
if (optUser.isPresent()) {
240+
cmd.outputWarning(ExitCode.ALREADY_EXIST, "User '" + user + "' already exist in the organization.");
241+
return ExitCode.ALREADY_EXIST;
242+
}
243+
244+
Optional<Role> optRole = oc.findRoleByName(role);
245+
if (!optRole.isPresent() && IdUtils.isUUID(role)) {
246+
optRole = oc.role(role).find();
247+
}
248+
249+
if (!optRole.isPresent()) {
250+
cmd.outputError(ExitCode.NOT_FOUND, "Role '" + role + "' has not been found");
251+
return ExitCode.NOT_FOUND;
252+
}
253+
254+
oc.inviteUser(user, optRole.get().getId());
255+
256+
cmd.outputSuccess(role);
257+
258+
} catch(RuntimeException e) {
259+
cmd.outputError(ExitCode.INTERNAL_ERROR,"Cannot invite user, technical error " + e.getMessage());
260+
return ExitCode.INTERNAL_ERROR;
261+
}
262+
return ExitCode.SUCCESS;
263+
}
145264

265+
/**
266+
* Delete a user if exist.
267+
*
268+
* @param cmd
269+
* current command options
270+
* @param user
271+
* user email of technial identifier
272+
* @return
273+
* status
274+
*/
275+
public static ExitCode deleteUser(BaseCommand cmd, String user) {
276+
try {
277+
OrganizationsClient oc = ShellContext.getInstance().getApiDevopsOrganizations();
278+
279+
Optional<User> optUser = oc.findUserByEmail(user);
280+
281+
if (!optUser.isPresent() && IdUtils.isUUID(user)) {
282+
optUser = oc.user(user).find();
283+
}
284+
285+
if (!optUser.isPresent()) {
286+
cmd.outputError(ExitCode.NOT_FOUND, "User '" + user + "' has not been found.");
287+
return ExitCode.NOT_FOUND;
288+
}
289+
290+
oc.user(optUser.get().getUserId()).delete();
291+
cmd.outputSuccess("Deleting user '" + user + "' (async operation)");
292+
293+
} catch(RuntimeException e) {
294+
cmd.outputError(ExitCode.INTERNAL_ERROR,"Cannot delete user, technical error " + e.getMessage());
295+
return ExitCode.INTERNAL_ERROR;
296+
}
297+
298+
return ExitCode.SUCCESS;
299+
}
300+
146301
}

astra-shell/src/main/java/com/datastax/astra/shell/cmd/iam/ShowUserCommand.java

Lines changed: 0 additions & 68 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.datastax.astra.shell.cmd.iam;
2+
3+
import com.datastax.astra.shell.ExitCode;
4+
import com.datastax.astra.shell.cmd.BaseCliCommand;
5+
import com.datastax.astra.shell.cmd.BaseCommand;
6+
import com.github.rvesse.airline.annotations.Arguments;
7+
import com.github.rvesse.airline.annotations.Command;
8+
import com.github.rvesse.airline.annotations.restrictions.Required;
9+
10+
/**
11+
* Delete a user if exist
12+
*
13+
* @author Cedrick LUNVEN (@clunven)
14+
*/
15+
@Command(name = BaseCommand.DELETE, description = "Delete an existing user")
16+
public class UserDeleteCli extends BaseCliCommand {
17+
18+
/**
19+
* Database name or identifier
20+
*/
21+
@Required
22+
@Arguments(title = "EMAIL", description = "User email or identifier")
23+
public String user;
24+
25+
26+
/** {@inheritDoc} */
27+
public ExitCode execute() {
28+
return OperationIam.deleteUser(this, user);
29+
}
30+
31+
}

0 commit comments

Comments
 (0)