Skip to content

Commit

Permalink
update query pkg to support role-binding V2, add v2 APIs
Browse files Browse the repository at this point in the history
Signed-off-by: Bailin He <[email protected]>
  • Loading branch information
bailinhe committed Mar 12, 2024
1 parent 7064a66 commit ccd4b7c
Show file tree
Hide file tree
Showing 32 changed files with 5,590 additions and 221 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@

# NATS dirs
.devcontainer/nsc/
resolver.conf

# binary files
permissions-api
tmp
58 changes: 41 additions & 17 deletions cmd/createrole.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ import (
"go.infratographer.com/permissions-api/internal/query"
"go.infratographer.com/permissions-api/internal/spicedbx"
"go.infratographer.com/permissions-api/internal/storage"
"go.infratographer.com/permissions-api/internal/types"
)

const (
createRoleFlagSubject = "subject"
createRoleFlagResource = "resource"
createRoleFlagActions = "actions"
createRoleFlagName = "name"
createRoleFlagIsV2 = "v2"
)

var (
createRoleCmd = &cobra.Command{
Use: "create-role",
Short: "create role in SpiceDB directly",
Run: func(cmd *cobra.Command, args []string) {
createRole(cmd.Context(), globalCfg)
},
}
)
var createRoleCmd = &cobra.Command{
Use: "create-role",
Short: "create role in SpiceDB directly",
Run: func(cmd *cobra.Command, _ []string) {
createRole(cmd.Context(), globalCfg)
},
}

func init() {
rootCmd.AddCommand(createRoleCmd)
Expand All @@ -42,20 +42,23 @@ func init() {
flags.StringSlice(createRoleFlagActions, []string{}, "actions to assign to created role")
flags.String(createRoleFlagResource, "", "resource to bind to created role")
flags.String(createRoleFlagName, "", "name of role to create")
flags.Bool(createRoleFlagIsV2, false, "create a v2 role")

v := viper.GetViper()

viperx.MustBindFlag(v, createRoleFlagSubject, flags.Lookup(createRoleFlagSubject))
viperx.MustBindFlag(v, createRoleFlagActions, flags.Lookup(createRoleFlagActions))
viperx.MustBindFlag(v, createRoleFlagResource, flags.Lookup(createRoleFlagResource))
viperx.MustBindFlag(v, createRoleFlagName, flags.Lookup(createRoleFlagName))
viperx.MustBindFlag(v, createRoleFlagIsV2, flags.Lookup(createRoleFlagIsV2))
}

func createRole(ctx context.Context, cfg *config.AppConfig) {
subjectIDStr := viper.GetString(createRoleFlagSubject)
actions := viper.GetStringSlice(createRoleFlagActions)
resourceIDStr := viper.GetString(createRoleFlagResource)
name := viper.GetString(createRoleFlagName)
v2 := viper.GetBool(createRoleFlagIsV2)

if subjectIDStr == "" || len(actions) == 0 || resourceIDStr == "" || name == "" {
logger.Fatal("invalid config")
Expand Down Expand Up @@ -125,14 +128,35 @@ func createRole(ctx context.Context, cfg *config.AppConfig) {
logger.Fatalw("error creating subject resource", "error", err)
}

role, err := engine.CreateRole(ctx, subjectResource, resource, name, actions)
if err != nil {
logger.Fatalw("error creating role", "error", err)
}
if v2 {
role, err := engine.CreateRoleV2(ctx, subjectResource, resource, name, actions)
if err != nil {
logger.Fatalw("error creating role", "error", err)
}

if err = engine.AssignSubjectRole(ctx, subjectResource, role); err != nil {
logger.Fatalw("error creating role", "error", err)
}
rbsubj := []types.RoleBindingSubject{{SubjectResource: subjectResource}}

roleres, err := engine.NewResourceFromID(role.ID)
if err != nil {
logger.Fatalw("error creating role resource", "error", err)
}

logger.Infow("role successfully created", "role_id", role.ID)
rb, err := engine.CreateRoleBinding(ctx, resource, roleres, rbsubj)
if err != nil {
logger.Fatalw("error creating role binding", "error", err)
}

logger.Infof("created role %s[%s] and role-binding %s", role.Name, role.ID, rb.ID)
} else {
role, err := engine.CreateRole(ctx, subjectResource, resource, name, actions)
if err != nil {
logger.Fatalw("error creating role", "error", err)
}

if err = engine.AssignSubjectRole(ctx, subjectResource, role); err != nil {
logger.Fatalw("error creating role", "error", err)
}

logger.Infow("role successfully created", "role_id", role.ID)
}
}
26 changes: 25 additions & 1 deletion cmd/schema_mermaid.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ import (

var (
mermaidTemplate = `erDiagram
{{- if ne .RBAC.RoleResource nil}}
{{ .RBAC.RoleBindingResource }} }o--o{ {{ .RBAC.RoleResource }} : role
{{- range $subj := .RBAC.RoleBindingSubjects }}
{{ $.RBAC.RoleBindingResource }} }o--o{ {{ $subj.Name }} : subject
{{- end }}
{{- end }}
{{- range $resource := .ResourceTypes }}
{{ $resource.Name }} {
id_prefix {{ $resource.IDPrefix }}
Expand All @@ -29,6 +36,11 @@ var (
{{- range $targetName := $rel.TargetTypeNames }}
{{ $resource.Name }} }o--o{ {{ $targetName }} : {{ $rel.Relation }}
{{- end }}
{{- range $target := $rel.TargetTypes }}
{{ $resource.Name }} }o--o{ {{ $target.Name -}} : {{ $rel.Relation -}}
{{- end }}
{{- end }}
{{- end }}
{{- range $union := .Unions }}
Expand All @@ -45,7 +57,13 @@ var (
{{- range $typ := $union.ResourceTypeNames }}
{{ $union.Name }} ||--|| {{ $typ }} : alias
{{- end }}
{{- end }}`
{{- range $typ := $union.ResourceTypes }}
{{ $union.Name }} ||--|| {{ $typ.Name -}} : alias
{{- end}}
{{- end }}
`

mermaidTmpl = template.Must(template.New("mermaid").Parse(mermaidTemplate))
)
Expand All @@ -55,6 +73,7 @@ type mermaidContext struct {
Unions []iapl.Union
Actions map[string][]string
RelatedActions map[string]map[string][]string
RBAC *iapl.RBAC
}

func outputPolicyMermaid(filePath string, markdown bool) {
Expand Down Expand Up @@ -99,6 +118,11 @@ func outputPolicyMermaid(filePath string, markdown bool) {
Unions: policy.Unions,
Actions: actions,
RelatedActions: relatedActions,
RBAC: nil,
}

if policy.RBAC != nil {
ctx.RBAC = policy.RBAC
}

var out bytes.Buffer
Expand Down
6 changes: 2 additions & 4 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import (
"go.infratographer.com/permissions-api/internal/storage"
)

var (
apiDefaultListen = "0.0.0.0:7602"
)
var apiDefaultListen = "0.0.0.0:7602"

var serverCmd = &cobra.Command{
Use: "server",
Expand Down Expand Up @@ -89,7 +87,7 @@ func serve(ctx context.Context, cfg *config.AppConfig) {
logger.Fatalw("invalid spicedb policy", "error", err)
}

engine, err := query.NewEngine("infratographer", spiceClient, kv, store, query.WithPolicy(policy))
engine, err := query.NewEngine("infratographer", spiceClient, kv, store, query.WithPolicy(policy), query.WithLogger(logger))
if err != nil {
logger.Fatalw("error creating engine", "error", err)
}
Expand Down
Loading

0 comments on commit ccd4b7c

Please sign in to comment.