Skip to content

Commit

Permalink
service-token delete-access for Orgs
Browse files Browse the repository at this point in the history
This enables `delete-access` to work for org level permissions.

Now by leaving `--database` off, it will send a delete request for org level token access.
  • Loading branch information
mscoutermarsh committed Dec 8, 2023
1 parent ea56f97 commit 05b5dfb
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 11 deletions.
36 changes: 27 additions & 9 deletions internal/cmd/token/deleteaccess.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ func DeleteAccessCmd(ch *cmdutil.Helper) *cobra.Command {
cmd := &cobra.Command{
Use: "delete-access <token> <access> <access> ...",
Short: "delete access granted to a service token in the organization",
Example: `The delete-access command removes an access grant from a service token.
For example, to remove access for a specific database, include the --database flag:
pscale service-token remove-access <token id> read_branch --database <database name>
To remove an organization level grant:
pscale service-token add-access <token id> delete_databases`,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
client, err := ch.Client()
Expand All @@ -29,19 +38,24 @@ func DeleteAccessCmd(ch *cmdutil.Helper) *cobra.Command {

req := &planetscale.DeleteServiceTokenAccessRequest{
ID: token,
Database: ch.Config.Database,
Organization: ch.Config.Organization,
Accesses: perms,
}

if ch.Config.Database != "" {
req.Database = ch.Config.Database
}

end := ch.Printer.PrintProgress(fmt.Sprintf("Removing access %s on database %s", printer.BoldBlue(strings.Join(perms, ", ")), printer.BoldBlue(ch.Config.Database)))
defer end()

if err := client.ServiceTokens.DeleteAccess(ctx, req); err != nil {
err = client.ServiceTokens.DeleteAccess(ctx, req)

if err != nil {
switch cmdutil.ErrCode(err) {
case planetscale.ErrNotFound:
return fmt.Errorf("database %s or token does not exist in organization %s",
printer.BoldBlue(ch.Config.Database), printer.BoldBlue(ch.Config.Organization))
return fmt.Errorf("token %s does not exist in organization %s.\nPlease run 'pscale service-token list' to see a list of tokens",
printer.BoldBlue(token), printer.BoldBlue(ch.Config.Organization))
default:
return cmdutil.HandleError(err)
}
Expand All @@ -50,22 +64,26 @@ func DeleteAccessCmd(ch *cmdutil.Helper) *cobra.Command {
end()

if ch.Printer.Format() == printer.Human {
ch.Printer.Printf("Accesses %v were successfully deleted.\n",
printer.BoldBlue(strings.Join(perms, ",")))
if len(perms) == 1 {
ch.Printer.Printf("%v has been removed.\n",
printer.BoldBlue(perms[0]))
} else {
ch.Printer.Printf("%v have been removed.\n",
printer.BoldBlue(strings.Join(perms, ", ")))
}
return nil
}

return ch.Printer.PrintResource(
map[string]string{
"result": "accesses deleted",
"result": "access removed",
"perms": strings.Join(perms, ","),
},
)
},
}

cmd.PersistentFlags().StringVar(&ch.Config.Database, "database", ch.Config.Database, "The database this project is using")
cmd.MarkPersistentFlagRequired("database") // nolint:errcheck
cmd.PersistentFlags().StringVar(&ch.Config.Database, "database", ch.Config.Database, "The database to remove access to")

return cmd
}
55 changes: 53 additions & 2 deletions internal/cmd/token/deleteaccess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestServiceToken_DeleteAccessCmd(t *testing.T) {
DeleteAccessFn: func(ctx context.Context, req *ps.DeleteServiceTokenAccessRequest) error {
c.Assert(req.Organization, qt.Equals, org)
c.Assert(req.ID, qt.Equals, token)
c.Assert(req.ID, qt.Equals, token)
c.Assert(req.Database, qt.Equals, db)
c.Assert(req.Accesses, qt.DeepEquals, accesses)
return nil
},
Expand Down Expand Up @@ -61,8 +61,59 @@ func TestServiceToken_DeleteAccessCmd(t *testing.T) {
c.Assert(svc.DeleteAccessFnInvoked, qt.IsTrue)

res := map[string]string{
"result": "accesses deleted",
"result": "access removed",
"perms": "read_branch,delete_branch",
}
c.Assert(buf.String(), qt.JSONEquals, res)
}

func TestServiceToken_DeleteOrganizationAccessCmd(t *testing.T) {
c := qt.New(t)

var buf bytes.Buffer
format := printer.JSON
p := printer.NewPrinter(&format)
p.SetResourceOutput(&buf)

org := "planetscale"
token := "123456"
accesses := []string{"delete_databases", "create_databases"}

svc := &mock.ServiceTokenService{
DeleteAccessFn: func(ctx context.Context, req *ps.DeleteServiceTokenAccessRequest) error {
c.Assert(req.Organization, qt.Equals, org)
c.Assert(req.ID, qt.Equals, token)
c.Assert(req.Database, qt.Equals, "")
c.Assert(req.Accesses, qt.DeepEquals, accesses)
return nil
},
}

ch := &cmdutil.Helper{
Printer: p,
Config: &config.Config{
Organization: org,
},
Client: func() (*ps.Client, error) {
return &ps.Client{
ServiceTokens: svc,
}, nil
},
}

args := []string{token}
args = append(args, accesses...)

cmd := DeleteAccessCmd(ch)
cmd.SetArgs(args)
err := cmd.Execute()

c.Assert(err, qt.IsNil)
c.Assert(svc.DeleteAccessFnInvoked, qt.IsTrue)

res := map[string]string{
"result": "access removed",
"perms": "delete_databases,create_databases",
}
c.Assert(buf.String(), qt.JSONEquals, res)
}

0 comments on commit 05b5dfb

Please sign in to comment.