Skip to content

Commit

Permalink
PR(ACP): Add CLI Client For Adding Policy Command
Browse files Browse the repository at this point in the history
  • Loading branch information
shahzadlone committed Feb 29, 2024
1 parent 3644d9b commit 2e53560
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 8 deletions.
25 changes: 25 additions & 0 deletions cli/acp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2024 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package cli

import (
"github.com/spf13/cobra"
)

func MakeACPCommand() *cobra.Command {
var cmd = &cobra.Command{
Use: "acp",
Short: "Interact with the access control system of a DefraDB node",
Long: `Interact with the access control system of a DefraDB node`,
}

return cmd
}
25 changes: 25 additions & 0 deletions cli/acp_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2024 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package cli

import (
"github.com/spf13/cobra"
)

func MakeACPPolicyCommand() *cobra.Command {
var cmd = &cobra.Command{
Use: "policy",
Short: "Interact with the acp policy features of DefraDB instance",
Long: `Interact with the acp policy features of DefraDB instance`,
}

return cmd
}
147 changes: 147 additions & 0 deletions cli/acp_policy_add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright 2024 Democratized Data Foundation
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package cli

import (
"io"
"os"

"github.com/spf13/cobra"
)

func MakeACPPolicyAddCommand() *cobra.Command {
const identityFlagLongRequired string = "identity"
const identityFlagShortRequired string = "i"

const fileFlagLong string = "file"
const fileFlagShort string = "f"

var identitySignature string
var policyFile string

var cmd = &cobra.Command{
Use: "add [-i --identity] [policy]",
Short: "Add new policy",
Long: `Add new policy
Terminology:
- 'DPI' means 'DefraDB Policy Interface'.
- 'Permissioned Schema' means to have a policy on the schema: @policy(id:".." resource: "..")
Requirements:
- Must provide a valid [TODO-ACP Insert agreed upon name with bruno] signature identity.
- ACP module must be available (i.e. ACP not disabled).
- Policy specified must be a valid policy (but DPI compliance is not necessary).
- Policy specified must be in a valid JSON or YAML format (detected automatically).
Notes:
- A non-DPI policy is be accepted (will be registered with acp module).
- But only a valid DPI policyID & resource can be specified on a schema.
- DPI validation happens when attempting to add a permissioned schema.
- If DPI validation fails while adding schema, the schema is rejected.
Example: add from an argument string:
defradb client acp policy add -i cosmos1f2djr7dl9vhrk3twt3xwqp09nhtzec9mdkf70j '
description: A Valid DefraDB Policy Interface
actor:
name: actor
resources:
users:
permissions:
read:
expr: owner + reader
write:
expr: owner
relations:
owner:
types:
- actor
reader:
types:
- actor
'
Example: add from file:
defradb client acp policy add -i cosmos17r39df0hdcrgnmmw4mvu7qgk5nu888c7uvv37y -f policy.yml
Example: add from file, verbose flags:
defradb client acp policy add --identity cosmos1kpw734v54g0t0d8tcye8ee5jc3gld0tcr2q473 --file policy.yml
Example: add from stdin:
cat policy.yml | defradb client acp policy add -
Learn more about the DefraDB Policy Interface [TODO-ACP insert DPI Instruction link]
`,
RunE: func(cmd *cobra.Command, args []string) error {
if identitySignature == "" {
return NewErrRequiredFlagEmpty(identityFlagLongRequired, identityFlagShortRequired)
}

// TODO-ACP
// Handle required signature identity argument.
// Validate Identity that is provided to see if it is valid,
// if it is then all good, otherwise return this Error:
// return NewErrRequiredFlagInvalid(identityFlagLongRequired, identityFlagShortRequired)

// Handle policy argument.
extraArgsProvided := len(args)
var policy string
switch {
case policyFile != "":
data, err := os.ReadFile(policyFile)
if err != nil {
return err
}
policy = string(data)

case extraArgsProvided > 0 && args[extraArgsProvided-1] == "-":
data, err := io.ReadAll(cmd.InOrStdin())
if err != nil {
return err
}
policy = string(data)

case extraArgsProvided > 0:
policy = args[0]

default:
return ErrPolicyFileArgCanNotBeEmpty
}

store := mustGetContextStore(cmd)
policyResult, err := store.AddPolicy(
cmd.Context(),
identitySignature,
policy,
)

if err != nil {
return err
}

return writeJSON(cmd, policyResult)
},
}
cmd.Flags().StringVarP(&policyFile, fileFlagLong, fileFlagShort, "", "File to load a policy from")
cmd.Flags().StringVarP(
&identitySignature,
identityFlagLongRequired,
identityFlagShortRequired,
"",
"[Required] Signature identity of the creator",
)
_ = cmd.MarkFlagRequired(identityFlagLongRequired)

return cmd
}
11 changes: 11 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ func NewDefraCommand() *cobra.Command {
schema_migrate,
)

policy := MakeACPPolicyCommand()
policy.AddCommand(
MakeACPPolicyAddCommand(),
)

acp := MakeACPCommand()
acp.AddCommand(
policy,
)

view := MakeViewCommand()
view.AddCommand(
MakeViewAddCommand(),
Expand Down Expand Up @@ -102,6 +112,7 @@ func NewDefraCommand() *cobra.Command {
MakeDumpCommand(),
MakeRequestCommand(),
schema,
acp,
view,
index,
p2p,
Expand Down
28 changes: 20 additions & 8 deletions cli/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,37 @@
package cli

import (
"fmt"

"github.com/sourcenetwork/defradb/errors"
)

const (
errInvalidLensConfig string = "invalid lens configuration"
errSchemaVersionNotOfSchema string = "the given schema version is from a different schema"
errRequiredFlag string = "the required flag [--%s|-%s] is %s"
)

var (
ErrNoDocOrFile = errors.New("document or file must be defined")
ErrInvalidDocument = errors.New("invalid document")
ErrNoDocIDOrFilter = errors.New("docID or filter must be defined")
ErrInvalidExportFormat = errors.New("invalid export format")
ErrNoLensConfig = errors.New("lens config cannot be empty")
ErrInvalidLensConfig = errors.New("invalid lens configuration")
ErrSchemaVersionNotOfSchema = errors.New(errSchemaVersionNotOfSchema)
ErrViewAddMissingArgs = errors.New("please provide a base query and output SDL for this view")
ErrNoDocOrFile = errors.New("document or file must be defined")
ErrInvalidDocument = errors.New("invalid document")
ErrNoDocIDOrFilter = errors.New("docID or filter must be defined")
ErrInvalidExportFormat = errors.New("invalid export format")
ErrNoLensConfig = errors.New("lens config cannot be empty")
ErrInvalidLensConfig = errors.New("invalid lens configuration")
ErrSchemaVersionNotOfSchema = errors.New(errSchemaVersionNotOfSchema)
ErrViewAddMissingArgs = errors.New("please provide a base query and output SDL for this view")
ErrPolicyFileArgCanNotBeEmpty = errors.New("policy file argument can not be empty")
)

func NewErrRequiredFlagEmpty(longName string, shortName string) error {
return errors.New(fmt.Sprintf(errRequiredFlag, longName, shortName, "empty"))
}

func NewErrRequiredFlagInvalid(longName string, shortName string) error {
return errors.New(fmt.Sprintf(errRequiredFlag, longName, shortName, "invalid"))
}

func NewErrInvalidLensConfig(inner error) error {
return errors.Wrap(errInvalidLensConfig, inner)
}
Expand Down
11 changes: 11 additions & 0 deletions cli/schema_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ func MakeSchemaAddCommand() *cobra.Command {
Short: "Add new schema",
Long: `Add new schema.
Terminology:
- 'DPI' means 'DefraDB Policy Interface'.
- 'Permissioned Schema' means to have a policy on the schema: @policy(id:".." resource: "..")
Requirements:
- ACP module must be available if adding a permissioned schema (i.e. ACP not disabled).
- The specified policy and resource must be DPI compliant if adding a permissioned schema.
Notes:
- If DPI validation fails upon adding a schema, the schema is rejected.
Example: add from an argument string:
defradb client schema add 'type Foo { ... }'
Expand Down

0 comments on commit 2e53560

Please sign in to comment.