package cmd import ( "context" "encoding/json" "fmt" "os" "gogs.dmsc.dev/arp/arp_cli/client" "gogs.dmsc.dev/arp/arp_cli/config" "github.com/AlecAivazis/survey/v2" "github.com/olekukonko/tablewriter" "github.com/urfave/cli/v3" ) // PermissionCommand returns the permission command func PermissionCommand() *cli.Command { return &cli.Command{ Name: "permission", Usage: "Manage permissions", Description: `Manage ARP permissions. Permissions define fine-grained access control. Use this command to create, list, update, and delete permissions.`, Commands: []*cli.Command{ { Name: "list", Aliases: []string{"ls"}, Usage: "List all permissions", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "json", Aliases: []string{"j"}, Usage: "Output as JSON", }, }, Action: permissionList, }, { Name: "get", Usage: "Get a permission by ID", Flags: []cli.Flag{ &cli.StringFlag{ Name: "id", Aliases: []string{"i"}, Usage: "Permission ID", Required: true, }, &cli.BoolFlag{ Name: "json", Aliases: []string{"j"}, Usage: "Output as JSON", }, }, Action: permissionGet, }, { Name: "create", Usage: "Create a new permission", Action: permissionCreate, Flags: []cli.Flag{ &cli.StringFlag{ Name: "code", Aliases: []string{"c"}, Usage: "Permission code", }, &cli.StringFlag{ Name: "description", Aliases: []string{"d"}, Usage: "Permission description", }, }, }, { Name: "update", Usage: "Update a permission", Action: permissionUpdate, Flags: []cli.Flag{ &cli.StringFlag{ Name: "id", Aliases: []string{"i"}, Usage: "Permission ID", Required: true, }, &cli.StringFlag{ Name: "code", Aliases: []string{"c"}, Usage: "Permission code", }, &cli.StringFlag{ Name: "description", Aliases: []string{"d"}, Usage: "Permission description", }, }, }, { Name: "delete", Usage: "Delete a permission", Action: permissionDelete, Flags: []cli.Flag{ &cli.StringFlag{ Name: "id", Aliases: []string{"i"}, Usage: "Permission ID", Required: true, }, &cli.BoolFlag{ Name: "yes", Aliases: []string{"y"}, Usage: "Skip confirmation", }, }, }, }, } } type PermissionDetail struct { ID string `json:"id"` Code string `json:"code"` Description string `json:"description"` } func permissionList(ctx context.Context, cmd *cli.Command) error { cfg, err := config.Load() if err != nil { return err } if err := RequireAuth(cfg); err != nil { return err } c := client.New(cfg.ServerURL) c.SetToken(cfg.Token) query := "query Permissions { permissions { id code description } }" resp, err := c.Query(query, nil) if err != nil { return err } var result struct { Permissions []PermissionDetail `json:"permissions"` } if err := json.Unmarshal(resp.Data, &result); err != nil { return err } if cmd.Bool("json") { enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(result.Permissions) } if len(result.Permissions) == 0 { fmt.Println("No permissions found.") return nil } table := tablewriter.NewWriter(os.Stdout) table.Header([]string{"ID", "Code", "Description"}) for _, p := range result.Permissions { table.Append([]string{p.ID, p.Code, p.Description}) } table.Render() return nil } func permissionGet(ctx context.Context, cmd *cli.Command) error { cfg, err := config.Load() if err != nil { return err } if err := RequireAuth(cfg); err != nil { return err } c := client.New(cfg.ServerURL) c.SetToken(cfg.Token) id := cmd.String("id") query := "query Permission($id: ID!) { permission(id: $id) { id code description } }" resp, err := c.Query(query, map[string]interface{}{"id": id}) if err != nil { return err } var result struct { Permission *PermissionDetail `json:"permission"` } if err := json.Unmarshal(resp.Data, &result); err != nil { return err } if result.Permission == nil { return fmt.Errorf("permission not found") } if cmd.Bool("json") { enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(result.Permission) } p := result.Permission fmt.Printf("ID: %s\n", p.ID) fmt.Printf("Code: %s\n", p.Code) fmt.Printf("Description: %s\n", p.Description) return nil } func permissionCreate(ctx context.Context, cmd *cli.Command) error { cfg, err := config.Load() if err != nil { return err } if err := RequireAuth(cfg); err != nil { return err } code := cmd.String("code") description := cmd.String("description") if code == "" { prompt := &survey.Input{Message: "Permission code:"} if err := survey.AskOne(prompt, &code, survey.WithValidator(survey.Required)); err != nil { return err } } if description == "" { prompt := &survey.Input{Message: "Description:"} if err := survey.AskOne(prompt, &description, survey.WithValidator(survey.Required)); err != nil { return err } } c := client.New(cfg.ServerURL) c.SetToken(cfg.Token) mutation := `mutation CreatePermission($input: NewPermission!) { createPermission(input: $input) { id code description } }` input := map[string]interface{}{ "code": code, "description": description, } resp, err := c.Mutation(mutation, map[string]interface{}{"input": input}) if err != nil { return err } var result struct { CreatePermission *PermissionDetail `json:"createPermission"` } if err := json.Unmarshal(resp.Data, &result); err != nil { return err } if result.CreatePermission == nil { return fmt.Errorf("failed to create permission") } fmt.Printf("Permission created successfully!\n") fmt.Printf("ID: %s\n", result.CreatePermission.ID) fmt.Printf("Code: %s\n", result.CreatePermission.Code) return nil } func permissionUpdate(ctx context.Context, cmd *cli.Command) error { cfg, err := config.Load() if err != nil { return err } if err := RequireAuth(cfg); err != nil { return err } id := cmd.String("id") code := cmd.String("code") description := cmd.String("description") if code == "" && description == "" { fmt.Println("No updates provided. Use flags to specify what to update.") return nil } c := client.New(cfg.ServerURL) c.SetToken(cfg.Token) input := make(map[string]interface{}) if code != "" { input["code"] = code } if description != "" { input["description"] = description } mutation := `mutation UpdatePermission($id: ID!, $input: UpdatePermissionInput!) { updatePermission(id: $id, input: $input) { id code description } }` resp, err := c.Mutation(mutation, map[string]interface{}{"id": id, "input": input}) if err != nil { return err } var result struct { UpdatePermission *PermissionDetail `json:"updatePermission"` } if err := json.Unmarshal(resp.Data, &result); err != nil { return err } if result.UpdatePermission == nil { return fmt.Errorf("permission not found") } fmt.Printf("Permission updated successfully!\n") fmt.Printf("ID: %s\n", result.UpdatePermission.ID) fmt.Printf("Code: %s\n", result.UpdatePermission.Code) return nil } func permissionDelete(ctx context.Context, cmd *cli.Command) error { cfg, err := config.Load() if err != nil { return err } if err := RequireAuth(cfg); err != nil { return err } id := cmd.String("id") skipConfirm := cmd.Bool("yes") if !skipConfirm { confirm := false prompt := &survey.Confirm{ Message: fmt.Sprintf("Are you sure you want to delete permission %s?", id), Default: false, } if err := survey.AskOne(prompt, &confirm); err != nil { return err } if !confirm { fmt.Println("Deletion cancelled.") return nil } } c := client.New(cfg.ServerURL) c.SetToken(cfg.Token) mutation := `mutation DeletePermission($id: ID!) { deletePermission(id: $id) }` resp, err := c.Mutation(mutation, map[string]interface{}{"id": id}) if err != nil { return err } var result struct { DeletePermission bool `json:"deletePermission"` } if err := json.Unmarshal(resp.Data, &result); err != nil { return err } if result.DeletePermission { fmt.Printf("Permission %s deleted successfully.\n", id) } else { fmt.Printf("Failed to delete permission %s.\n", id) } return nil }