3
0

Base CUE, def, schemas

This commit is contained in:
Denis Arh
2021-12-27 15:12:58 +01:00
parent 691481424a
commit c19ee84f5d
42 changed files with 1760 additions and 872 deletions

16
app/app.cue Normal file
View File

@@ -0,0 +1,16 @@
package app
import (
"github.com/cortezaproject/corteza-server/def/schema"
"github.com/cortezaproject/corteza-server/system"
"github.com/cortezaproject/corteza-server/compose"
)
corteza: schema.#platform & {
ident: "corteza"
components: [
system.component,
compose.component,
]
}

1
codecov.cue Normal file
View File

@@ -0,0 +1 @@
ignore: ["vendor/.*"]

10
codegen/all.cue Normal file
View File

@@ -0,0 +1,10 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
all: [...schema.#codegen] &
rbacAccessControl +
rbacTypes +
[] // placeholder

View File

@@ -0,0 +1,5 @@
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//

View File

@@ -1,7 +1,6 @@
package {{ .Package }}
package {{ .package }}
{{ template "header-gentext.tpl" }}
{{ template "header-definitions.tpl" . }}
{{ template "gocode/header-gentext.tpl" }}
import (
"fmt"
@@ -10,8 +9,8 @@ import (
"context"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
{{- range .Imports }}
{{ . }}
{{- range .imports }}
"{{ . }}"
{{- end }}
)
@@ -26,7 +25,6 @@ type (
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
}
}
)
@@ -56,17 +54,13 @@ func (svc accessControl) Effective(ctx context.Context, rr ... rbac.Resource) (e
func (svc accessControl) List() (out []map[string]string) {
def := []map[string]string{
{{- range .Def }}
{{- $Resource := .Resource }}
{{- $RbacResource := .RBAC.Resource }}
{{- range .RBAC.Operations }}
{{- range .operations }}
{
"type": types.{{ coalesce $Resource }}ResourceType,
"any": types.{{ coalesce $Resource }}RbacResource({{ range $RbacResource.References }}0,{{ end }}),
"op": {{ printf "%q" .Operation }},
"type": {{ .const }},
"any": {{ .ctor }},
"op": {{ printf "%q" .op }},
},
{{- end }}
{{- end }}
}
func(svc interface{}) {
@@ -143,42 +137,24 @@ func (svc accessControl) CloneRulesByRoleID(ctx context.Context, fromRoleID uint
return svc.rbac.CloneRulesByRoleID(ctx, fromRoleID, toRoleID...)
}
{{- range .Def }}
{{ $GoType := printf "types.%s" (.Resource) }}
{{ if .IsComponentResource }}
{{- range .RBAC.Operations }}
// {{ export .CanFnName }} checks if current user can {{ lower .Description }}
//
// This function is auto-generated
func (svc accessControl) {{ export .CanFnName }}(ctx context.Context) bool {
return svc.can(ctx, {{ printf "%q" .Operation }}, &types.Component{})
}
{{- end }}
{{ else }}
{{- range .RBAC.Operations }}
// {{ export .CanFnName }} checks if current user can {{ lower .Description }}
//
// This function is auto-generated
func (svc accessControl) {{ export .CanFnName }}(ctx context.Context, r * {{ $GoType }}) bool {
return svc.can(ctx, {{ printf "%q" .Operation }}, r)
}
{{- end }}
{{ end }}
{{- range .operations }}
// {{ .checkFuncName }} checks if current user can {{ lower .description }}
//
// This function is auto-generated
func (svc accessControl) {{ .checkFuncName }}(ctx context.Context{{ if not .component }}, r *{{ .goType }}{{ end }}) bool {
{{- if .component }}r := &{{ .goType }}{}{{ end }}
return svc.can(ctx, {{ printf "%q" .op }}, r)
}
{{- end }}
// rbacResourceValidator validates known component's resource by routing it to the appropriate validator
//
// This function is auto-generated
func rbacResourceValidator(r string, oo ...string) error {
switch rbac.ResourceType(r) {
{{- range .Def }}
case types.{{ coalesce .Resource }}ResourceType:
return rbac{{ .Resource }}ResourceValidator(r, oo...)
{{- range .validation }}
case {{ .const }}:
return {{ .funcName }}(r, oo...)
{{- end }}
}
@@ -190,11 +166,11 @@ func rbacResourceValidator(r string, oo ...string) error {
// This function is auto-generated
func rbacResourceOperations(r string) map[string]bool {
switch rbac.ResourceType(r) {
{{- range .Def }}
case types.{{ coalesce .Resource }}ResourceType:
{{- range .validation }}
case {{ .const }}:
return map[string]bool{
{{- range .RBAC.Operations }}
{{ printf "%q" .Operation }}: true,
{{- range .operations }}
{{ printf "%q" . }}: true,
{{- end }}
}
{{- end }}
@@ -203,57 +179,53 @@ func rbacResourceOperations(r string) map[string]bool {
return nil
}
{{- range .Def }}
{{- range .validation }}
{{ $Resource := .Resource }}
{{ $GoType := printf "types.%s" (.Resource) }}
// rbac{{ .Resource }}ResourceValidator checks validity of rbac resource and operations
// {{ .funcName }} checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbac{{ .Resource }}ResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for {{ .Component }}{{ if not .IsComponentResource }} {{ .Resource }}{{end }} resource", o)
}
}
if !strings.HasPrefix(r, {{ $GoType }}ResourceType) {
func {{ .funcName }}(r string, oo ...string) error {
if !strings.HasPrefix(r, {{ .const }}) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for {{ .label }} resource", o)
}
}
{{ if .RBAC.Resource.References }}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len({{ $GoType }}ResourceType):], sep), sep)
prc = []string{
{{- range .RBAC.Resource.References }}
{{ printf "%q" .Field }},
{{ if .references }}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len({{ .const }}):], sep), sep)
prc = []string{
{{- range .references }}
{{ printf "%q" . }},
{{- end }}
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for {{ .label }} resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
{{- end }}
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for {{ .Resource }}", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
{{- end }}
return nil
}
{{- end }}

View File

@@ -0,0 +1,78 @@
package {{ .package }}
{{ template "gocode/header-gentext.tpl" }}
import (
"fmt"
"strconv"
)
type (
// Component struct serves as a virtual resource type for the {{ .cmpIdent }} component
//
// This struct is auto-generated
Component struct {}
)
var (
{{/*
making sure that generated code does not break
when these packages are not used
*/}}
_ = fmt.Printf
_ = strconv.FormatUint
)
const (
{{- range .types }}
{{ .const }} = {{ printf "%q" .type }}
{{- end }}
)
{{- range .types }}
// RbacResource returns string representation of RBAC resource for {{ .goType }} by calling {{ .resFunc }} fn
//
// RBAC resource is in the {{ .type }}/... format
//
// This function is auto-generated
func (r {{ .goType }}) RbacResource() string {
return {{ .resFunc }}({{ if not .component }}{{ range .references }}r.{{ . }},{{ end }}{{ end }})
}
// {{ .resFunc }} returns string representation of RBAC resource for {{ .goType }}
//
// RBAC resource is in the {{ .type }}/{{- if .references }}...{{ end }} format
//
// This function is auto-generated
func {{ .resFunc }}({{ if not .component }}{{ range .references }}{{ . }} uint64,{{ end }}{{ end }}) string {
{{- if .references }}
cpts := []interface{{"{}"}}{{"{"}}{{ .goType }}ResourceType{{"}"}}
{{- range .references }}
if {{ . }} != 0 {
cpts = append(cpts, strconv.FormatUint({{ . }}, 10))
} else {
cpts = append(cpts, "*")
}
{{ end }}
return fmt.Sprintf({{ .tplFunc }}(), cpts...)
{{- else }}
return {{ .goType }}ResourceType + "/"
{{- end }}
}
func {{ .tplFunc }}() string {
{{- if .references }}
return "%s
{{- range .references }}/%s{{- end }}"
{{- else }}
return "%s"
{{- end }}
}
{{- end }}

View File

@@ -0,0 +1,60 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/codegen/schema"
"github.com/cortezaproject/corteza-server/app"
)
rbacAccessControl:
[...schema.#codegen] &
[
for cmp in app.corteza.components {
template: "gocode/rbac/access_control.go.tpl"
output: "\(cmp.ident)/service/access_control.gen.go"
payload: {
imports: [
"github.com/cortezaproject/corteza-server/\(cmp.ident)/types",
]
package: "service"
// All possible RBAC operations on component and resources
// flattened
operations: [
for res in cmp.resources for op in res.rbac.operations {
"op": op.handle
"const": "types.\(res.expIdent)ResourceType"
"ctor": "types.\(res.expIdent)RbacResource(\(len(res.rbac.resource.references)*"0,"))"
"goType": res.goType
"description": op.description
"checkFuncName": op.checkFuncName
},
for op in cmp.rbac.operations {
"op": op.handle
"const": "types.ComponentResourceType"
"ctor": "types.ComponentRbacResource()"
"goType": "types.Component"
"description": op.description
"checkFuncName": op.checkFuncName
"component": true
},
]
// Operation/resource validators, grouped by resource
validation: [
for res in cmp.resources {
"label": res.ident
"const": "types.\(res.expIdent)ResourceType"
"funcName": "rbac\(res.expIdent)ResourceValidator"
"references": res.rbac.resource.references
"operations": [ for op in res.rbac.operations {op.handle}]
},
{
"label": "\(cmp.ident) component"
"const": "types.ComponentResourceType"
"funcName": "rbacComponentResourceValidator"
"operations": [ for op in cmp.rbac.operations {op.handle}]
},
]
}
},
]

43
codegen/rbac-types.cue Normal file
View File

@@ -0,0 +1,43 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/app"
"github.com/cortezaproject/corteza-server/codegen/schema"
"strings"
)
rbacTypes:
[...schema.#codegen] &
[
for cmp in app.corteza.components {
template: "gocode/rbac/types.go.tpl"
output: "\(cmp.ident)/types/rbac.gen.go"
payload: {
package: "types"
cmpIdent: cmp.ident
// Operation/resource validators, grouped by resource
types: [
for res in cmp.resources {
"const": "\(res.expIdent)ResourceType"
"type": res.rbac.resource.type
"resFunc": "\(res.expIdent)RbacResource"
"tplFunc": "\(res.expIdent)RbacResourceTpl"
"attFunc": "\(res.expIdent)RbacAttributes"
"goType": res.expIdent
"references": [ for field in res.rbac.resource.references { strings.ToTitle(field) } ]
},
{
"const": "ComponentResourceType"
"type": cmp.rbac.resource.type
"resFunc": "ComponentRbacResource"
"tplFunc": "ComponentRbacResourceTpl"
"attFunc": "ComponentRbacAttributes"
"goType": "Component"
"component": true
},
]
}
},
]

View File

@@ -0,0 +1,13 @@
package schema
#codegen: {
template: string
output: string
syntax: "go"
if output =~ "\\.adoc" {
syntax: "adoc"
}
payload: _
}

74
codegen/tool/main.go Normal file
View File

@@ -0,0 +1,74 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"text/template"
"github.com/cortezaproject/corteza-server/pkg/cli"
)
type (
task struct {
Template string `json:"template"`
Output string `json:"output"`
Syntax string `json:"syntax"`
Payload interface{} `json:"payload"`
}
)
var (
verbose bool
showHelp bool
tplRootPath string
)
func init() {
flag.BoolVar(&showHelp, "h", false, "show help")
flag.BoolVar(&verbose, "v", false, "be verbose")
flag.StringVar(&tplRootPath, "p", "codegen/assets/templates", "location of the template files")
flag.Parse()
}
// Takes JSON input with codegen tasks and definitions and generates files
func main() {
if showHelp {
flag.PrintDefaults()
os.Exit(0)
}
var (
input = json.NewDecoder(os.Stdin)
tasks = make([]*task, 0)
tpl *template.Template
err error
)
print("Waiting for stdin ...\n")
if err = input.Decode(&tasks); err != nil {
cli.HandleError(fmt.Errorf("failed to decode input from standard input: %v", err))
}
if tpl, err = LoadTemplates(BaseTemplate(), tplRootPath); err != nil {
cli.HandleError(fmt.Errorf("failed to load templates: %v", err))
}
for _, j := range tasks {
switch j.Syntax {
case "go":
print(fmt.Sprintf("generating %s (from %s) ...", j.Output, j.Template))
if err = GoTemplate(j.Output, tpl.Lookup(j.Template), j.Payload); err != nil {
cli.HandleError(fmt.Errorf("failed to write template: %v", err))
}
print("done\n")
}
}
}
func print(msg string) {
if verbose {
_, _ = fmt.Fprint(os.Stderr, msg)
}
}

View File

@@ -0,0 +1,78 @@
package main
import (
"bytes"
"fmt"
"go/format"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/Masterminds/sprig"
)
func BaseTemplate() *template.Template {
return template.New("").
Funcs(sprig.TxtFuncMap())
}
func LoadTemplates(rTpl *template.Template, rootDir string) (*template.Template, error) {
cleanRoot := filepath.Clean(rootDir)
pfx := len(cleanRoot) + 1
return rTpl, filepath.Walk(cleanRoot, func(path string, info os.FileInfo, err error) error {
if info.IsDir() || !strings.HasSuffix(path, ".tpl") || err != nil {
return err
}
b, err := ioutil.ReadFile(path)
if err != nil {
return err
}
name := path[pfx:]
rTpl, err = rTpl.New(name).Parse(string(b))
return err
})
}
func GoTemplate(dst string, tpl *template.Template, payload interface{}) (err error) {
var output io.WriteCloser
buf := bytes.Buffer{}
if tpl == nil {
return fmt.Errorf("could not find template for %s", dst)
}
if err := tpl.Execute(&buf, payload); err != nil {
return err
}
fmtsrc, err := format.Source(buf.Bytes())
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "%s fmt warn: %v\n", dst, err)
err = nil
fmtsrc = buf.Bytes()
}
if dst == "" || dst == "-" {
output = os.Stdout
} else {
if output, err = os.Create(dst); err != nil {
return err
}
defer output.Close()
}
if _, err = output.Write(fmtsrc); err != nil {
return err
}
return nil
}

23
compose/chart.cue Normal file
View File

@@ -0,0 +1,23 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
chart: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "ID"]
operations: {
"read": {}
"update": {}
"delete": {}
}
}
// locale:
// resource:
// references: [ namespace, ID ]
// keys:
// - name
}

26
compose/component.cue Normal file
View File

@@ -0,0 +1,26 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
component: schema.#component & {
ident: "compose"
resources: {
"namespace": namespace
"module": module
"module-field": moduleField
"record": record
"page": page
"chart": chart
}
rbac: operations: {
"settings.read": description: "Read settings"
"settings.manage": description: "Manage settings"
"namespace.create": description: "Create namespace"
"namespaces.search": description: "List, search or filter namespaces"
"resource-translations.manage": description: "List, search, create, or update resource translations"
}
}

34
compose/module-field.cue Normal file
View File

@@ -0,0 +1,34 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
moduleField: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "moduleID", "ID"]
operations: {
"recod.value.read": description: "Read field value on records"
"recod.value.update": description: "Update field value on records"
}
}
//locale:
// resource:
// references: [ namespace, module, ID ]
//
// skipSvc: true
// keys:
// - label
// - { name: descriptionView, path: meta.description.view, custom: true, customHandler: descriptionView }
// - { name: descriptionEdit, path: meta.description.edit, custom: true, customHandler: descriptionEdit }
// - { name: hintView, path: meta.hint.view, custom: true, customHandler: hintView }
// - { name: hintEdit, path: meta.hint.edit, custom: true, customHandler: hintEdit }
// - { name: validatorError, path: "expression.validator.{{validatorID}}.error", custom: true, customHandler: validatorError }
// - { name: optionsOptionTexts,
// path: "meta.options.{{value}}.text",
// custom: true,
// customHandler: optionsOptionTexts
// }
}

27
compose/module.cue Normal file
View File

@@ -0,0 +1,27 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
module: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "ID"]
operations: {
"read": {}
"update": {}
"delete": {}
"record.create": description: "Create record"
"records.search": description: "List, search or filter records"
}
}
//locale:
// resource:
// references: [ namespace, ID ]
//
// extended: true
// keys:
// - name
}

29
compose/namespace.cue Normal file
View File

@@ -0,0 +1,29 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
namespace: schema.#resource & {
rbac: {
operations: {
"read": {}
"update": {}
"delete": {}
"manage": description: "Access to namespace admin panel"
"module.create": description: "Create module on namespace"
"modules.search": description: "List, search or filter module on namespace"
"chart.create": description: "Create chart on namespace"
"charts.search": description: "List, search or filter chart on namespace"
"page.create": description: "Create page on namespace"
"pages.search": description: "List, search or filter pages on namespace"
}
}
//
//locale:
// keys:
// - name
// - { path: subtitle, field: "Meta.Subtitle" }
// - { path: description, field: "Meta.Description" }
}

29
compose/page.cue Normal file
View File

@@ -0,0 +1,29 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
page: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "ID"]
operations: {
"read": {}
"update": {}
"delete": {}
}
}
//locale:
// resource:
// references: [ namespace, ID ]
//
// extended: true
// keys:
// - title
// - description
// - { name: blockTitle, path: "pageBlock.{{blockID}}.title", custom: true }
// - { name: blockDescription, path: "pageBlock.{{blockID}}.description", custom: true }
// - { name: blockAutomationButtonlabel, path: "pageBlock.{{blockID}}.button.{{buttonID}}.label", custom: true }
}

17
compose/record.cue Normal file
View File

@@ -0,0 +1,17 @@
package compose
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
record: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "moduleID", "ID"]
operations: {
"read": {}
"update": {}
"delete": {}
}
}
}

View File

@@ -6,15 +6,6 @@ package service
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// - compose.chart.yaml
// - compose.module-field.yaml
// - compose.module.yaml
// - compose.namespace.yaml
// - compose.page.yaml
// - compose.record.yaml
// - compose.yaml
import (
"context"
"fmt"
@@ -63,56 +54,6 @@ func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee
func (svc accessControl) List() (out []map[string]string) {
def := []map[string]string{
{
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "read",
},
{
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "update",
},
{
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "delete",
},
{
"type": types.ModuleFieldResourceType,
"any": types.ModuleFieldRbacResource(0, 0, 0),
"op": "record.value.read",
},
{
"type": types.ModuleFieldResourceType,
"any": types.ModuleFieldRbacResource(0, 0, 0),
"op": "record.value.update",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "read",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "update",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "delete",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "record.create",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "records.search",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
@@ -163,6 +104,56 @@ func (svc accessControl) List() (out []map[string]string) {
"any": types.NamespaceRbacResource(0),
"op": "pages.search",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "read",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "update",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "delete",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "record.create",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
"op": "records.search",
},
{
"type": types.ModuleFieldResourceType,
"any": types.ModuleFieldRbacResource(0, 0, 0),
"op": "recod.value.read",
},
{
"type": types.ModuleFieldResourceType,
"any": types.ModuleFieldRbacResource(0, 0, 0),
"op": "recod.value.update",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"op": "read",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"op": "update",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"op": "delete",
},
{
"type": types.PageResourceType,
"any": types.PageRbacResource(0, 0),
@@ -179,18 +170,18 @@ func (svc accessControl) List() (out []map[string]string) {
"op": "delete",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "read",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "update",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "delete",
},
{
@@ -296,91 +287,21 @@ func (svc accessControl) CloneRulesByRoleID(ctx context.Context, fromRoleID uint
return svc.rbac.CloneRulesByRoleID(ctx, fromRoleID, toRoleID...)
}
// CanReadChart checks if current user can read chart
//
// This function is auto-generated
func (svc accessControl) CanReadChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateChart checks if current user can update chart
//
// This function is auto-generated
func (svc accessControl) CanUpdateChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteChart checks if current user can delete chart
//
// This function is auto-generated
func (svc accessControl) CanDeleteChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "delete", r)
}
// CanReadRecordValue checks if current user can read field value on records
//
// This function is auto-generated
func (svc accessControl) CanReadRecordValue(ctx context.Context, r *types.ModuleField) bool {
return svc.can(ctx, "record.value.read", r)
}
// CanUpdateRecordValue checks if current user can update field value on records
//
// This function is auto-generated
func (svc accessControl) CanUpdateRecordValue(ctx context.Context, r *types.ModuleField) bool {
return svc.can(ctx, "record.value.update", r)
}
// CanReadModule checks if current user can read module
//
// This function is auto-generated
func (svc accessControl) CanReadModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateModule checks if current user can update module
//
// This function is auto-generated
func (svc accessControl) CanUpdateModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteModule checks if current user can delete module
//
// This function is auto-generated
func (svc accessControl) CanDeleteModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "delete", r)
}
// CanCreateRecordOnModule checks if current user can create record
//
// This function is auto-generated
func (svc accessControl) CanCreateRecordOnModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "record.create", r)
}
// CanSearchRecordsOnModule checks if current user can list, search or filter records
//
// This function is auto-generated
func (svc accessControl) CanSearchRecordsOnModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "records.search", r)
}
// CanReadNamespace checks if current user can read namespace
// CanReadNamespace checks if current user can read corteza::compose:namespace
//
// This function is auto-generated
func (svc accessControl) CanReadNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateNamespace checks if current user can update namespace
// CanUpdateNamespace checks if current user can update corteza::compose:namespace
//
// This function is auto-generated
func (svc accessControl) CanUpdateNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteNamespace checks if current user can delete namespace
// CanDeleteNamespace checks if current user can delete corteza::compose:namespace
//
// This function is auto-generated
func (svc accessControl) CanDeleteNamespace(ctx context.Context, r *types.Namespace) bool {
@@ -394,130 +315,206 @@ func (svc accessControl) CanManageNamespace(ctx context.Context, r *types.Namesp
return svc.can(ctx, "manage", r)
}
// CanCreateModuleOnNamespace checks if current user can create module on namespace
// CanCreateModuleNamespace checks if current user can create module on namespace
//
// This function is auto-generated
func (svc accessControl) CanCreateModuleOnNamespace(ctx context.Context, r *types.Namespace) bool {
func (svc accessControl) CanCreateModuleNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "module.create", r)
}
// CanSearchModulesOnNamespace checks if current user can list, search or filter module on namespace
// CanSearchModulesNamespace checks if current user can list, search or filter module on namespace
//
// This function is auto-generated
func (svc accessControl) CanSearchModulesOnNamespace(ctx context.Context, r *types.Namespace) bool {
func (svc accessControl) CanSearchModulesNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "modules.search", r)
}
// CanCreateChartOnNamespace checks if current user can create chart on namespace
// CanCreateChartNamespace checks if current user can create chart on namespace
//
// This function is auto-generated
func (svc accessControl) CanCreateChartOnNamespace(ctx context.Context, r *types.Namespace) bool {
func (svc accessControl) CanCreateChartNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "chart.create", r)
}
// CanSearchChartsOnNamespace checks if current user can list, search or filter chart on namespace
// CanSearchChartsNamespace checks if current user can list, search or filter chart on namespace
//
// This function is auto-generated
func (svc accessControl) CanSearchChartsOnNamespace(ctx context.Context, r *types.Namespace) bool {
func (svc accessControl) CanSearchChartsNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "charts.search", r)
}
// CanCreatePageOnNamespace checks if current user can create page on namespace
// CanCreatePageNamespace checks if current user can create page on namespace
//
// This function is auto-generated
func (svc accessControl) CanCreatePageOnNamespace(ctx context.Context, r *types.Namespace) bool {
func (svc accessControl) CanCreatePageNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "page.create", r)
}
// CanSearchPagesOnNamespace checks if current user can list, search or filter pages on namespace
// CanSearchPagesNamespace checks if current user can list, search or filter pages on namespace
//
// This function is auto-generated
func (svc accessControl) CanSearchPagesOnNamespace(ctx context.Context, r *types.Namespace) bool {
func (svc accessControl) CanSearchPagesNamespace(ctx context.Context, r *types.Namespace) bool {
return svc.can(ctx, "pages.search", r)
}
// CanReadPage checks if current user can read page
// CanReadModule checks if current user can read corteza::compose:module
//
// This function is auto-generated
func (svc accessControl) CanReadPage(ctx context.Context, r *types.Page) bool {
func (svc accessControl) CanReadModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "read", r)
}
// CanUpdatePage checks if current user can update page
// CanUpdateModule checks if current user can update corteza::compose:module
//
// This function is auto-generated
func (svc accessControl) CanUpdatePage(ctx context.Context, r *types.Page) bool {
func (svc accessControl) CanUpdateModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "update", r)
}
// CanDeletePage checks if current user can delete page
// CanDeleteModule checks if current user can delete corteza::compose:module
//
// This function is auto-generated
func (svc accessControl) CanDeletePage(ctx context.Context, r *types.Page) bool {
func (svc accessControl) CanDeleteModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "delete", r)
}
// CanReadRecord checks if current user can read record
// CanCreateRecordModule checks if current user can create record
//
// This function is auto-generated
func (svc accessControl) CanCreateRecordModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "record.create", r)
}
// CanSearchRecordsModule checks if current user can list, search or filter records
//
// This function is auto-generated
func (svc accessControl) CanSearchRecordsModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "records.search", r)
}
// CanReadRecodValueModuleField checks if current user can read field value on records
//
// This function is auto-generated
func (svc accessControl) CanReadRecodValueModuleField(ctx context.Context, r *types.ModuleField) bool {
return svc.can(ctx, "recod.value.read", r)
}
// CanUpdateRecodValueModuleField checks if current user can update field value on records
//
// This function is auto-generated
func (svc accessControl) CanUpdateRecodValueModuleField(ctx context.Context, r *types.ModuleField) bool {
return svc.can(ctx, "recod.value.update", r)
}
// CanReadRecord checks if current user can read corteza::compose:record
//
// This function is auto-generated
func (svc accessControl) CanReadRecord(ctx context.Context, r *types.Record) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateRecord checks if current user can update record
// CanUpdateRecord checks if current user can update corteza::compose:record
//
// This function is auto-generated
func (svc accessControl) CanUpdateRecord(ctx context.Context, r *types.Record) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteRecord checks if current user can delete record
// CanDeleteRecord checks if current user can delete corteza::compose:record
//
// This function is auto-generated
func (svc accessControl) CanDeleteRecord(ctx context.Context, r *types.Record) bool {
return svc.can(ctx, "delete", r)
}
// CanReadPage checks if current user can read corteza::compose:page
//
// This function is auto-generated
func (svc accessControl) CanReadPage(ctx context.Context, r *types.Page) bool {
return svc.can(ctx, "read", r)
}
// CanUpdatePage checks if current user can update corteza::compose:page
//
// This function is auto-generated
func (svc accessControl) CanUpdatePage(ctx context.Context, r *types.Page) bool {
return svc.can(ctx, "update", r)
}
// CanDeletePage checks if current user can delete corteza::compose:page
//
// This function is auto-generated
func (svc accessControl) CanDeletePage(ctx context.Context, r *types.Page) bool {
return svc.can(ctx, "delete", r)
}
// CanReadChart checks if current user can read corteza::compose:chart
//
// This function is auto-generated
func (svc accessControl) CanReadChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateChart checks if current user can update corteza::compose:chart
//
// This function is auto-generated
func (svc accessControl) CanUpdateChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteChart checks if current user can delete corteza::compose:chart
//
// This function is auto-generated
func (svc accessControl) CanDeleteChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "delete", r)
}
// CanGrant checks if current user can manage compose permissions
//
// This function is auto-generated
func (svc accessControl) CanGrant(ctx context.Context) bool {
return svc.can(ctx, "grant", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "grant", r)
}
// CanReadSettings checks if current user can read settings
//
// This function is auto-generated
func (svc accessControl) CanReadSettings(ctx context.Context) bool {
return svc.can(ctx, "settings.read", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "settings.read", r)
}
// CanManageSettings checks if current user can manage settings
//
// This function is auto-generated
func (svc accessControl) CanManageSettings(ctx context.Context) bool {
return svc.can(ctx, "settings.manage", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "settings.manage", r)
}
// CanCreateNamespace checks if current user can create namespace
//
// This function is auto-generated
func (svc accessControl) CanCreateNamespace(ctx context.Context) bool {
return svc.can(ctx, "namespace.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "namespace.create", r)
}
// CanSearchNamespaces checks if current user can list, search or filter namespaces
//
// This function is auto-generated
func (svc accessControl) CanSearchNamespaces(ctx context.Context) bool {
return svc.can(ctx, "namespaces.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "namespaces.search", r)
}
// CanManageResourceTranslations checks if current user can list, search, create, or update resource translations
//
// This function is auto-generated
func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool {
return svc.can(ctx, "resource-translations.manage", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "resource-translations.manage", r)
}
// rbacResourceValidator validates known component's resource by routing it to the appropriate validator
@@ -525,18 +522,18 @@ func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool
// This function is auto-generated
func rbacResourceValidator(r string, oo ...string) error {
switch rbac.ResourceType(r) {
case types.ChartResourceType:
return rbacChartResourceValidator(r, oo...)
case types.ModuleFieldResourceType:
return rbacModuleFieldResourceValidator(r, oo...)
case types.ModuleResourceType:
return rbacModuleResourceValidator(r, oo...)
case types.NamespaceResourceType:
return rbacNamespaceResourceValidator(r, oo...)
case types.PageResourceType:
return rbacPageResourceValidator(r, oo...)
case types.ModuleResourceType:
return rbacModuleResourceValidator(r, oo...)
case types.ModuleFieldResourceType:
return rbacModuleFieldResourceValidator(r, oo...)
case types.RecordResourceType:
return rbacRecordResourceValidator(r, oo...)
case types.PageResourceType:
return rbacPageResourceValidator(r, oo...)
case types.ChartResourceType:
return rbacChartResourceValidator(r, oo...)
case types.ComponentResourceType:
return rbacComponentResourceValidator(r, oo...)
}
@@ -549,25 +546,6 @@ func rbacResourceValidator(r string, oo ...string) error {
// This function is auto-generated
func rbacResourceOperations(r string) map[string]bool {
switch rbac.ResourceType(r) {
case types.ChartResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
}
case types.ModuleFieldResourceType:
return map[string]bool{
"record.value.read": true,
"record.value.update": true,
}
case types.ModuleResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
"record.create": true,
"records.search": true,
}
case types.NamespaceResourceType:
return map[string]bool{
"read": true,
@@ -581,13 +559,32 @@ func rbacResourceOperations(r string) map[string]bool {
"page.create": true,
"pages.search": true,
}
case types.ModuleResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
"record.create": true,
"records.search": true,
}
case types.ModuleFieldResourceType:
return map[string]bool{
"recod.value.read": true,
"recod.value.update": true,
}
case types.RecordResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
}
case types.PageResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
}
case types.RecordResourceType:
case types.ChartResourceType:
return map[string]bool{
"read": true,
"update": true,
@@ -607,27 +604,71 @@ func rbacResourceOperations(r string) map[string]bool {
return nil
}
// rbacChartResourceValidator checks validity of rbac resource and operations
// rbacNamespaceResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacChartResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose Chart resource", o)
}
}
if !strings.HasPrefix(r, types.ChartResourceType) {
func rbacNamespaceResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.NamespaceResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for namespace resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ChartResourceType):], sep), sep)
pp = strings.Split(strings.Trim(r[len(types.NamespaceResourceType):], sep), sep)
prc = []string{
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for namespace resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacModuleResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacModuleResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.ModuleResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for module resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ModuleResourceType):], sep), sep)
prc = []string{
"namespaceID",
"ID",
@@ -641,7 +682,7 @@ func rbacChartResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Chart", i)
return fmt.Errorf("invalid path wildcard level (%d) for module resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -652,24 +693,24 @@ func rbacChartResourceValidator(r string, oo ...string) error {
return nil
}
// rbacModuleFieldResourceValidator checks validity of rbac resource and operations
// rbacModuleFieldResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacModuleFieldResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose ModuleField resource", o)
}
}
if !strings.HasPrefix(r, types.ModuleFieldResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for moduleField resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ModuleFieldResourceType):], sep), sep)
@@ -687,7 +728,7 @@ func rbacModuleFieldResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for ModuleField", i)
return fmt.Errorf("invalid path wildcard level (%d) for moduleField resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -698,158 +739,24 @@ func rbacModuleFieldResourceValidator(r string, oo ...string) error {
return nil
}
// rbacModuleResourceValidator checks validity of rbac resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacModuleResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose Module resource", o)
}
}
if !strings.HasPrefix(r, types.ModuleResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ModuleResourceType):], sep), sep)
prc = []string{
"namespaceID",
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Module", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacNamespaceResourceValidator checks validity of rbac resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacNamespaceResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose Namespace resource", o)
}
}
if !strings.HasPrefix(r, types.NamespaceResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.NamespaceResourceType):], sep), sep)
prc = []string{
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Namespace", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacPageResourceValidator checks validity of rbac resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacPageResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose Page resource", o)
}
}
if !strings.HasPrefix(r, types.PageResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.PageResourceType):], sep), sep)
prc = []string{
"namespaceID",
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Page", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacRecordResourceValidator checks validity of rbac resource and operations
// rbacRecordResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacRecordResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose Record resource", o)
}
}
if !strings.HasPrefix(r, types.RecordResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for record resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.RecordResourceType):], sep), sep)
@@ -867,7 +774,7 @@ func rbacRecordResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Record", i)
return fmt.Errorf("invalid path wildcard level (%d) for record resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -878,23 +785,113 @@ func rbacRecordResourceValidator(r string, oo ...string) error {
return nil
}
// rbacComponentResourceValidator checks validity of rbac resource and operations
// rbacPageResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacPageResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.PageResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for page resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.PageResourceType):], sep), sep)
prc = []string{
"namespaceID",
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for page resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacChartResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacChartResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.ChartResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for chart resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ChartResourceType):], sep), sep)
prc = []string{
"namespaceID",
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for chart resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacComponentResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacComponentResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose resource", o)
}
}
if !strings.HasPrefix(r, types.ComponentResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for compose component resource", o)
}
}
return nil
}

View File

@@ -6,15 +6,6 @@ package types
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// - compose.chart.yaml
// - compose.module-field.yaml
// - compose.module.yaml
// - compose.namespace.yaml
// - compose.page.yaml
// - compose.record.yaml
// - compose.yaml
import (
"fmt"
"strconv"
@@ -27,50 +18,84 @@ type (
Component struct{}
)
var (
_ = fmt.Printf
_ = strconv.FormatUint
)
const (
ChartResourceType = "corteza::compose:chart"
ModuleFieldResourceType = "corteza::compose:module-field"
ModuleResourceType = "corteza::compose:module"
NamespaceResourceType = "corteza::compose:namespace"
PageResourceType = "corteza::compose:page"
ModuleResourceType = "corteza::compose:module"
ModuleFieldResourceType = "corteza::compose:module-field"
RecordResourceType = "corteza::compose:record"
PageResourceType = "corteza::compose:page"
ChartResourceType = "corteza::compose:chart"
ComponentResourceType = "corteza::compose"
)
// RbacResource returns string representation of RBAC resource for Chart by calling ChartRbacResource fn
// RbacResource returns string representation of RBAC resource for Namespace by calling NamespaceRbacResource fn
//
// RBAC resource is in the corteza::compose:chart/... format
// RBAC resource is in the corteza::compose:namespace/... format
//
// This function is auto-generated
func (r Chart) RbacResource() string {
return ChartRbacResource(r.NamespaceID, r.ID)
func (r Namespace) RbacResource() string {
return NamespaceRbacResource(r.ID)
}
// ChartRbacResource returns string representation of RBAC resource for Chart
// NamespaceRbacResource returns string representation of RBAC resource for Namespace
//
// RBAC resource is in the corteza::compose:chart/... format
// RBAC resource is in the corteza::compose:namespace/... format
//
// This function is auto-generated
func ChartRbacResource(namespaceID uint64, id uint64) string {
cpts := []interface{}{ChartResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
func NamespaceRbacResource(ID uint64) string {
cpts := []interface{}{NamespaceResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
return fmt.Sprintf(NamespaceRbacResourceTpl(), cpts...)
}
func NamespaceRbacResourceTpl() string {
return "%s/%s"
}
// RbacResource returns string representation of RBAC resource for Module by calling ModuleRbacResource fn
//
// RBAC resource is in the corteza::compose:module/... format
//
// This function is auto-generated
func (r Module) RbacResource() string {
return ModuleRbacResource(r.NamespaceID, r.ID)
}
// ModuleRbacResource returns string representation of RBAC resource for Module
//
// RBAC resource is in the corteza::compose:module/... format
//
// This function is auto-generated
func ModuleRbacResource(NamespaceID uint64, ID uint64) string {
cpts := []interface{}{ModuleResourceType}
if NamespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(NamespaceID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ChartRbacResourceTpl(), cpts...)
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ModuleRbacResourceTpl(), cpts...)
}
// @todo template
func ChartRbacResourceTpl() string {
func ModuleRbacResourceTpl() string {
return "%s/%s/%s"
}
@@ -88,22 +113,22 @@ func (r ModuleField) RbacResource() string {
// RBAC resource is in the corteza::compose:module-field/... format
//
// This function is auto-generated
func ModuleFieldRbacResource(namespaceID uint64, moduleID uint64, id uint64) string {
func ModuleFieldRbacResource(NamespaceID uint64, ModuleID uint64, ID uint64) string {
cpts := []interface{}{ModuleFieldResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
if NamespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(NamespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if moduleID != 0 {
cpts = append(cpts, strconv.FormatUint(moduleID, 10))
if ModuleID != 0 {
cpts = append(cpts, strconv.FormatUint(ModuleID, 10))
} else {
cpts = append(cpts, "*")
}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -112,116 +137,10 @@ func ModuleFieldRbacResource(namespaceID uint64, moduleID uint64, id uint64) str
}
// @todo template
func ModuleFieldRbacResourceTpl() string {
return "%s/%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Module by calling ModuleRbacResource fn
//
// RBAC resource is in the corteza::compose:module/... format
//
// This function is auto-generated
func (r Module) RbacResource() string {
return ModuleRbacResource(r.NamespaceID, r.ID)
}
// ModuleRbacResource returns string representation of RBAC resource for Module
//
// RBAC resource is in the corteza::compose:module/... format
//
// This function is auto-generated
func ModuleRbacResource(namespaceID uint64, id uint64) string {
cpts := []interface{}{ModuleResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ModuleRbacResourceTpl(), cpts...)
}
// @todo template
func ModuleRbacResourceTpl() string {
return "%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Namespace by calling NamespaceRbacResource fn
//
// RBAC resource is in the corteza::compose:namespace/... format
//
// This function is auto-generated
func (r Namespace) RbacResource() string {
return NamespaceRbacResource(r.ID)
}
// NamespaceRbacResource returns string representation of RBAC resource for Namespace
//
// RBAC resource is in the corteza::compose:namespace/... format
//
// This function is auto-generated
func NamespaceRbacResource(id uint64) string {
cpts := []interface{}{NamespaceResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(NamespaceRbacResourceTpl(), cpts...)
}
// @todo template
func NamespaceRbacResourceTpl() string {
return "%s/%s"
}
// RbacResource returns string representation of RBAC resource for Page by calling PageRbacResource fn
//
// RBAC resource is in the corteza::compose:page/... format
//
// This function is auto-generated
func (r Page) RbacResource() string {
return PageRbacResource(r.NamespaceID, r.ID)
}
// PageRbacResource returns string representation of RBAC resource for Page
//
// RBAC resource is in the corteza::compose:page/... format
//
// This function is auto-generated
func PageRbacResource(namespaceID uint64, id uint64) string {
cpts := []interface{}{PageResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(PageRbacResourceTpl(), cpts...)
}
// @todo template
func PageRbacResourceTpl() string {
return "%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Record by calling RecordRbacResource fn
//
// RBAC resource is in the corteza::compose:record/... format
@@ -236,22 +155,22 @@ func (r Record) RbacResource() string {
// RBAC resource is in the corteza::compose:record/... format
//
// This function is auto-generated
func RecordRbacResource(namespaceID uint64, moduleID uint64, id uint64) string {
func RecordRbacResource(NamespaceID uint64, ModuleID uint64, ID uint64) string {
cpts := []interface{}{RecordResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
if NamespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(NamespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if moduleID != 0 {
cpts = append(cpts, strconv.FormatUint(moduleID, 10))
if ModuleID != 0 {
cpts = append(cpts, strconv.FormatUint(ModuleID, 10))
} else {
cpts = append(cpts, "*")
}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -260,11 +179,82 @@ func RecordRbacResource(namespaceID uint64, moduleID uint64, id uint64) string {
}
// @todo template
func RecordRbacResourceTpl() string {
return "%s/%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Page by calling PageRbacResource fn
//
// RBAC resource is in the corteza::compose:page/... format
//
// This function is auto-generated
func (r Page) RbacResource() string {
return PageRbacResource(r.NamespaceID, r.ID)
}
// PageRbacResource returns string representation of RBAC resource for Page
//
// RBAC resource is in the corteza::compose:page/... format
//
// This function is auto-generated
func PageRbacResource(NamespaceID uint64, ID uint64) string {
cpts := []interface{}{PageResourceType}
if NamespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(NamespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(PageRbacResourceTpl(), cpts...)
}
func PageRbacResourceTpl() string {
return "%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Chart by calling ChartRbacResource fn
//
// RBAC resource is in the corteza::compose:chart/... format
//
// This function is auto-generated
func (r Chart) RbacResource() string {
return ChartRbacResource(r.NamespaceID, r.ID)
}
// ChartRbacResource returns string representation of RBAC resource for Chart
//
// RBAC resource is in the corteza::compose:chart/... format
//
// This function is auto-generated
func ChartRbacResource(NamespaceID uint64, ID uint64) string {
cpts := []interface{}{ChartResourceType}
if NamespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(NamespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ChartRbacResourceTpl(), cpts...)
}
func ChartRbacResourceTpl() string {
return "%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Component by calling ComponentRbacResource fn
//
// RBAC resource is in the corteza::compose/... format
@@ -284,7 +274,6 @@ func ComponentRbacResource() string {
}
// @todo template
func ComponentRbacResourceTpl() string {
return "%s"
}

1
cue.mod/module.cue Normal file
View File

@@ -0,0 +1 @@
module: "github.com/cortezaproject/corteza-server"

3
cue.mods Normal file
View File

@@ -0,0 +1,3 @@
module github.com/cortezaproject/corteza-server
cue v0.4.0

0
cue.sums Normal file
View File

27
def/schema/component.cue Normal file
View File

@@ -0,0 +1,27 @@
package schema
import (
"strings"
)
#component: {
ident: #baseHandle
expIdent: #expIdent | *strings.ToTitle(ident)
label: strings.ToTitle(ident)
platform: #baseHandle
resources: {
[key=_]: {handle: key, "component": ident, "platform": platform} & #resource
}
// All known RBAC operations for this component
rbac: #rbacComponent & {
resource: type: platform + "::" + ident
operations: {
grant: {
description: "Manage \(ident) permissions"
}
}
}
}

29
def/schema/locale.cue Normal file
View File

@@ -0,0 +1,29 @@
package schema
import (
// "strings"
)
#locale: {
// @todo we need a better name here!
skipSvc: bool | *false
resource: {
// @todo merge with RBAC res-ref and move 2 levels lower.
references: [ ...string] | *["ID"]
}
keys: {
[key=_]: #localeKey & {
name: key
}
}
}
#localeKey: {
name: #handle
path: string | *(name)
custom?: true
customHandler?: string
}

17
def/schema/platform.cue Normal file
View File

@@ -0,0 +1,17 @@
package schema
#platform: {
ident: #baseHandle
components: [...{platform: ident} & #component]
// env-var definitions
// options: {}
//
// automation: {
// types: ....
// function ....
// }
}

61
def/schema/rbac.cue Normal file
View File

@@ -0,0 +1,61 @@
package schema
import (
"strings"
)
#rbacComponent: {
resource: {
type: string
}
operations: {
[key=_]: #rbacOperation & {handle: key}
}
}
#rbacResource: {
resource: {
type: string
expIdent: #expIdent
references: [ ...string] | *["ID"]
}
operations: {
[key=_]: #rbacOperation & {
handle: key
resourceExpIdent: resource.expIdent
description: string | *(strings.ToTitle(key) + " " + resource.type)
}
}
}
#rbacOperation: {
handle: #handle
description: string
resourceExpIdent?: string
_isComponent: resourceExpIdent == _|_
// Some string manipulation that will result in
// more pronouncable access-control check function name
// When check function name is not explicitly defined we try
// to use resource and operation name and generate easy-to-read name
//
// <res> + <op> => Can<Op><Res>
// <res> + <op:foo.bar.verb> => Can<Verb><Foo><Bar>On<Res>
_operation: strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1)
_opSplit: strings.Split(_operation, ".")
_opFlip: [_opSplit[len(_opSplit)-1]] + _opSplit[0:len(_opSplit)-1]
_opFinal: strings.Replace(strings.ToTitle(strings.Join(_opFlip, " ")), " ", "", -1)
if _isComponent {
checkFuncName: #expIdent | *("Can" + _opFinal)
}
if !_isComponent {
checkFuncName: #expIdent | *("Can" + _opFinal + resourceExpIdent)
}
}

93
def/schema/resource.cue Normal file
View File

@@ -0,0 +1,93 @@
package schema
import (
"strings"
)
#resource: {
handle: #baseHandle | *"unknown-resource"
_words: strings.Replace(strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1), ".", " ", -1)
ident: #ident | *strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
expIdent: #expIdent | *strings.Replace(strings.ToTitle(_words), " ", "", -1)
platform: #baseHandle | *"unknown-platform"
component: string | *"unknown-component"
// Fully qualified resource name
fqrn: string | *(platform + "::" + component + ":" + handle)
goType: string | *("types." + expIdent)
// fields: #Fields
// operations: #Operations
// All known RBAC operations for this resource
rbac: #rbacResource & {
resource: {
type: fqrn
"expIdent": expIdent
}
}
// List of known keys for resource translation
// locale?: {
// [Name=_]: {
// name: Name & #Handle
// path: string
// custom: bool | *false
// }
// }
}
#fields: {
// Each field can be
[key=_]: #fields | *({name: key} & #field)
}
#field: {
name: #expIdent
unique: bool | *false
// Golang type (built-in or other)
type: string | *"string"
// System fields,
system: bool | *false
if name =~ "At$" {
type: string | *"*time.Time"
}
}
//#Operations: {
// [Operation=_]: {operation: Operation} & #Operation
//}
//#Operation: {
// name: #ExpIdent
// description: string
// can: string | false | *"\(name)"
//}
idField: {
// Expecting ID field to allways have name ID
name: "ID"
unique: true
// Service fields,
// @todo We might want to have a better name for this
// service: true
// @todo someday we'll replace this with the "ID" type
type: "uint64"
}
handleField: {
// Expecting ID field to allways have name ID
name: "handle"
unique: true
// @todo someday we'll replace this with the "ID" type
type: "string" & #handle
}

14
def/schema/shared.cue Normal file
View File

@@ -0,0 +1,14 @@
package schema
// Resource definition identifier
#ident: =~"^[a-z][a-zA-Z0-9_]*$"
// Exported identifier
#expIdent: =~"^[A-Z][a-zA-Z0-9]*$"
// More liberal then identifier, allows underscores and dots
#handle: =~"^[A-Za-z][a-zA-Z0-9_\\-\\.]*[a-zA-Z0-9]+$"
// More liberal then identifier, allows underscores and dots
#baseHandle: =~"^[a-z][a-z0-9-]*[a-z0-9]+$"

View File

@@ -16,3 +16,4 @@ rbac:
description: Unmask name
impersonate:
description: Impersonate user

View File

@@ -1,99 +0,0 @@
package {{ .Package }}
{{ template "header-gentext.tpl" }}
{{ template "header-definitions.tpl" . }}
import (
"fmt"
"strconv"
)
type (
// Component struct serves as a virtual resource type for the {{ .Component }} component
//
// This struct is auto-generated
Component struct {}
)
const (
{{- range .Def }}
{{ coalesce .Resource "Component" }}ResourceType = "{{ .RBAC.ResourceType }}"
{{- end }}
)
{{- range .Def }}
{{ $Resource := .Resource }}
{{ $GoType := printf "types.%s" .Resource }}
// RbacResource returns string representation of RBAC resource for {{ .Resource }} by calling {{ .Resource }}RbacResource fn
//
// RBAC resource is in the {{ .RBAC.ResourceType }}/... format
//
// This function is auto-generated
func (r {{ .Resource }}) RbacResource() string {
return {{ .Resource }}RbacResource({{ if .RBAC.Resource }}{{ range .RBAC.Resource.References }}r.{{ export .Field }},{{ end }}{{ end }})
}
// {{ .Resource }}RbacResource returns string representation of RBAC resource for {{ .Resource }}
//
// RBAC resource is in the {{ .RBAC.ResourceType }}/{{- if .RBAC.Resource.References }}...{{ end }} format
//
// This function is auto-generated
func {{ .Resource }}RbacResource({{ if .RBAC.Resource }}{{ range .RBAC.Resource.References }}{{ unexport .Field }} uint64,{{ end }}{{ end }}) string {
{{- if .RBAC.Resource.References }}
cpts := []interface{{"{}"}}{{"{"}}{{ .Resource }}ResourceType{{"}"}}
{{- range .RBAC.Resource.References }}
if {{ unexport .Field }} != 0 {
cpts = append(cpts, strconv.FormatUint({{ unexport .Field }}, 10))
} else {
cpts = append(cpts, "*")
}
{{ end }}
return fmt.Sprintf({{ .Resource }}RbacResourceTpl(), cpts...)
{{- else }}
return {{ .Resource }}ResourceType + "/"
{{- end }}
}
// @todo template
func {{ .Resource }}RbacResourceTpl() string {
{{- if .RBAC.Resource.References }}
return "%s
{{- range .RBAC.Resource.References }}/%s{{- end }}"
{{- else }}
return "%s"
{{- end }}
}
{{ if .RBAC.Resource.Attributes }}
// RbacAttributes returns resource attributes used for generating list of contextual roles
//
// This function is auto-generated
func (r {{ .Resource }}) RbacAttributes() map[string]interface{} {
return {{ unexport .Resource }}RbacAttributes(r)
}
{{ if .RBAC.Resource.Attributes.Fields }}
// {{ .Resource }}RbacResource returns string representation of RBAC resource for {{ .Resource }}
//
// RBAC resource is in the {{ .RBAC.ResourceType }}/... format
//
// This function is auto-generated
func {{ unexport .Resource }}RbacAttributes(r {{ .Resource }}) map[string]interface{} {
return map[string]interface{}{
{{- range .RBAC.Resource.Attributes.Fields }}
{{ printf "%q" . }}: r.{{ export . }},
{{- end }}
}
}
{{- end }}
{{- end }}
{{- end }}

15
system/apigw-route.cue Normal file
View File

@@ -0,0 +1,15 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
apigwRoute: schema.#resource & {
rbac: {
operations: {
read: description: "Read API Gateway route"
update: description: "Update API Gateway route"
delete: description: "Delete API Gateway route"
}
}
}

18
system/application.cue Normal file
View File

@@ -0,0 +1,18 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
application: schema.#resource & {
rbac: {
operations: {
read:
description: "Read application"
update:
description: "Update application"
delete:
description: "Delete application"
}
}
}

16
system/auth-client.cue Normal file
View File

@@ -0,0 +1,16 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
authClient: schema.#resource & {
rbac: {
operations: {
read: description: "Read authorization client"
update: description: "Update authorization client"
delete: description: "Delete authorization client"
authorize: description: "Authorize authorization client"
}
}
}

56
system/component.cue Normal file
View File

@@ -0,0 +1,56 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
component: schema.#component & {
ident: "system"
resources: {
"apigw-route": apigwRoute
"application": application
"auth-client": authClient
"queue": queue
"report": report
"role": role
"template": template
"user": user
}
rbac: operations: {
"action-log.read": description: "Access to action log"
"settings.read": description: "Read system settings"
"settings.manage": description: "Manage system settings"
"auth-client.create": description: "Create auth clients"
"auth-clients.search": description: "List, search or filter auth clients"
"role.create": description: "Create roles"
"roles.search": description: "List, search or filter roles"
"user.create": description: "Create users"
"users.search": description: "List, search or filter users"
"application.create": description: "Create applications"
"applications.search": description: "List, search or filter auth clients"
"application.flag.self": description: "Manage private flags for applications"
"application.flag.global": description: "Manage global flags for applications"
"template.create": description: "Create template"
"templates.search": description: "List, search or filter templates"
"report.create": description: "Create report"
"reports.search": description: "List, search or filter reports"
"reminder.assign": description: " Assign reminders"
"queue.create": description: "Create messagebus queues"
"queues.search": description: "List, search or filter messagebus queues"
"apigw-route.create": description: "Create API gateway route"
"apigw-routes.search": description: "List search or filter API gateway routes"
"resource-translations.manage": description: "List, search, create, or update resource translations"
}
}

18
system/queue.cue Normal file
View File

@@ -0,0 +1,18 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
queue: schema.#resource & {
rbac: {
operations: {
"render": description: "Render template"
"read": description: "Read queue"
"update": description: "Update queue"
"delete": description: "Delete queue"
"queue.read": description: "Read from queue"
"queue.write": description: "Write to queue"
}
}
}

23
system/report.cue Normal file
View File

@@ -0,0 +1,23 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
report: schema.#resource & {
rbac: {
operations: {
read: description: "Read report"
update: description: "Update report"
delete: description: "Delete report"
run: description: "Run report"
}
}
// locale:
// extended: true
// keys:
// - { path: name, field: "Meta.Name" }
// - { path: description, field: "Meta.Description" }
// - { name: block title, path: "block.{{blockID}}.title", custom: true }
// - { name: block description, path: "block.{{blockID}}.description", custom: true }
}

14
system/role.cue Normal file
View File

@@ -0,0 +1,14 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
role: schema.#resource & {
rbac: {
operations: {
read: description: "Read role"
update: description: "Update role"
delete: description: "Delete role"
"members.manage": description: "Manage members"
}}}

View File

@@ -6,17 +6,6 @@ package service
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// - system.apigw-route.yaml
// - system.application.yaml
// - system.auth-client.yaml
// - system.queue.yaml
// - system.report.yaml
// - system.role.yaml
// - system.template.yaml
// - system.user.yaml
// - system.yaml
import (
"context"
"fmt"
@@ -115,6 +104,11 @@ func (svc accessControl) List() (out []map[string]string) {
"any": types.AuthClientRbacResource(0),
"op": "authorize",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"op": "render",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
@@ -503,6 +497,13 @@ func (svc accessControl) CanAuthorizeAuthClient(ctx context.Context, r *types.Au
return svc.can(ctx, "authorize", r)
}
// CanRenderQueue checks if current user can render template
//
// This function is auto-generated
func (svc accessControl) CanRenderQueue(ctx context.Context, r *types.Queue) bool {
return svc.can(ctx, "render", r)
}
// CanReadQueue checks if current user can read queue
//
// This function is auto-generated
@@ -524,17 +525,17 @@ func (svc accessControl) CanDeleteQueue(ctx context.Context, r *types.Queue) boo
return svc.can(ctx, "delete", r)
}
// CanReadQueueOnQueue checks if current user can read from queue
// CanReadQueueQueue checks if current user can read from queue
//
// This function is auto-generated
func (svc accessControl) CanReadQueueOnQueue(ctx context.Context, r *types.Queue) bool {
func (svc accessControl) CanReadQueueQueue(ctx context.Context, r *types.Queue) bool {
return svc.can(ctx, "queue.read", r)
}
// CanWriteQueueOnQueue checks if current user can write to queue
// CanWriteQueueQueue checks if current user can write to queue
//
// This function is auto-generated
func (svc accessControl) CanWriteQueueOnQueue(ctx context.Context, r *types.Queue) bool {
func (svc accessControl) CanWriteQueueQueue(ctx context.Context, r *types.Queue) bool {
return svc.can(ctx, "queue.write", r)
}
@@ -587,10 +588,10 @@ func (svc accessControl) CanDeleteRole(ctx context.Context, r *types.Role) bool
return svc.can(ctx, "delete", r)
}
// CanManageMembersOnRole checks if current user can manage members
// CanManageMembersRole checks if current user can manage members
//
// This function is auto-generated
func (svc accessControl) CanManageMembersOnRole(ctx context.Context, r *types.Role) bool {
func (svc accessControl) CanManageMembersRole(ctx context.Context, r *types.Role) bool {
return svc.can(ctx, "members.manage", r)
}
@@ -643,7 +644,7 @@ func (svc accessControl) CanDeleteUser(ctx context.Context, r *types.User) bool
return svc.can(ctx, "delete", r)
}
// CanSuspendUser checks if current user can suspemd user
// CanSuspendUser checks if current user can suspend user
//
// This function is auto-generated
func (svc accessControl) CanSuspendUser(ctx context.Context, r *types.User) bool {
@@ -657,17 +658,17 @@ func (svc accessControl) CanUnsuspendUser(ctx context.Context, r *types.User) bo
return svc.can(ctx, "unsuspend", r)
}
// CanUnmaskEmailOnUser checks if current user can unmask email
// CanUnmaskEmailUser checks if current user can unmask email
//
// This function is auto-generated
func (svc accessControl) CanUnmaskEmailOnUser(ctx context.Context, r *types.User) bool {
func (svc accessControl) CanUnmaskEmailUser(ctx context.Context, r *types.User) bool {
return svc.can(ctx, "email.unmask", r)
}
// CanUnmaskNameOnUser checks if current user can unmask name
// CanUnmaskNameUser checks if current user can unmask name
//
// This function is auto-generated
func (svc accessControl) CanUnmaskNameOnUser(ctx context.Context, r *types.User) bool {
func (svc accessControl) CanUnmaskNameUser(ctx context.Context, r *types.User) bool {
return svc.can(ctx, "name.unmask", r)
}
@@ -682,168 +683,192 @@ func (svc accessControl) CanImpersonateUser(ctx context.Context, r *types.User)
//
// This function is auto-generated
func (svc accessControl) CanGrant(ctx context.Context) bool {
return svc.can(ctx, "grant", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "grant", r)
}
// CanReadActionLog checks if current user can access to action log
//
// This function is auto-generated
func (svc accessControl) CanReadActionLog(ctx context.Context) bool {
return svc.can(ctx, "action-log.read", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "action-log.read", r)
}
// CanReadSettings checks if current user can read system settings
//
// This function is auto-generated
func (svc accessControl) CanReadSettings(ctx context.Context) bool {
return svc.can(ctx, "settings.read", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "settings.read", r)
}
// CanManageSettings checks if current user can manage system settings
//
// This function is auto-generated
func (svc accessControl) CanManageSettings(ctx context.Context) bool {
return svc.can(ctx, "settings.manage", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "settings.manage", r)
}
// CanCreateAuthClient checks if current user can create auth clients
//
// This function is auto-generated
func (svc accessControl) CanCreateAuthClient(ctx context.Context) bool {
return svc.can(ctx, "auth-client.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "auth-client.create", r)
}
// CanSearchAuthClients checks if current user can list, search or filter auth clients
//
// This function is auto-generated
func (svc accessControl) CanSearchAuthClients(ctx context.Context) bool {
return svc.can(ctx, "auth-clients.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "auth-clients.search", r)
}
// CanCreateRole checks if current user can create roles
//
// This function is auto-generated
func (svc accessControl) CanCreateRole(ctx context.Context) bool {
return svc.can(ctx, "role.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "role.create", r)
}
// CanSearchRoles checks if current user can list, search or filter roles
//
// This function is auto-generated
func (svc accessControl) CanSearchRoles(ctx context.Context) bool {
return svc.can(ctx, "roles.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "roles.search", r)
}
// CanCreateUser checks if current user can create users
//
// This function is auto-generated
func (svc accessControl) CanCreateUser(ctx context.Context) bool {
return svc.can(ctx, "user.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "user.create", r)
}
// CanSearchUsers checks if current user can list, search or filter users
//
// This function is auto-generated
func (svc accessControl) CanSearchUsers(ctx context.Context) bool {
return svc.can(ctx, "users.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "users.search", r)
}
// CanCreateApplication checks if current user can create applications
//
// This function is auto-generated
func (svc accessControl) CanCreateApplication(ctx context.Context) bool {
return svc.can(ctx, "application.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "application.create", r)
}
// CanSearchApplications checks if current user can list, search or filter auth clients
//
// This function is auto-generated
func (svc accessControl) CanSearchApplications(ctx context.Context) bool {
return svc.can(ctx, "applications.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "applications.search", r)
}
// CanSelfApplicationFlag checks if current user can manage private flags for applications
//
// This function is auto-generated
func (svc accessControl) CanSelfApplicationFlag(ctx context.Context) bool {
return svc.can(ctx, "application.flag.self", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "application.flag.self", r)
}
// CanGlobalApplicationFlag checks if current user can manage global flags for applications
//
// This function is auto-generated
func (svc accessControl) CanGlobalApplicationFlag(ctx context.Context) bool {
return svc.can(ctx, "application.flag.global", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "application.flag.global", r)
}
// CanCreateTemplate checks if current user can create template
//
// This function is auto-generated
func (svc accessControl) CanCreateTemplate(ctx context.Context) bool {
return svc.can(ctx, "template.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "template.create", r)
}
// CanSearchTemplates checks if current user can list, search or filter templates
//
// This function is auto-generated
func (svc accessControl) CanSearchTemplates(ctx context.Context) bool {
return svc.can(ctx, "templates.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "templates.search", r)
}
// CanCreateReport checks if current user can create report
//
// This function is auto-generated
func (svc accessControl) CanCreateReport(ctx context.Context) bool {
return svc.can(ctx, "report.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "report.create", r)
}
// CanSearchReports checks if current user can list, search or filter reports
//
// This function is auto-generated
func (svc accessControl) CanSearchReports(ctx context.Context) bool {
return svc.can(ctx, "reports.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "reports.search", r)
}
// CanAssignReminder checks if current user can assign reminders
// CanAssignReminder checks if current user can assign reminders
//
// This function is auto-generated
func (svc accessControl) CanAssignReminder(ctx context.Context) bool {
return svc.can(ctx, "reminder.assign", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "reminder.assign", r)
}
// CanCreateQueue checks if current user can create messagebus queues
//
// This function is auto-generated
func (svc accessControl) CanCreateQueue(ctx context.Context) bool {
return svc.can(ctx, "queue.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "queue.create", r)
}
// CanSearchQueues checks if current user can list, search or filter messagebus queues
//
// This function is auto-generated
func (svc accessControl) CanSearchQueues(ctx context.Context) bool {
return svc.can(ctx, "queues.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "queues.search", r)
}
// CanCreateApigwRoute checks if current user can create api gateway route
//
// This function is auto-generated
func (svc accessControl) CanCreateApigwRoute(ctx context.Context) bool {
return svc.can(ctx, "apigw-route.create", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "apigw-route.create", r)
}
// CanSearchApigwRoutes checks if current user can list search or filter api gateway routes
//
// This function is auto-generated
func (svc accessControl) CanSearchApigwRoutes(ctx context.Context) bool {
return svc.can(ctx, "apigw-routes.search", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "apigw-routes.search", r)
}
// CanManageResourceTranslations checks if current user can list, search, create, or update resource translations
//
// This function is auto-generated
func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool {
return svc.can(ctx, "resource-translations.manage", &types.Component{})
r := &types.Component{}
return svc.can(ctx, "resource-translations.manage", r)
}
// rbacResourceValidator validates known component's resource by routing it to the appropriate validator
@@ -900,6 +925,7 @@ func rbacResourceOperations(r string) map[string]bool {
}
case types.QueueResourceType:
return map[string]bool{
"render": true,
"read": true,
"update": true,
"delete": true,
@@ -970,24 +996,24 @@ func rbacResourceOperations(r string) map[string]bool {
return nil
}
// rbacApigwRouteResourceValidator checks validity of rbac resource and operations
// rbacApigwRouteResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacApigwRouteResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system ApigwRoute resource", o)
}
}
if !strings.HasPrefix(r, types.ApigwRouteResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for apigwRoute resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ApigwRouteResourceType):], sep), sep)
@@ -1003,7 +1029,7 @@ func rbacApigwRouteResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for ApigwRoute", i)
return fmt.Errorf("invalid path wildcard level (%d) for apigwRoute resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1014,24 +1040,24 @@ func rbacApigwRouteResourceValidator(r string, oo ...string) error {
return nil
}
// rbacApplicationResourceValidator checks validity of rbac resource and operations
// rbacApplicationResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacApplicationResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system Application resource", o)
}
}
if !strings.HasPrefix(r, types.ApplicationResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for application resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ApplicationResourceType):], sep), sep)
@@ -1047,7 +1073,7 @@ func rbacApplicationResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Application", i)
return fmt.Errorf("invalid path wildcard level (%d) for application resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1058,24 +1084,24 @@ func rbacApplicationResourceValidator(r string, oo ...string) error {
return nil
}
// rbacAuthClientResourceValidator checks validity of rbac resource and operations
// rbacAuthClientResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacAuthClientResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system AuthClient resource", o)
}
}
if !strings.HasPrefix(r, types.AuthClientResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for authClient resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.AuthClientResourceType):], sep), sep)
@@ -1091,7 +1117,7 @@ func rbacAuthClientResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for AuthClient", i)
return fmt.Errorf("invalid path wildcard level (%d) for authClient resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1102,24 +1128,24 @@ func rbacAuthClientResourceValidator(r string, oo ...string) error {
return nil
}
// rbacQueueResourceValidator checks validity of rbac resource and operations
// rbacQueueResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacQueueResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system Queue resource", o)
}
}
if !strings.HasPrefix(r, types.QueueResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for queue resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.QueueResourceType):], sep), sep)
@@ -1135,7 +1161,7 @@ func rbacQueueResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Queue", i)
return fmt.Errorf("invalid path wildcard level (%d) for queue resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1146,24 +1172,24 @@ func rbacQueueResourceValidator(r string, oo ...string) error {
return nil
}
// rbacReportResourceValidator checks validity of rbac resource and operations
// rbacReportResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacReportResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system Report resource", o)
}
}
if !strings.HasPrefix(r, types.ReportResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for report resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ReportResourceType):], sep), sep)
@@ -1179,7 +1205,7 @@ func rbacReportResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Report", i)
return fmt.Errorf("invalid path wildcard level (%d) for report resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1190,24 +1216,24 @@ func rbacReportResourceValidator(r string, oo ...string) error {
return nil
}
// rbacRoleResourceValidator checks validity of rbac resource and operations
// rbacRoleResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacRoleResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system Role resource", o)
}
}
if !strings.HasPrefix(r, types.RoleResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for role resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.RoleResourceType):], sep), sep)
@@ -1223,7 +1249,7 @@ func rbacRoleResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Role", i)
return fmt.Errorf("invalid path wildcard level (%d) for role resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1234,24 +1260,24 @@ func rbacRoleResourceValidator(r string, oo ...string) error {
return nil
}
// rbacTemplateResourceValidator checks validity of rbac resource and operations
// rbacTemplateResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacTemplateResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system Template resource", o)
}
}
if !strings.HasPrefix(r, types.TemplateResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for template resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.TemplateResourceType):], sep), sep)
@@ -1267,7 +1293,7 @@ func rbacTemplateResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for Template", i)
return fmt.Errorf("invalid path wildcard level (%d) for template resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1278,24 +1304,24 @@ func rbacTemplateResourceValidator(r string, oo ...string) error {
return nil
}
// rbacUserResourceValidator checks validity of rbac resource and operations
// rbacUserResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacUserResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system User resource", o)
}
}
if !strings.HasPrefix(r, types.UserResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for user resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.UserResourceType):], sep), sep)
@@ -1311,7 +1337,7 @@ func rbacUserResourceValidator(r string, oo ...string) error {
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid resource path wildcard level (%d) for User", i)
return fmt.Errorf("invalid path wildcard level (%d) for user resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -1322,23 +1348,23 @@ func rbacUserResourceValidator(r string, oo ...string) error {
return nil
}
// rbacComponentResourceValidator checks validity of rbac resource and operations
// rbacComponentResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacComponentResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system resource", o)
}
}
if !strings.HasPrefix(r, types.ComponentResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for system component resource", o)
}
}
return nil
}

16
system/template.cue Normal file
View File

@@ -0,0 +1,16 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
template: schema.#resource & {
rbac: {
operations: {
read: description: "Read template"
update: description: "Update template"
delete: description: "Delete template"
render: description: "Render template"
}
}
}

View File

@@ -6,17 +6,6 @@ package types
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// - system.apigw-route.yaml
// - system.application.yaml
// - system.auth-client.yaml
// - system.queue.yaml
// - system.report.yaml
// - system.role.yaml
// - system.template.yaml
// - system.user.yaml
// - system.yaml
import (
"fmt"
"strconv"
@@ -29,6 +18,11 @@ type (
Component struct{}
)
var (
_ = fmt.Printf
_ = strconv.FormatUint
)
const (
ApigwRouteResourceType = "corteza::system:apigw-route"
ApplicationResourceType = "corteza::system:application"
@@ -55,10 +49,10 @@ func (r ApigwRoute) RbacResource() string {
// RBAC resource is in the corteza::system:apigw-route/... format
//
// This function is auto-generated
func ApigwRouteRbacResource(id uint64) string {
func ApigwRouteRbacResource(ID uint64) string {
cpts := []interface{}{ApigwRouteResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -67,7 +61,6 @@ func ApigwRouteRbacResource(id uint64) string {
}
// @todo template
func ApigwRouteRbacResourceTpl() string {
return "%s/%s"
}
@@ -86,10 +79,10 @@ func (r Application) RbacResource() string {
// RBAC resource is in the corteza::system:application/... format
//
// This function is auto-generated
func ApplicationRbacResource(id uint64) string {
func ApplicationRbacResource(ID uint64) string {
cpts := []interface{}{ApplicationResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -98,7 +91,6 @@ func ApplicationRbacResource(id uint64) string {
}
// @todo template
func ApplicationRbacResourceTpl() string {
return "%s/%s"
}
@@ -117,10 +109,10 @@ func (r AuthClient) RbacResource() string {
// RBAC resource is in the corteza::system:auth-client/... format
//
// This function is auto-generated
func AuthClientRbacResource(id uint64) string {
func AuthClientRbacResource(ID uint64) string {
cpts := []interface{}{AuthClientResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -129,7 +121,6 @@ func AuthClientRbacResource(id uint64) string {
}
// @todo template
func AuthClientRbacResourceTpl() string {
return "%s/%s"
}
@@ -148,10 +139,10 @@ func (r Queue) RbacResource() string {
// RBAC resource is in the corteza::system:queue/... format
//
// This function is auto-generated
func QueueRbacResource(id uint64) string {
func QueueRbacResource(ID uint64) string {
cpts := []interface{}{QueueResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -160,7 +151,6 @@ func QueueRbacResource(id uint64) string {
}
// @todo template
func QueueRbacResourceTpl() string {
return "%s/%s"
}
@@ -179,10 +169,10 @@ func (r Report) RbacResource() string {
// RBAC resource is in the corteza::system:report/... format
//
// This function is auto-generated
func ReportRbacResource(id uint64) string {
func ReportRbacResource(ID uint64) string {
cpts := []interface{}{ReportResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -191,7 +181,6 @@ func ReportRbacResource(id uint64) string {
}
// @todo template
func ReportRbacResourceTpl() string {
return "%s/%s"
}
@@ -210,10 +199,10 @@ func (r Role) RbacResource() string {
// RBAC resource is in the corteza::system:role/... format
//
// This function is auto-generated
func RoleRbacResource(id uint64) string {
func RoleRbacResource(ID uint64) string {
cpts := []interface{}{RoleResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -222,7 +211,6 @@ func RoleRbacResource(id uint64) string {
}
// @todo template
func RoleRbacResourceTpl() string {
return "%s/%s"
}
@@ -241,10 +229,10 @@ func (r Template) RbacResource() string {
// RBAC resource is in the corteza::system:template/... format
//
// This function is auto-generated
func TemplateRbacResource(id uint64) string {
func TemplateRbacResource(ID uint64) string {
cpts := []interface{}{TemplateResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -253,7 +241,6 @@ func TemplateRbacResource(id uint64) string {
}
// @todo template
func TemplateRbacResourceTpl() string {
return "%s/%s"
}
@@ -272,10 +259,10 @@ func (r User) RbacResource() string {
// RBAC resource is in the corteza::system:user/... format
//
// This function is auto-generated
func UserRbacResource(id uint64) string {
func UserRbacResource(ID uint64) string {
cpts := []interface{}{UserResourceType}
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
@@ -284,7 +271,6 @@ func UserRbacResource(id uint64) string {
}
// @todo template
func UserRbacResourceTpl() string {
return "%s/%s"
}
@@ -308,7 +294,6 @@ func ComponentRbacResource() string {
}
// @todo template
func ComponentRbacResourceTpl() string {
return "%s"
}

33
system/user.cue Normal file
View File

@@ -0,0 +1,33 @@
package system
import (
"github.com/cortezaproject/corteza-server/def/schema"
)
user: schema.#resource & {
// fields: {
// ID: schema.IdField
// handle: schema.HandleField
// email: { unique: true }
// kind: {}
// meta: {
// note: type: string
// sub: {
// sub: { "non-unique-string-named-sub": {} }
// }
// }
// }
rbac: {
operations: {
"read": description: "Read user"
"update": description: "Update user"
"delete": description: "Delete user"
"suspend": description: "Suspend user"
"unsuspend": description: "Unsuspend user"
"email.unmask": description: "Unmask email"
"name.unmask": description: "Unmask name"
"impersonate": description: "Impersonate user"
}
}
}