Skip to content

Commit

Permalink
feat(core): kas-grants list (#346)
Browse files Browse the repository at this point in the history
Resolves #332 
Resolves #253
  • Loading branch information
jakedoublev authored Sep 5, 2024
1 parent 8702ec0 commit 7f51282
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 124 deletions.
87 changes: 86 additions & 1 deletion cmd/kas-grants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"fmt"

"github.com/evertras/bubble-table/table"
"github.com/google/uuid"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -153,6 +155,80 @@ func policy_unassignKasGrant(cmd *cobra.Command, args []string) {
HandleSuccess(cmd, "", t, res)
}

func policy_listKasGrants(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
h := NewHandler(c)
defer h.Close()
kasF := c.Flags.GetOptionalString("kas")
var (
kasID string
kasURI string
)

// if not a UUID, infer flag value passed was a URI
if kasF != "" {
_, err := uuid.Parse(kasF)
if err != nil {
kasURI = kasF
} else {
kasID = kasF
}
}

grants, err := h.ListKasGrants(cmd.Context(), kasID, kasURI)
if err != nil {
cli.ExitWithError("Failed to list assigned KAS Grants", err)
}

rows := []table.Row{}
t := cli.NewTable(
// columns should be kas id, kas uri, type, id, fqn
table.NewFlexColumn("kas_id", "KAS ID", 3),
table.NewFlexColumn("kas_uri", "KAS URI", 3),
table.NewFlexColumn("grant_type", "Assigned To", 1),
table.NewFlexColumn("id", "Granted Object ID", 3),
table.NewFlexColumn("fqn", "Granted Object FQN", 3),
)

for _, g := range grants {
kasID := g.GetKeyAccessServer().GetId()
kasURI := g.GetKeyAccessServer().GetUri()
for _, ag := range g.GetAttributeGrants() {
rows = append(rows, table.NewRow(table.RowData{
"kas_id": kasID,
"kas_uri": kasURI,
"grant_type": "Definition",
"id": ag.GetId(),
"fqn": ag.GetFqn(),
}))
}
for _, vg := range g.GetValueGrants() {
rows = append(rows, table.NewRow(table.RowData{
"kas_id": kasID,
"kas_uri": kasURI,
"grant_type": "Value",
"id": vg.GetId(),
"fqn": vg.GetFqn(),
}))
}
for _, ng := range g.GetNamespaceGrants() {
rows = append(rows, table.NewRow(table.RowData{
"kas_id": kasID,
"kas_uri": kasURI,
"grant_type": "Namespace",
"id": ng.GetId(),
"fqn": ng.GetFqn(),
}))
}
}
t = t.WithRows(rows)

// Do not supporting printing the 'get --id=...' helper message as grants are atypical
// with no individual ID.
cmd.Use = ""
HandleSuccess(cmd, "", t, grants)
}

func init() {
assignCmd := man.Docs.GetCommand("policy/kas-grants/assign",
man.WithRun(policy_assignKasGrant),
Expand Down Expand Up @@ -217,8 +293,17 @@ func init() {
unassignCmd.GetDocFlag("force").Description,
)

listCmd := man.Docs.GetCommand("policy/kas-grants/list",
man.WithRun(policy_listKasGrants),
)
listCmd.Flags().StringP(
listCmd.GetDocFlag("kas").Name,
listCmd.GetDocFlag("kas").Shorthand,
listCmd.GetDocFlag("kas").Default,
listCmd.GetDocFlag("kas").Description,
)
cmd := man.Docs.GetCommand("policy/kas-grants",
man.WithSubcommands(assignCmd, unassignCmd),
man.WithSubcommands(assignCmd, unassignCmd, listCmd),
)
policyCmd.AddCommand(&cmd.Command)
}
7 changes: 6 additions & 1 deletion cmd/kas-registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,16 @@ func policy_createKeyAccessRegistry(cmd *cobra.Command, args []string) {
cli.ExitWithError("Failed to create Registered KAS entry", err)
}

keyJSON, err := protojson.Marshal(key)
if err != nil {
cli.ExitWithError("Failed to marshal public key to JSON", err)
}

rows := [][]string{
{"Id", created.GetId()},
{"URI", created.GetUri()},
{"PublicKey Type", keyType},
{"PublicKey", key.String()},
{"PublicKey", string(keyJSON)},
}
if mdRows := getMetadataRows(created.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
Expand Down
21 changes: 21 additions & 0 deletions docs/man/policy/kas-grants/list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: List KAS Grants

command:
name: list
aliases:
- l
description: List the Grants of KASes to Attribute Namespaces, Definitions, and Values
flags:
- name: kas
shorthand: k
description: The optional ID or URI of a KAS to filter the list
---

List the Grants of Registered Key Access Servers (KASes) to attribute namespaces, definitions,
or values.

Omitting `kas` lists all grants known to platform policy, otherwise results are filtered to
the KAS URI or ID specified by the flag value.

For more information, see `kas-registry` and `kas-grants` manuals.
12 changes: 12 additions & 0 deletions pkg/handlers/kas-grants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"github.com/opentdf/platform/protocol/go/policy/attributes"
"github.com/opentdf/platform/protocol/go/policy/kasregistry"
"github.com/opentdf/platform/protocol/go/policy/namespaces"
)

Expand Down Expand Up @@ -96,3 +97,14 @@ func (h Handler) DeleteKasGrantFromNamespace(ctx context.Context, ns_id string,

return resp.GetNamespaceKeyAccessServer(), nil
}

func (h Handler) ListKasGrants(ctx context.Context, kas_id, kas_uri string) ([]*kasregistry.KeyAccessServerGrants, error) {
resp, err := h.sdk.KeyAccessServerRegistry.ListKeyAccessServerGrants(ctx, &kasregistry.ListKeyAccessServerGrantsRequest{
KasId: kas_id,
KasUri: kas_uri,
})
if err != nil {
return nil, err
}
return resp.GetGrants(), nil
}
Loading

0 comments on commit 7f51282

Please sign in to comment.