From 231ec9b3465aeeb7cf8b99d6b318d42c22fbbe8f Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Date: Tue, 17 Jan 2023 17:44:40 +0100 Subject: [PATCH] DXCDT-314: Add ability to remove roles from a user (#606) --- docs/auth0_users_roles.md | 1 + docs/auth0_users_roles_assign.md | 1 + docs/auth0_users_roles_remove.md | 46 +++++++++++++ docs/auth0_users_roles_show.md | 1 + internal/auth0/user.go | 3 + internal/cli/users_roles.go | 107 ++++++++++++++++++++++++++++++- test/integration/test-cases.yaml | 4 ++ 7 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 docs/auth0_users_roles_remove.md diff --git a/docs/auth0_users_roles.md b/docs/auth0_users_roles.md index f56c426f7..ce7c47282 100644 --- a/docs/auth0_users_roles.md +++ b/docs/auth0_users_roles.md @@ -8,5 +8,6 @@ Manage a user's assigned roles. To learn more about roles and their behavior, re ## Commands - [auth0 users roles assign](auth0_users_roles_assign.md) - Assign roles to a user +- [auth0 users roles remove](auth0_users_roles_remove.md) - Remove roles from a user - [auth0 users roles show](auth0_users_roles_show.md) - Show a user's roles diff --git a/docs/auth0_users_roles_assign.md b/docs/auth0_users_roles_assign.md index 19f8f5174..ef75e80a2 100644 --- a/docs/auth0_users_roles_assign.md +++ b/docs/auth0_users_roles_assign.md @@ -40,6 +40,7 @@ auth0 users roles assign [flags] ## Related Commands - [auth0 users roles assign](auth0_users_roles_assign.md) - Assign roles to a user +- [auth0 users roles remove](auth0_users_roles_remove.md) - Remove roles from a user - [auth0 users roles show](auth0_users_roles_show.md) - Show a user's roles diff --git a/docs/auth0_users_roles_remove.md b/docs/auth0_users_roles_remove.md new file mode 100644 index 000000000..4cef42876 --- /dev/null +++ b/docs/auth0_users_roles_remove.md @@ -0,0 +1,46 @@ +--- +layout: default +--- +# auth0 users roles remove + +Remove existing roles from a user. + +## Usage +``` +auth0 users roles remove [flags] +``` + +## Examples + +``` + auth0 users roles remove + auth0 users roles remove --roles + auth0 users roles rm -r "rol_1eKJp3jV04SiU04h,rol_2eKJp3jV04SiU04h" --json +``` + + +## Flags + +``` + --json Output in json format. + -r, --roles strings Roles to assign to a user. +``` + + +## InheritedFlags + +``` + --debug Enable debug mode. + --no-color Disable colors. + --no-input Disable interactivity. + --tenant string Specific tenant to use. +``` + + +## Related Commands + +- [auth0 users roles assign](auth0_users_roles_assign.md) - Assign roles to a user +- [auth0 users roles remove](auth0_users_roles_remove.md) - Remove roles from a user +- [auth0 users roles show](auth0_users_roles_show.md) - Show a user's roles + + diff --git a/docs/auth0_users_roles_show.md b/docs/auth0_users_roles_show.md index 07083f266..131c2af6f 100644 --- a/docs/auth0_users_roles_show.md +++ b/docs/auth0_users_roles_show.md @@ -41,6 +41,7 @@ auth0 users roles show [flags] ## Related Commands - [auth0 users roles assign](auth0_users_roles_assign.md) - Assign roles to a user +- [auth0 users roles remove](auth0_users_roles_remove.md) - Remove roles from a user - [auth0 users roles show](auth0_users_roles_show.md) - Show a user's roles diff --git a/internal/auth0/user.go b/internal/auth0/user.go index f48bc83ac..8e383663d 100644 --- a/internal/auth0/user.go +++ b/internal/auth0/user.go @@ -33,4 +33,7 @@ type UserAPI interface { // AssignRoles assigns roles to a user. AssignRoles(id string, roles []*management.Role, opts ...management.RequestOption) error + + // RemoveRoles removes roles from a user. + RemoveRoles(id string, roles []*management.Role, opts ...management.RequestOption) error } diff --git a/internal/cli/users_roles.go b/internal/cli/users_roles.go index 422877b59..02702236a 100644 --- a/internal/cli/users_roles.go +++ b/internal/cli/users_roles.go @@ -1,6 +1,7 @@ package cli import ( + "errors" "fmt" "strings" @@ -29,6 +30,8 @@ var ( Help: "Roles to assign to a user.", IsRequired: true, } + + errNoRolesSelected = errors.New("required to select at least one role") ) type userRolesInput struct { @@ -48,6 +51,7 @@ func userRolesCmd(cli *cli) *cobra.Command { cmd.SetUsageTemplate(resourceUsageTemplate()) cmd.AddCommand(showUserRolesCmd(cli)) cmd.AddCommand(addUserRolesCmd(cli)) + cmd.AddCommand(removeUserRolesCmd(cli)) return cmd } @@ -137,7 +141,7 @@ func addUserRolesCmd(cli *cli) *cobra.Command { } if len(inputs.Roles) == 0 { - if err := cli.pickUserRoles(&inputs); err != nil { + if err := cli.pickUserRolesToAdd(&inputs); err != nil { return err } } @@ -175,7 +179,67 @@ func addUserRolesCmd(cli *cli) *cobra.Command { return cmd } -func (cli *cli) pickUserRoles(inputs *userRolesInput) error { +func removeUserRolesCmd(cli *cli) *cobra.Command { + var inputs userRolesInput + + cmd := &cobra.Command{ + Use: "remove", + Aliases: []string{"rm"}, + Args: cobra.MaximumNArgs(1), + Short: "Remove roles from a user", + Long: "Remove existing roles from a user.", + Example: ` auth0 users roles remove + auth0 users roles remove --roles + auth0 users roles rm -r "rol_1eKJp3jV04SiU04h,rol_2eKJp3jV04SiU04h" --json`, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + if err := userID.Ask(cmd, &inputs.ID); err != nil { + return err + } + } else { + inputs.ID = args[0] + } + + if len(inputs.Roles) == 0 { + if err := cli.pickUserRolesToRemove(&inputs); err != nil { + return err + } + } + + var rolesToRemove []*management.Role + for _, roleID := range inputs.Roles { + rolesToRemove = append(rolesToRemove, &management.Role{ + ID: auth0.String(roleID), + }) + } + + if err := ansi.Waiting(func() (err error) { + return cli.api.User.RemoveRoles(inputs.ID, rolesToRemove) + }); err != nil { + return fmt.Errorf("failed to remove roles for user with ID %s: %w", inputs.ID, err) + } + + var userRoleList *management.RoleList + if err := ansi.Waiting(func() (err error) { + userRoleList, err = cli.api.User.Roles(inputs.ID) + return err + }); err != nil { + return fmt.Errorf("failed to find roles for user with ID %s: %w", inputs.ID, err) + } + + cli.renderer.UserRoleList(userRoleList.Roles) + + return nil + }, + } + + userRoles.RegisterStringSlice(cmd, &inputs.Roles, nil) + cmd.Flags().BoolVar(&cli.json, "json", false, "Output in json format.") + + return cmd +} + +func (cli *cli) pickUserRolesToAdd(inputs *userRolesInput) error { var currentUserRoleList *management.RoleList if err := ansi.Waiting(func() (err error) { currentUserRoleList, err = cli.api.User.Roles(inputs.ID, management.PerPage(100)) @@ -220,7 +284,44 @@ func (cli *cli) pickUserRoles(inputs *userRolesInput) error { } if len(inputs.Roles) == 0 { - return fmt.Errorf("required to select at least one role") + return errNoRolesSelected + } + + return nil +} + +func (cli *cli) pickUserRolesToRemove(inputs *userRolesInput) error { + var currentUserRoleList *management.RoleList + if err := ansi.Waiting(func() (err error) { + currentUserRoleList, err = cli.api.User.Roles(inputs.ID) + return err + }); err != nil { + return fmt.Errorf("failed to find the current roles for user with ID %s: %w", inputs.ID, err) + } + + const emptySpace = " " + var options []string + for _, role := range currentUserRoleList.Roles { + options = append(options, fmt.Sprintf("%s%s(Name: %s)", role.GetID(), emptySpace, role.GetName())) + } + + rolesPrompt := &survey.MultiSelect{ + Message: "Roles", + Options: options, + } + + var selectedRoles []string + if err := survey.AskOne(rolesPrompt, &selectedRoles); err != nil { + return err + } + + for _, selectedRole := range selectedRoles { + indexOfFirstEmptySpace := strings.Index(selectedRole, emptySpace) + inputs.Roles = append(inputs.Roles, selectedRole[:indexOfFirstEmptySpace]) + } + + if len(inputs.Roles) == 0 { + return errNoRolesSelected } return nil diff --git a/test/integration/test-cases.yaml b/test/integration/test-cases.yaml index 3597d456c..534c371ad 100644 --- a/test/integration/test-cases.yaml +++ b/test/integration/test-cases.yaml @@ -740,3 +740,7 @@ tests: users roles add: command: auth0 users roles add $(cat ./test/integration/identifiers/user-id) -r $(cat ./test/integration/identifiers/role-id) exit-code: 0 + + users roles remove: + command: auth0 users roles rm $(cat ./test/integration/identifiers/user-id) -r $(cat ./test/integration/identifiers/role-id) + exit-code: 0