diff --git a/cmd/create.go b/cmd/create.go index 339677a..8267ecb 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/speatzle/go-passbolt-cli/folder" + "github.com/speatzle/go-passbolt-cli/group" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -18,4 +19,5 @@ func init() { rootCmd.AddCommand(createCmd) createCmd.AddCommand(resource.ResourceCreateCmd) createCmd.AddCommand(folder.FolderCreateCmd) + createCmd.AddCommand(group.GroupCreateCmd) } diff --git a/cmd/delete.go b/cmd/delete.go index 85e4ff5..ed99f73 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/speatzle/go-passbolt-cli/folder" + "github.com/speatzle/go-passbolt-cli/group" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -18,6 +19,7 @@ func init() { rootCmd.AddCommand(deleteCmd) deleteCmd.AddCommand(resource.ResourceDeleteCmd) deleteCmd.AddCommand(folder.FolderDeleteCmd) + deleteCmd.AddCommand(group.GroupDeleteCmd) deleteCmd.PersistentFlags().String("id", "", "ID of the Entity to Delete") } diff --git a/cmd/get.go b/cmd/get.go index cf632ec..a1d2211 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/speatzle/go-passbolt-cli/folder" + "github.com/speatzle/go-passbolt-cli/group" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -18,4 +19,5 @@ func init() { rootCmd.AddCommand(getCmd) getCmd.AddCommand(resource.ResourceGetCmd) getCmd.AddCommand(folder.FolderGetCmd) + getCmd.AddCommand(group.GroupGetCmd) } diff --git a/cmd/list.go b/cmd/list.go index f89c42c..6756557 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/speatzle/go-passbolt-cli/folder" + "github.com/speatzle/go-passbolt-cli/group" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -18,4 +19,5 @@ func init() { rootCmd.AddCommand(listCmd) listCmd.AddCommand(resource.ResourceListCmd) listCmd.AddCommand(folder.FolderListCmd) + listCmd.AddCommand(group.GroupListCmd) } diff --git a/cmd/move.go b/cmd/move.go index 9e60501..90b7538 100644 --- a/cmd/move.go +++ b/cmd/move.go @@ -1,6 +1,7 @@ package cmd import ( + "github.com/speatzle/go-passbolt-cli/folder" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -15,4 +16,5 @@ var moveCmd = &cobra.Command{ func init() { rootCmd.AddCommand(moveCmd) moveCmd.AddCommand(resource.ResourceMoveCmd) + moveCmd.AddCommand(folder.FolderMoveCmd) } diff --git a/cmd/share.go b/cmd/share.go index 37e5a23..21aaecc 100644 --- a/cmd/share.go +++ b/cmd/share.go @@ -1,6 +1,7 @@ package cmd import ( + "github.com/speatzle/go-passbolt-cli/folder" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -15,4 +16,5 @@ var shareCmd = &cobra.Command{ func init() { rootCmd.AddCommand(shareCmd) shareCmd.AddCommand(resource.ResourceShareCmd) + shareCmd.AddCommand(folder.FolderShareCmd) } diff --git a/cmd/update.go b/cmd/update.go index c332df9..06a9ab6 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/speatzle/go-passbolt-cli/folder" + "github.com/speatzle/go-passbolt-cli/group" "github.com/speatzle/go-passbolt-cli/resource" "github.com/spf13/cobra" ) @@ -18,4 +19,5 @@ func init() { rootCmd.AddCommand(updateCmd) updateCmd.AddCommand(resource.ResourceUpdateCmd) updateCmd.AddCommand(folder.FolderUpdateCmd) + updateCmd.AddCommand(group.GroupUpdateCmd) } diff --git a/group/create.go b/group/create.go new file mode 100644 index 0000000..66125e6 --- /dev/null +++ b/group/create.go @@ -0,0 +1,79 @@ +package group + +import ( + "context" + "fmt" + + "github.com/speatzle/go-passbolt-cli/util" + "github.com/speatzle/go-passbolt/helper" + "github.com/spf13/cobra" +) + +// GroupCreateCmd Creates a Passbolt Group +var GroupCreateCmd = &cobra.Command{ + Use: "group", + Short: "Creates a Passbolt Group", + Long: `Creates a Passbolt Group and Returns the Groups ID`, + RunE: GroupCreate, +} + +func init() { + GroupCreateCmd.Flags().StringP("name", "n", "", "Group Name") + + GroupCreateCmd.Flags().StringArrayP("users", "u", []string{}, "Users to Add to Group") + GroupCreateCmd.Flags().StringArrayP("managers", "m", []string{}, "Managers to Add to Group (atleast 1 is required)") + + GroupCreateCmd.MarkFlagRequired("name") + GroupCreateCmd.MarkFlagRequired("managers") +} + +func GroupCreate(cmd *cobra.Command, args []string) error { + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + users, err := cmd.Flags().GetStringArray("users") + if err != nil { + return err + } + managers, err := cmd.Flags().GetStringArray("managers") + if err != nil { + return err + } + + ops := []helper.GroupMembershipOperation{} + for _, user := range users { + ops = append(ops, helper.GroupMembershipOperation{ + UserID: user, + IsGroupManager: false, + }) + } + for _, manager := range managers { + ops = append(ops, helper.GroupMembershipOperation{ + UserID: manager, + IsGroupManager: true, + }) + } + + ctx := util.GetContext() + + client, err := util.GetClient(ctx) + if err != nil { + return err + } + defer client.Logout(context.TODO()) + cmd.SilenceUsage = true + + id, err := helper.CreateGroup( + ctx, + client, + name, + ops, + ) + if err != nil { + return fmt.Errorf("Creating Group: %w", err) + } + + fmt.Printf("GroupID: %v\n", id) + return nil +} diff --git a/group/delete.go b/group/delete.go new file mode 100644 index 0000000..532efa5 --- /dev/null +++ b/group/delete.go @@ -0,0 +1,43 @@ +package group + +import ( + "context" + "fmt" + + "github.com/speatzle/go-passbolt-cli/util" + "github.com/spf13/cobra" +) + +// GroupDeleteCmd Deletes a Group +var GroupDeleteCmd = &cobra.Command{ + Use: "group", + Short: "Deletes a Passbolt Group", + Long: `Deletes a Passbolt Group`, + RunE: GroupDelete, +} + +func GroupDelete(cmd *cobra.Command, args []string) error { + resourceID, err := cmd.Flags().GetString("id") + if err != nil { + return err + } + + if resourceID == "" { + return fmt.Errorf("No ID to Delete Provided") + } + + ctx := util.GetContext() + + client, err := util.GetClient(ctx) + if err != nil { + return err + } + defer client.Logout(context.TODO()) + cmd.SilenceUsage = true + + client.DeleteGroup(ctx, resourceID) + if err != nil { + return fmt.Errorf("Deleting Group: %w", err) + } + return nil +} diff --git a/group/get.go b/group/get.go new file mode 100644 index 0000000..1e6034a --- /dev/null +++ b/group/get.go @@ -0,0 +1,87 @@ +package group + +import ( + "context" + "fmt" + "strings" + + "github.com/pterm/pterm" + "github.com/speatzle/go-passbolt-cli/util" + "github.com/speatzle/go-passbolt/helper" + "github.com/spf13/cobra" +) + +// GroupGetCmd Gets a Passbolt Group +var GroupGetCmd = &cobra.Command{ + Use: "group", + Short: "Gets a Passbolt Group", + Long: `Gets a Passbolt Group`, + RunE: GroupGet, +} + +func init() { + GroupGetCmd.Flags().String("id", "", "id of Group to Get") + + GroupGetCmd.Flags().StringArrayP("columns", "c", []string{"UserID", "IsGroupManager"}, "Membership Columns to return, possible Columns:\nUserID, Username, UserFirstName, UserLastName, IsGroupManager") + + GroupGetCmd.MarkFlagRequired("id") +} + +func GroupGet(cmd *cobra.Command, args []string) error { + id, err := cmd.Flags().GetString("id") + if err != nil { + return err + } + columns, err := cmd.Flags().GetStringArray("columns") + if err != nil { + return err + } + + ctx := util.GetContext() + + client, err := util.GetClient(ctx) + if err != nil { + return err + } + defer client.Logout(context.TODO()) + cmd.SilenceUsage = true + + name, memberships, err := helper.GetGroup( + ctx, + client, + id, + ) + if err != nil { + return fmt.Errorf("Getting Group: %w", err) + } + fmt.Printf("Name: %v\n", name) + // Print Memberships + if len(columns) != 0 { + data := pterm.TableData{columns} + + for _, membership := range memberships { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "userid": + entry[i] = membership.UserID + case "isgroupmanager": + entry[i] = fmt.Sprint(membership.IsGroupManager) + case "username": + entry[i] = fmt.Sprint(membership.Username) + case "userfirstname": + entry[i] = fmt.Sprint(membership.UserFirstName) + case "userlastname": + entry[i] = fmt.Sprint(membership.UserLastName) + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + } + return nil +} diff --git a/group/list.go b/group/list.go new file mode 100644 index 0000000..c09db13 --- /dev/null +++ b/group/list.go @@ -0,0 +1,85 @@ +package group + +import ( + "context" + "fmt" + "strings" + + "github.com/speatzle/go-passbolt-cli/util" + "github.com/speatzle/go-passbolt/api" + "github.com/spf13/cobra" + + "github.com/pterm/pterm" +) + +// GroupListCmd Lists a Passbolt Group +var GroupListCmd = &cobra.Command{ + Use: "group", + Short: "Lists Passbolt Groups", + Long: `Lists Passbolt Groups`, + Aliases: []string{"groups"}, + RunE: GroupList, +} + +func init() { + GroupListCmd.Flags().StringArrayP("users", "u", []string{}, "Groups that are shared with group") + GroupListCmd.Flags().StringArrayP("managers", "m", []string{}, "Groups that are in folder") + + GroupListCmd.Flags().StringArrayP("columns", "c", []string{"ID", "Name"}, "Columns to return, possible Columns:\nID, Name") +} + +func GroupList(cmd *cobra.Command, args []string) error { + users, err := cmd.Flags().GetStringArray("users") + if err != nil { + return err + } + managers, err := cmd.Flags().GetStringArray("managers") + if err != nil { + return err + } + columns, err := cmd.Flags().GetStringArray("columns") + if err != nil { + return err + } + if len(columns) == 0 { + return fmt.Errorf("You need to specify atleast one column to return") + } + + ctx := util.GetContext() + + client, err := util.GetClient(ctx) + if err != nil { + return err + } + defer client.Logout(context.TODO()) + cmd.SilenceUsage = true + + resources, err := client.GetGroups(ctx, &api.GetGroupsOptions{ + FilterHasUsers: users, + FilterHasManagers: managers, + }) + if err != nil { + return fmt.Errorf("Listing Group: %w", err) + } + + data := pterm.TableData{columns} + + for _, resource := range resources { + entry := make([]string, len(columns)) + for i := range columns { + switch strings.ToLower(columns[i]) { + case "id": + entry[i] = resource.ID + case "name": + entry[i] = resource.Name + default: + cmd.SilenceUsage = false + return fmt.Errorf("Unknown Column: %v", columns[i]) + } + } + data = append(data, entry) + } + + pterm.DefaultTable.WithHasHeader().WithData(data).Render() + return nil +} diff --git a/group/update.go b/group/update.go new file mode 100644 index 0000000..98b9c7e --- /dev/null +++ b/group/update.go @@ -0,0 +1,90 @@ +package group + +import ( + "context" + "fmt" + + "github.com/speatzle/go-passbolt-cli/util" + "github.com/speatzle/go-passbolt/helper" + "github.com/spf13/cobra" +) + +// GroupUpdateCmd Updates a Passbolt Group +var GroupUpdateCmd = &cobra.Command{ + Use: "group", + Short: "Updates a Passbolt Group", + Long: `Updates a Passbolt Group`, + RunE: GroupUpdate, +} + +func init() { + GroupUpdateCmd.Flags().String("id", "", "id of Group to Update") + GroupUpdateCmd.Flags().StringP("name", "n", "", "Group Name") + + GroupUpdateCmd.Flags().BoolP("delete", "d", false, "Remove Users/Managers from Group (default is Adding Users/Managers)") + + GroupUpdateCmd.Flags().StringArrayP("users", "u", []string{}, "Users to Add/Remove to/from Group(Including Group Managers)") + GroupUpdateCmd.Flags().StringArrayP("managers", "m", []string{}, "Managers to Add/Remove to/from Group") + + GroupUpdateCmd.MarkFlagRequired("id") +} + +func GroupUpdate(cmd *cobra.Command, args []string) error { + id, err := cmd.Flags().GetString("id") + if err != nil { + return err + } + delete, err := cmd.Flags().GetBool("delete") + if err != nil { + return err + } + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + users, err := cmd.Flags().GetStringArray("users") + if err != nil { + return err + } + managers, err := cmd.Flags().GetStringArray("managers") + if err != nil { + return err + } + + ops := []helper.GroupMembershipOperation{} + for _, user := range users { + ops = append(ops, helper.GroupMembershipOperation{ + UserID: user, + IsGroupManager: false, + Delete: delete, + }) + } + for _, manager := range managers { + ops = append(ops, helper.GroupMembershipOperation{ + UserID: manager, + IsGroupManager: true, + Delete: delete, + }) + } + + ctx := util.GetContext() + + client, err := util.GetClient(ctx) + if err != nil { + return err + } + defer client.Logout(context.TODO()) + cmd.SilenceUsage = true + + err = helper.UpdateGroup( + ctx, + client, + id, + name, + ops, + ) + if err != nil { + return fmt.Errorf("Updating Group: %w", err) + } + return nil +}