From f53b61dd79c463e363cf5340517fea74c491cdba Mon Sep 17 00:00:00 2001 From: Krish Suchak <42231639+suchak1@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:38:00 -0400 Subject: [PATCH] feat(core): kas-grants CRUD (#80) Co-authored-by: Jake Van Vorhis <83739412+jakedoublev@users.noreply.github.com> --- cmd/kas-grants.go | 134 +++++++++++++++++++++++++++++++++++++ pkg/handlers/kas-grants.go | 65 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 cmd/kas-grants.go create mode 100644 pkg/handlers/kas-grants.go diff --git a/cmd/kas-grants.go b/cmd/kas-grants.go new file mode 100644 index 00000000..9d9f297d --- /dev/null +++ b/cmd/kas-grants.go @@ -0,0 +1,134 @@ +package cmd + +import ( + "strings" + + "github.com/opentdf/tructl/pkg/cli" + "github.com/spf13/cobra" +) + +var ( + kasGrants_crudCommands = []string{ + kasGrantsUpdateCmd.Use, + kasGrantsDeleteCmd.Use, + } + + // KasGrantsCmd is the command for managing KAS grants + kasGrantsCmd = &cobra.Command{ + Use: "kas-grants", + Short: "Manage Key Access Server grants [" + strings.Join(kasGrants_crudCommands, ", ") + "]", + } + + // Update one KAS registry entry + kasGrantsUpdateCmd = &cobra.Command{ + Use: "update", + Short: "Update a KAS grant", + Run: func(cmd *cobra.Command, args []string) { + h := cli.NewHandler(cmd) + defer h.Close() + + flagHelper := cli.NewFlagHelper(cmd) + + attr := flagHelper.GetOptionalString("attribute") + val := flagHelper.GetOptionalString("value") + kas := flagHelper.GetRequiredString("kas") + + if attr == "" && val == "" { + cli.ExitWithError("Must specify and Attribute Definition id or Value id to update.", nil) + } + var ( + id string + header string + res interface{} + err error + ) + + if attr != "" { + res, err = h.UpdateKasGrantForAttribute(attr, kas) + if err != nil { + cli.ExitWithError("Could not update KAS grant for attribute", err) + } + id = attr + header = "Attribute ID" + } else { + res, err = h.UpdateKasGrantForValue(val, kas) + if err != nil { + cli.ExitWithError("Could not update KAS grant for attribute value", err) + } + id = val + header = "Value ID" + } + + t := cli.NewTabular(). + Rows([][]string{ + {header, id}, + {"KAS ID", kas}, + }...) + HandleSuccess(cmd, id, t, res) + }, + } + + kasGrantsDeleteCmd = &cobra.Command{ + Use: "delete", + Short: "Delete a KAS grant", + Run: func(cmd *cobra.Command, args []string) { + h := cli.NewHandler(cmd) + defer h.Close() + + flagHelper := cli.NewFlagHelper(cmd) + attr := flagHelper.GetOptionalString("attribute") + val := flagHelper.GetOptionalString("value") + kas := flagHelper.GetRequiredString("kas") + + if attr == "" && val == "" { + cli.ExitWithError("Must specify and Attribute Definition id or Value id to delete.", nil) + } + var ( + id string + header string + res interface{} + err error + ) + + cli.ConfirmDelete("KAS ID: ", kas) + + if attr != "" { + res, err = h.DeleteKasGrantFromAttribute(attr, kas) + if err != nil { + cli.ExitWithError("Could not update KAS grant for attribute", err) + } + id = attr + header = "Attribute ID" + } else { + _, err := h.DeleteKasGrantFromValue(val, kas) + if err != nil { + cli.ExitWithError("Could not update KAS grant for attribute value", err) + } + id = val + header = "Value ID" + } + + t := cli.NewTabular(). + Rows([][]string{ + {header, id}, + {"KAS ID", kas}, + }...) + HandleSuccess(cmd, id, t, res) + }, + } +) + +func init() { + policyCmd.AddCommand(kasGrantsCmd) + + kasGrantsCmd.AddCommand(kasGrantsUpdateCmd) + kasGrantsUpdateCmd.Flags().StringP("attribute", "a", "", "Attribute Definition ID") + kasGrantsUpdateCmd.Flags().StringP("value", "v", "", "Attribute Value ID") + kasGrantsUpdateCmd.Flags().StringP("kas", "k", "", "Key Access Server (KAS) ID") + injectLabelFlags(kasGrantsUpdateCmd, true) + + kasGrantsCmd.AddCommand(kasGrantsDeleteCmd) + kasGrantsDeleteCmd.Flags().StringP("attribute", "a", "", "Attribute Definition ID") + kasGrantsDeleteCmd.Flags().StringP("value", "v", "", "Attribute Value ID") + kasGrantsDeleteCmd.Flags().StringP("kas", "k", "", "Key Access Server (KAS) ID") +} diff --git a/pkg/handlers/kas-grants.go b/pkg/handlers/kas-grants.go new file mode 100644 index 00000000..162fa31e --- /dev/null +++ b/pkg/handlers/kas-grants.go @@ -0,0 +1,65 @@ +package handlers + +import ( + "github.com/opentdf/platform/protocol/go/policy/attributes" +) + +func (h Handler) UpdateKasGrantForAttribute(attr_id string, kas_id string) (*attributes.AttributeKeyAccessServer, error) { + kas := &attributes.AttributeKeyAccessServer{ + AttributeId: attr_id, + KeyAccessServerId: kas_id, + } + resp, err := h.sdk.Attributes.AssignKeyAccessServerToAttribute(h.ctx, &attributes.AssignKeyAccessServerToAttributeRequest{ + AttributeKeyAccessServer: kas, + }) + if err != nil { + return nil, err + } + + return resp.AttributeKeyAccessServer, nil +} + +func (h Handler) DeleteKasGrantFromAttribute(attr_id string, kas_id string) (*attributes.AttributeKeyAccessServer, error) { + kas := &attributes.AttributeKeyAccessServer{ + AttributeId: attr_id, + KeyAccessServerId: kas_id, + } + resp, err := h.sdk.Attributes.RemoveKeyAccessServerFromAttribute(h.ctx, &attributes.RemoveKeyAccessServerFromAttributeRequest{ + AttributeKeyAccessServer: kas, + }) + if err != nil { + return nil, err + } + + return resp.AttributeKeyAccessServer, nil +} + +func (h Handler) UpdateKasGrantForValue(val_id string, kas_id string) (*attributes.ValueKeyAccessServer, error) { + kas := &attributes.ValueKeyAccessServer{ + ValueId: val_id, + KeyAccessServerId: kas_id, + } + resp, err := h.sdk.Attributes.AssignKeyAccessServerToValue(h.ctx, &attributes.AssignKeyAccessServerToValueRequest{ + ValueKeyAccessServer: kas, + }) + if err != nil { + return nil, err + } + + return resp.ValueKeyAccessServer, nil +} + +func (h Handler) DeleteKasGrantFromValue(val_id string, kas_id string) (*attributes.ValueKeyAccessServer, error) { + kas := &attributes.ValueKeyAccessServer{ + ValueId: val_id, + KeyAccessServerId: kas_id, + } + resp, err := h.sdk.Attributes.RemoveKeyAccessServerFromValue(h.ctx, &attributes.RemoveKeyAccessServerFromValueRequest{ + ValueKeyAccessServer: kas, + }) + if err != nil { + return nil, err + } + + return resp.ValueKeyAccessServer, nil +}