diff --git a/cli/cmd/user/create.go b/cli/cmd/user/create.go index dc1e2a0b..ac313072 100644 --- a/cli/cmd/user/create.go +++ b/cli/cmd/user/create.go @@ -1,6 +1,8 @@ package user import ( + "strings" + "github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/models" "github.com/spf13/cobra" @@ -12,18 +14,41 @@ var userCreateCmd = &cobra.Command{ Short: "Create a new user", Long: `Create a new user`, Run: func(cmd *cobra.Command, args []string) { - user := &models.User{UserName: username, Password: password, IsAdmin: admin} + user := &models.User{UserName: username, Password: password, PlatformRoleID: models.UserRoleID(platformID)} + if len(networkRoles) > 0 { + netRolesMap := make(map[models.NetworkID]map[models.UserRoleID]struct{}) + for netID, netRoles := range networkRoles { + roleMap := make(map[models.UserRoleID]struct{}) + for _, roleID := range strings.Split(netRoles, ",") { + roleMap[models.UserRoleID(roleID)] = struct{}{} + } + netRolesMap[models.NetworkID(netID)] = roleMap + } + user.NetworkRoles = netRolesMap + } + if len(groups) > 0 { + grMap := make(map[models.UserGroupID]struct{}) + for _, groupID := range groups { + grMap[models.UserGroupID(groupID)] = struct{}{} + } + user.UserGroups = grMap + } + functions.PrettyPrint(functions.CreateUser(user)) }, } func init() { + userCreateCmd.Flags().StringVar(&username, "name", "", "Name of the user") userCreateCmd.Flags().StringVar(&password, "password", "", "Password of the user") + userCreateCmd.Flags().StringVarP(&platformID, "platform-id", "r", models.ServiceUser.String(), + "Platform Role of the user; run `nmctl roles list` to see available user roles") userCreateCmd.MarkFlagRequired("name") userCreateCmd.MarkFlagRequired("password") - userCreateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ?") - userCreateCmd.Flags().StringVar(&networks, "networks", "", "List of networks the user will access to (comma separated)") - userCreateCmd.Flags().StringVar(&groups, "groups", "", "List of user groups the user will be part of (comma separated)") + userCreateCmd.PersistentFlags().StringToStringVarP(&networkRoles, "network-roles", "n", make(map[string]string), + "Mapping of networkID and list of roles user will be part of (comma separated)") + userCreateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ? (deprecated v0.25.0 onwards)") + userCreateCmd.Flags().StringArrayVarP(&groups, "groups", "g", nil, "List of user groups the user will be part of (comma separated)") rootCmd.AddCommand(userCreateCmd) } diff --git a/cli/cmd/user/flags.go b/cli/cmd/user/flags.go index 57f07843..224e8f6f 100644 --- a/cli/cmd/user/flags.go +++ b/cli/cmd/user/flags.go @@ -1,9 +1,11 @@ package user var ( - username string - password string - admin bool - networks string - groups string + username string + password string + platformID string + admin bool + networks string + networkRoles map[string]string + groups []string ) diff --git a/cli/cmd/user/list.go b/cli/cmd/user/list.go index 694697a2..d1d2fa79 100644 --- a/cli/cmd/user/list.go +++ b/cli/cmd/user/list.go @@ -3,6 +3,7 @@ package user import ( "os" "strconv" + "strings" "github.com/gravitl/netmaker/cli/cmd/commons" "github.com/gravitl/netmaker/cli/functions" @@ -22,9 +23,13 @@ var userListCmd = &cobra.Command{ functions.PrettyPrint(data) default: table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"Name", "SuperAdmin", "Admin"}) + table.SetHeader([]string{"Name", "Platform Role", "Groups"}) for _, d := range *data { - table.Append([]string{d.UserName, strconv.FormatBool(d.IsSuperAdmin), strconv.FormatBool(d.IsAdmin)}) + g := []string{} + for gID := range d.UserGroups { + g = append(g, gID.String()) + } + table.Append([]string{d.UserName, d.PlatformRoleID.String(), strconv.FormatBool(d.IsAdmin), strings.Join(g, ",")}) } table.Render() } diff --git a/cli/cmd/user/roles.go b/cli/cmd/user/roles.go new file mode 100644 index 00000000..a9e272e2 --- /dev/null +++ b/cli/cmd/user/roles.go @@ -0,0 +1,73 @@ +package user + +import ( + "fmt" + "os" + "strconv" + + "github.com/gravitl/netmaker/cli/cmd/commons" + "github.com/gravitl/netmaker/cli/functions" + "github.com/gravitl/netmaker/models" + "github.com/guumaster/tablewriter" + "github.com/spf13/cobra" +) + +var userRoleCmd = &cobra.Command{ + Use: "role", + Args: cobra.NoArgs, + Short: "Manage User Roles", + Long: `Manage User Roles`, +} + +// List Roles +var ( + platformRoles bool +) +var userroleListCmd = &cobra.Command{ + Use: "list", + Args: cobra.NoArgs, + Short: "List all user roles", + Long: `List all user roles`, + Run: func(cmd *cobra.Command, args []string) { + data := functions.ListUserRoles() + userRoles := data.Response.([]models.UserRolePermissionTemplate) + switch commons.OutputFormat { + case commons.JsonOutput: + functions.PrettyPrint(data) + default: + table := tablewriter.NewWriter(os.Stdout) + h := []string{"ID", "Default", "Dashboard Access", "Full Access"} + + if !platformRoles { + h = append(h, "Network") + } + table.SetHeader(h) + for _, d := range userRoles { + e := []string{d.ID.String(), strconv.FormatBool(d.Default), strconv.FormatBool(d.DenyDashboardAccess), strconv.FormatBool(d.FullAccess)} + if !platformRoles { + e = append(e, d.NetworkID.String()) + } + table.Append(e) + } + table.Render() + } + }, +} + +var userRoleCreateCmd = &cobra.Command{ + Use: "create", + Args: cobra.NoArgs, + Short: "create user role", + Long: `create user role`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("CLI doesn't support creation of roles currently") + }, +} + +func init() { + rootCmd.AddCommand(userRoleCmd) + userroleListCmd.Flags().BoolVar(&platformRoles, "platform-roles", true, + "set to false to list network roles. By default it will only list platform roles") + userRoleCmd.AddCommand(userroleListCmd) + userRoleCmd.AddCommand(userCreateCmd) +} diff --git a/cli/cmd/user/update.go b/cli/cmd/user/update.go index 0a79f26a..f8030761 100644 --- a/cli/cmd/user/update.go +++ b/cli/cmd/user/update.go @@ -1,6 +1,8 @@ package user import ( + "strings" + "github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/models" "github.com/spf13/cobra" @@ -12,7 +14,28 @@ var userUpdateCmd = &cobra.Command{ Short: "Update a user", Long: `Update a user`, Run: func(cmd *cobra.Command, args []string) { - user := &models.User{UserName: args[0], IsAdmin: admin} + user := &models.User{UserName: args[0]} + if platformID != "" { + user.PlatformRoleID = models.UserRoleID(platformID) + } + if len(networkRoles) > 0 { + netRolesMap := make(map[models.NetworkID]map[models.UserRoleID]struct{}) + for netID, netRoles := range networkRoles { + roleMap := make(map[models.UserRoleID]struct{}) + for _, roleID := range strings.Split(netRoles, ",") { + roleMap[models.UserRoleID(roleID)] = struct{}{} + } + netRolesMap[models.NetworkID(netID)] = roleMap + } + user.NetworkRoles = netRolesMap + } + if len(groups) > 0 { + grMap := make(map[models.UserGroupID]struct{}) + for _, groupID := range groups { + grMap[models.UserGroupID(groupID)] = struct{}{} + } + user.UserGroups = grMap + } functions.PrettyPrint(functions.UpdateUser(user)) }, } @@ -20,6 +43,8 @@ var userUpdateCmd = &cobra.Command{ func init() { userUpdateCmd.Flags().BoolVar(&admin, "admin", false, "Make the user an admin ?") userUpdateCmd.Flags().StringVar(&networks, "networks", "", "List of networks the user will access to (comma separated)") - userUpdateCmd.Flags().StringVar(&groups, "groups", "", "List of user groups the user will be part of (comma separated)") + userUpdateCmd.Flags().StringVarP(&platformID, "platform-id", "r", "", + "Platform Role of the user; run `nmctl roles list` to see available user roles") + userUpdateCmd.Flags().StringArrayVarP(&groups, "groups", "g", nil, "List of user groups the user will be part of (comma separated)") rootCmd.AddCommand(userUpdateCmd) } diff --git a/cli/functions/user.go b/cli/functions/user.go index b286bc4e..43416bfd 100644 --- a/cli/functions/user.go +++ b/cli/functions/user.go @@ -1,6 +1,7 @@ package functions import ( + "fmt" "net/http" "github.com/gravitl/netmaker/models" @@ -35,3 +36,30 @@ func GetUser(username string) *models.User { func ListUsers() *[]models.ReturnUser { return request[[]models.ReturnUser](http.MethodGet, "/api/users", nil) } + +func CreateUserRole(role models.UserRolePermissionTemplate) *models.SuccessResponse { + return request[models.SuccessResponse](http.MethodPost, "/api/v1/users/role", role) +} +func UpdateUserRole(role models.UserRolePermissionTemplate) *models.SuccessResponse { + return request[models.SuccessResponse](http.MethodPut, "/api/v1/users/role", role) +} + +func ListUserRoles() *models.SuccessResponse { + return request[models.SuccessResponse](http.MethodGet, "/api/v1/users/roles", nil) +} + +func DeleteUserRole(roleID string) *models.SuccessResponse { + return request[models.SuccessResponse](http.MethodDelete, fmt.Sprintf("/api/v1/users/role?role_id=%s", roleID), nil) +} +func GetUserRole(roleID string) *models.SuccessResponse { + return request[models.SuccessResponse](http.MethodGet, fmt.Sprintf("/api/v1/users/role?role_id=%s", roleID), nil) +} + +/* + + r.HandleFunc("/api/v1/users/roles", logic.SecurityCheck(true, http.HandlerFunc(listRoles))).Methods(http.MethodGet) + r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(getRole))).Methods(http.MethodGet) + r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(createRole))).Methods(http.MethodPost) + r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(updateRole))).Methods(http.MethodPut) + r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(deleteRole))).Methods(http.MethodDelete) +*/