Migrate codegen for locale to CUE

This commit is contained in:
Denis Arh
2022-01-26 16:25:53 +01:00
parent c19ee84f5d
commit 3568d0841e
35 changed files with 1284 additions and 1212 deletions
+10 -4
View File
@@ -1,10 +1,16 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/codegen/schema"
"github.com/cortezaproject/corteza-server/codegen/schema"
)
all: [...schema.#codegen] &
rbacAccessControl +
rbacTypes +
// List of all codegen jobs for the entire platform
//
// How to run it?
// @todo when this gets into
// cue eval codegen/*.cue --out json -e platform | go run codegen/tool/*.go -v
platform: [...schema.#codegen] &
rbacAccessControl+
rbacTypes+
localeTypes+
[] // placeholder
@@ -0,0 +1,206 @@
package {{ .package }}
{{ template "gocode/header-gentext.tpl" }}
import (
"context"
{{- range .imports }}
{{ . }}
{{- end }}
"github.com/cortezaproject/corteza-server/pkg/actionlog"
intAuth "github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/errors"
"github.com/cortezaproject/corteza-server/pkg/locale"
"github.com/cortezaproject/corteza-server/pkg/options"
"github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
"golang.org/x/text/language"
)
type (
localeAccessControl interface {
CanManageResourceTranslations(ctx context.Context) bool
}
resourceTranslationsManager struct {
actionlog actionlog.Recorder
locale locale.Resource
store store.Storer
ac localeAccessController
}
localeAccessController interface {
CanManageResourceTranslations(context.Context) bool
}
ResourceTranslationsManagerService interface {
{{- range .resources }}
{{ .expIdent }}(ctx context.Context, {{ range .references }}{{ . }} uint64, {{ end }}) (locale.ResourceTranslationSet, error)
{{- end }}
Upsert(context.Context, locale.ResourceTranslationSet) error
Locale() locale.Resource
}
)
var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
return &resourceTranslationsManager{
actionlog: DefaultActionlog,
store: DefaultStore,
ac: DefaultAccessControl,
locale: ls,
}
}
func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
// User is allowed to manage resource translations when:
// - managed resource translation strings are all for default language
// or
// - user is allowed to manage resource translations
if rr.ContainsForeign(svc.Locale().Default().Tag) {
if !svc.ac.CanManageResourceTranslations(ctx) {
return ErrNotAllowedToManageResourceTranslations
}
}
for _, r := range rr {
r.Msg = locale.SanitizeMessage(r.Msg)
}
// @todo validation
me := intAuth.GetIdentityFromContext(ctx)
// - group by resource
localeByRes := make(map[string]locale.ResourceTranslationSet)
for _, r := range rr {
localeByRes[r.Resource] = append(localeByRes[r.Resource], r)
}
// - for each resource, fetch the current state
sysLocale := make(systemTypes.ResourceTranslationSet, 0, len(rr))
for res, rr := range localeByRes {
current, _, err := store.SearchResourceTranslations(ctx, svc.store, systemTypes.ResourceTranslationFilter{
Resource: res,
})
if err != nil {
return err
}
// get deltas and prepare upsert accordingly
aux := current.New(rr)
aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
cc.ID = nextID()
cc.CreatedAt = *now()
cc.CreatedBy = me.Identity()
return nil
})
sysLocale = append(sysLocale, aux...)
aux = current.Old(rr)
_ = aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
cc.UpdatedAt = now()
cc.UpdatedBy = me.Identity()
return nil
})
sysLocale = append(sysLocale, aux...)
}
err = store.UpsertResourceTranslation(ctx, svc.store, sysLocale...)
if err != nil {
return err
}
// Reload ALL resource translations
// @todo we could probably do this more selectively and refresh only updated resources?
_ = locale.Global().ReloadResourceTranslations(ctx)
return nil
}
func (svc resourceTranslationsManager) Locale() locale.Resource {
return svc.locale
}
{{- range .resources }}
func (svc resourceTranslationsManager) {{ .expIdent }}(ctx context.Context, {{ range .references }}{{ . }} uint64, {{ end }}) (locale.ResourceTranslationSet, error) {
var (
err error
out locale.ResourceTranslationSet
res *types.{{ .expIdent }}
k types.LocaleKey
)
res, err = svc.load{{ .expIdent }}(ctx, svc.store, {{ range .references }}{{ . }}, {{ end }})
if err != nil {
return nil, err
}
for _, tag := range svc.locale.Tags() {
{{- range .keys}}
{{- if not .customHandler }}
k = types.{{ .struct }}
out = append(out, &locale.ResourceTranslation{
Resource: res.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, res.ResourceTranslation(), k.Path),
})
{{ end }}
{{- end}}
}
{{ if .extended }}
tmp, err := svc.{{ .ident }}Extended(ctx, res)
return append(out, tmp...), err
{{- else }}
return out, nil
{{- end }}
}
{{- end }}
func updateTranslations(ctx context.Context, ac localeAccessControl, lsvc ResourceTranslationsManagerService, tt ...*locale.ResourceTranslation) error {
if lsvc == nil || lsvc.Locale() == nil || lsvc.Locale().Default() == nil {
// gracefully handle partial initializations
return nil
}
var (
// assuming options will not change after start
contentLang = lsvc.Locale().Default().Tag
)
if options.Locale().ResourceTranslationsEnabled {
contentLang = locale.GetContentLanguageFromContext(ctx)
// Resource translations enabled
if contentLang == language.Und {
// If no content-language meta (HTTP header) info was
// used, do not run update translations - we do not know
// what is the language that we're sending in
return nil
}
if !lsvc.Locale().SupportedLang(contentLang) {
// unsupported language
return errors.InvalidData("unsupported language")
}
if !ac.CanManageResourceTranslations(ctx) {
return errors.Unauthorized("not allowed to manage resource translations")
}
}
locale.ResourceTranslationSet(tt).SetLanguage(contentLang)
if err := lsvc.Upsert(ctx, tt); err != nil {
return err
}
return nil
}
@@ -0,0 +1,120 @@
package {{ .package }}
{{ template "gocode/header-gentext.tpl" }}
import (
"fmt"
"strconv"
"github.com/cortezaproject/corteza-server/pkg/locale"
)
type (
LocaleKey struct {
Name string
Resource string
Path string
CustomHandler string
}
)
// Types and stuff
const (
{{- range .resources }}
{{ .const }} = "{{ .type }}"
{{- end }}
)
var (
// @todo can we remove LocaleKey struct for string constant?
{{- range .resources }}
{{- range .keys }}
{{ .struct }} = LocaleKey{ Path: {{ printf "%q" .path }} }
{{- end }}
{{- end }}
)
{{- range .resources }}
// ResourceTranslation returns string representation of Locale resource for {{ .expIdent }} by calling {{ .expIdent }}ResourceTranslation fn
//
// Locale resource is in "{{ .type }}/..." format
//
// This function is auto-generated
func (r {{ .expIdent }}) ResourceTranslation() string {
return {{ .expIdent }}ResourceTranslation({{ if .references }}{{ range .references }}r.{{ . }},{{ end }}{{ end }})
}
// {{ .expIdent }}ResourceTranslation returns string representation of Locale resource for {{ .expIdent }}
//
// Locale resource is in the {{ .type }}/{{- if .references }}...{{ end }} format
//
// This function is auto-generated
func {{ .expIdent }}ResourceTranslation({{ if .references }}{{ range .references }}{{ . }} uint64,{{ end }}{{ end }}) string {
{{- if .references }}
cpts := []interface{{"{}"}}{
{{ .expIdent }}ResourceTranslationType,
{{- range .references }}
strconv.FormatUint({{ . }}, 10),
{{- end }}
}
return fmt.Sprintf({{ .expIdent }}ResourceTranslationTpl(), cpts...)
{{- end }}
}
func {{ .expIdent }}ResourceTranslationTpl() string {
{{- if .references }}
return "%s
{{- range .references }}/%s{{- end }}"
{{- else }}
return "%s"
{{- end }}
}
func (r *{{ .expIdent }}) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
{{- range .keys }}
{{ if .decodeFunc }}
{{ if not .extended }}
r.{{ .decodeFunc }}(tt)
{{- end}}
{{ else }}
if aux = tt.FindByKey({{ .struct }}.Path); aux != nil {
r.{{ .fieldPath }} = aux.Msg
}
{{- end}}
{{- end}}
{{- if .extended }}
r.decodeTranslations(tt)
{{- end }}
}
func (r *{{ .expIdent }}) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
{{- range .keys }}
{{ if .encodeFunc }}
{{ if not .extended }}
out = append(out, r.{{ .encodeFunc }}()...)
{{- end}}
{{ else }}
if r.{{ .fieldPath }} != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
Key: {{ .struct }}.Path,
Msg: locale.SanitizeMessage(r.{{ .fieldPath }}),
})
}
{{- end}}
{{- end}}
{{- if .extended }}
out = append(out, r.encodeTranslations()...)
{{- end }}
return out
}
{{- end }}
@@ -10,7 +10,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
{{- range .imports }}
"{{ . }}"
{{ . }}
{{- end }}
)
@@ -57,7 +57,7 @@ func (svc accessControl) List() (out []map[string]string) {
{{- range .operations }}
{
"type": {{ .const }},
"any": {{ .ctor }},
"any": {{ .resFunc }}({{ range .references }}0,{{ end }}),
"op": {{ printf "%q" .op }},
},
{{- end }}
@@ -38,7 +38,7 @@ const (
//
// This function is auto-generated
func (r {{ .goType }}) RbacResource() string {
return {{ .resFunc }}({{ if not .component }}{{ range .references }}r.{{ . }},{{ end }}{{ end }})
return {{ .resFunc }}({{ if not .component }}{{ range .references }}r.{{ .refField }},{{ end }}{{ end }})
}
// {{ .resFunc }} returns string representation of RBAC resource for {{ .goType }}
@@ -46,12 +46,12 @@ func (r {{ .goType }}) RbacResource() string {
// 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 {
func {{ .resFunc }}({{ if not .component }}{{ range .references }}{{ .param }} uint64,{{ end }}{{ end }}) string {
{{- if .references }}
cpts := []interface{{"{}"}}{{"{"}}{{ .goType }}ResourceType{{"}"}}
{{- range .references }}
if {{ . }} != 0 {
cpts = append(cpts, strconv.FormatUint({{ . }}, 10))
if {{ .param }} != 0 {
cpts = append(cpts, strconv.FormatUint({{ .param }}, 10))
} else {
cpts = append(cpts, "*")
}
+44
View File
@@ -0,0 +1,44 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/app"
"github.com/cortezaproject/corteza-server/codegen/schema"
"strings"
)
localeService:
[...schema.#codegen] &
[
// wrapped with additional for loop to trim out templates with empty types list
for tpl in [
for cmp in app.corteza.components {
template: "gocode/locale/service.go.tpl"
output: "\(cmp.ident)/service/locale.gen.go"
payload: {
package: "service"
imports: [
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
]
resources: [
for res in cmp.resources if (res.locale != _|_) if (!res.locale.skipSvc) {
expIdent: res.expIdent
ident: res.ident
references: [ for field in res.locale.resource.references {strings.ToTitle(field)}]
extended: res.locale.extended
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
struct: key.struct
extended: extended
customHandler: key.customHandler
if key.serviceFunc != _|_ {serviceFunc: key.serviceFunc}
}]
},
]
}
},
// skip empty type lists
] if len(tpl.payload.resources) > 0 {tpl}]
+55
View File
@@ -0,0 +1,55 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/app"
"github.com/cortezaproject/corteza-server/codegen/schema"
"strings"
)
localeTypes:
[...schema.#codegen] &
[
// wrapped with additional for loop to trim out templates with empty types list
for tpl in [
for cmp in app.corteza.components {
template: "gocode/locale/types.go.tpl"
output: "\(cmp.ident)/types/locale.gen.go"
payload: {
package: "types"
resources: [
for res in cmp.resources if res.locale != _|_ {
expIdent: res.expIdent
const: res.locale.resource.const
type: res.locale.resource.type
references: [ for field in res.locale.resource.references {strings.ToTitle(field)}]
extended: res.locale.extended
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
struct: key.struct
field: strings.ToTitle(key.name)
path: strings.Join([ for p in key.expandedPath {
if p.var {"{{\(p.part)}}"}
if !p.var {p.part}
}], ".")
if !key.customHandler {
fieldPath: strings.Join([ for p in key.expandedPath {
strings.ToTitle(p.part)
}], ".")
}
"extended": extended
if key.decodeFunc != _|_ {decodeFunc: key.decodeFunc}
if key.encodeFunc != _|_ {encodeFunc: key.encodeFunc}
}]
},
]
}
},
// skip empty type lists
] if len(tpl.payload.resources) > 0 {tpl}]
+33 -27
View File
@@ -1,8 +1,8 @@
package codegen
import (
"github.com/cortezaproject/corteza-server/codegen/schema"
"github.com/cortezaproject/corteza-server/app"
"github.com/cortezaproject/corteza-server/codegen/schema"
"github.com/cortezaproject/corteza-server/app"
)
rbacAccessControl:
@@ -12,47 +12,53 @@ rbacAccessControl:
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"
imports: [
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
]
// 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
"op": op.handle
const: "types.\(res.expIdent)ResourceType"
resFunc: "types.\(res.expIdent)RbacResource"
goType: "types.\(res.expIdent)"
description: op.description
checkFuncName: op.checkFuncName
if len(res.parents) > 0 {
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
}
},
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
"op": op.handle
const: "types.ComponentResourceType"
resFunc: "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: res.ident
const: "types.\(res.expIdent)ResourceType"
funcName: "rbac\(res.expIdent)ResourceValidator"
if len(res.parents) > 0 {
references: [ for p in res.parents {p.refField}, "ID"]
}
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}]
label: "\(cmp.ident) component"
const: "types.ComponentResourceType"
funcName: "rbacComponentResourceValidator"
operations: [ for op in cmp.rbac.operations {op.handle}]
},
]
}
+16 -15
View File
@@ -3,7 +3,6 @@ package codegen
import (
"github.com/cortezaproject/corteza-server/app"
"github.com/cortezaproject/corteza-server/codegen/schema"
"strings"
)
rbacTypes:
@@ -19,23 +18,25 @@ rbacTypes:
// 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
const: "\(res.expIdent)ResourceType"
type: res.fqrn
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) } ]
if len(res.parents) > 0 {
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
}
},
{
"const": "ComponentResourceType"
"type": cmp.rbac.resource.type
"resFunc": "ComponentRbacResource"
"tplFunc": "ComponentRbacResourceTpl"
"attFunc": "ComponentRbacAttributes"
"goType": "Component"
"component": true
const: "ComponentResourceType"
type: cmp.fqrn
resFunc: "ComponentRbacResource"
tplFunc: "ComponentRbacResourceTpl"
attFunc: "ComponentRbacAttributes"
goType: "Component"
component: true
},
]
}
+6 -10
View File
@@ -5,19 +5,15 @@ import (
)
chart: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "ID"]
parents: [
{handle: "namespace"},
]
rbac: {
operations: {
"read": {}
"update": {}
"delete": {}
"update": {}
"delete": {}
}
}
// locale:
// resource:
// references: [ namespace, ID ]
// keys:
// - name
}
+4 -4
View File
@@ -5,15 +5,15 @@ import (
)
component: schema.#component & {
ident: "compose"
handle: "compose"
resources: {
"namespace": namespace
"chart": chart
"module": module
"module-field": moduleField
"record": record
"namespace": namespace
"page": page
"chart": chart
"record": record
}
rbac: operations: {
+36 -19
View File
@@ -5,30 +5,47 @@ import (
)
moduleField: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "moduleID", "ID"]
parents: [
{handle: "namespace"},
{handle: "module"},
]
rbac: {
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
// }
locale: {
skipSvc: true
keys: {
label: {}
descriptionView: {
path: ["meta", "description", "view"]
customHandler: true
}
descriptionEdit: {
path: ["meta", "description", "edit"]
customHandler: true
}
hintView: {
path: ["meta", "hint", "view"]
customHandler: true
}
hintEdit: {
path: ["meta", "hint", "edit"]
customHandler: true
}
validatorError: {
path: ["expression", "validator", {part: "validatorID", var: true}, "error"]
customHandler: true
}
optionsOptionTexts: {
path: ["meta", "options", {part: "value", var: true}, "text"]
customHandler: true
}
}
}
}
+11 -2
View File
@@ -5,9 +5,12 @@ import (
)
module: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "ID"]
handle: "module"
parents: [
{handle: "namespace"},
]
rbac: {
operations: {
"read": {}
"update": {}
@@ -17,6 +20,12 @@ module: schema.#resource & {
}
}
locale: {
keys: {
"name": {}
}
}
//locale:
// resource:
// references: [ namespace, ID ]
+13 -6
View File
@@ -20,10 +20,17 @@ namespace: schema.#resource & {
}
}
//
//locale:
// keys:
// - name
// - { path: subtitle, field: "Meta.Subtitle" }
// - { path: description, field: "Meta.Description" }
locale: {
resource: references: [ "ID"]
keys: {
name: {}
metaSubtitle: {
path: ["meta", "subtitle"]
}
metaDescription: {
path: ["meta", "description"]
}
}
}
}
+24 -13
View File
@@ -5,9 +5,11 @@ import (
)
page: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "ID"]
parents: [
{handle: "namespace"},
]
rbac: {
operations: {
"read": {}
"update": {}
@@ -15,15 +17,24 @@ page: schema.#resource & {
}
}
//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 }
locale: {
extended: true
keys: {
title: {}
description: {}
blockTitle: {
path: ["pageBlock", {part: "blockID", var: true}, "title"]
customHandler: true
}
blockDescription: {
path: ["pageBlock", {part: "blockID", var: true}, "description"]
customHandler: true
}
blockAutomationButtonLabel: {
path: ["pageBlock", {part: "blockID", var: true}, "button", {part: "buttonID", var: true}, "label"]
customHandler: true
}
}
}
}
+5 -2
View File
@@ -5,9 +5,12 @@ import (
)
record: schema.#resource & {
rbac: {
resource: references: [ "namespaceID", "moduleID", "ID"]
parents: [
{handle: "namespace"},
{handle: "module"},
]
rbac: {
operations: {
"read": {}
"update": {}
+237 -259
View File
@@ -9,11 +9,12 @@ package service
import (
"context"
"fmt"
"strings"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/spf13/cast"
"strings"
)
type (
@@ -55,55 +56,20 @@ 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.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "read",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "update",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"op": "delete",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "manage",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "module.create",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "modules.search",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "chart.create",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "charts.search",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "page.create",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(0),
"op": "pages.search",
},
{
"type": types.ModuleResourceType,
"any": types.ModuleRbacResource(0, 0),
@@ -140,20 +106,55 @@ func (svc accessControl) List() (out []map[string]string) {
"op": "recod.value.update",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "read",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "update",
},
{
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "delete",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "manage",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "module.create",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "modules.search",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "chart.create",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "charts.search",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "page.create",
},
{
"type": types.NamespaceResourceType,
"any": types.NamespaceRbacResource(),
"op": "pages.search",
},
{
"type": types.PageResourceType,
"any": types.PageRbacResource(0, 0),
@@ -170,18 +171,18 @@ func (svc accessControl) List() (out []map[string]string) {
"op": "delete",
},
{
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"op": "read",
},
{
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"op": "update",
},
{
"type": types.ChartResourceType,
"any": types.ChartRbacResource(0, 0),
"type": types.RecordResourceType,
"any": types.RecordRbacResource(0, 0, 0),
"op": "delete",
},
{
@@ -287,21 +288,91 @@ func (svc accessControl) CloneRulesByRoleID(ctx context.Context, fromRoleID uint
return svc.rbac.CloneRulesByRoleID(ctx, fromRoleID, toRoleID...)
}
// CanReadNamespace checks if current user can read corteza::compose:namespace
// CanReadChart checks if current user can read
//
// 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
//
// 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
//
// This function is auto-generated
func (svc accessControl) CanDeleteChart(ctx context.Context, r *types.Chart) bool {
return svc.can(ctx, "delete", r)
}
// CanReadModule checks if current user can read
//
// 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
//
// 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
//
// This function is auto-generated
func (svc accessControl) CanDeleteModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "delete", r)
}
// 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)
}
// CanReadNamespace checks if current user can read
//
// 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 corteza::compose:namespace
// CanUpdateNamespace checks if current user can update
//
// 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 corteza::compose:namespace
// CanDeleteNamespace checks if current user can delete
//
// This function is auto-generated
func (svc accessControl) CanDeleteNamespace(ctx context.Context, r *types.Namespace) bool {
@@ -357,115 +428,45 @@ func (svc accessControl) CanSearchPagesNamespace(ctx context.Context, r *types.N
return svc.can(ctx, "pages.search", r)
}
// CanReadModule checks if current user can read corteza::compose: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 corteza::compose: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 corteza::compose:module
//
// This function is auto-generated
func (svc accessControl) CanDeleteModule(ctx context.Context, r *types.Module) bool {
return svc.can(ctx, "delete", r)
}
// 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 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 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
// CanReadPage checks if current user can read
//
// 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
// CanUpdatePage checks if current user can update
//
// 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
// CanDeletePage checks if current user can delete
//
// 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
// CanReadRecord checks if current user can read
//
// This function is auto-generated
func (svc accessControl) CanReadChart(ctx context.Context, r *types.Chart) bool {
func (svc accessControl) CanReadRecord(ctx context.Context, r *types.Record) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateChart checks if current user can update corteza::compose:chart
// CanUpdateRecord checks if current user can update
//
// This function is auto-generated
func (svc accessControl) CanUpdateChart(ctx context.Context, r *types.Chart) bool {
func (svc accessControl) CanUpdateRecord(ctx context.Context, r *types.Record) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteChart checks if current user can delete corteza::compose:chart
// CanDeleteRecord checks if current user can delete
//
// This function is auto-generated
func (svc accessControl) CanDeleteChart(ctx context.Context, r *types.Chart) bool {
func (svc accessControl) CanDeleteRecord(ctx context.Context, r *types.Record) bool {
return svc.can(ctx, "delete", r)
}
@@ -522,18 +523,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.NamespaceResourceType:
return rbacNamespaceResourceValidator(r, oo...)
case types.ChartResourceType:
return rbacChartResourceValidator(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.NamespaceResourceType:
return rbacNamespaceResourceValidator(r, oo...)
case types.PageResourceType:
return rbacPageResourceValidator(r, oo...)
case types.ChartResourceType:
return rbacChartResourceValidator(r, oo...)
case types.RecordResourceType:
return rbacRecordResourceValidator(r, oo...)
case types.ComponentResourceType:
return rbacComponentResourceValidator(r, oo...)
}
@@ -546,18 +547,11 @@ 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.NamespaceResourceType:
case types.ChartResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
"manage": true,
"module.create": true,
"modules.search": true,
"chart.create": true,
"charts.search": true,
"page.create": true,
"pages.search": true,
"read": true,
"update": true,
"delete": true,
}
case types.ModuleResourceType:
return map[string]bool{
@@ -572,11 +566,18 @@ func rbacResourceOperations(r string) map[string]bool {
"recod.value.read": true,
"recod.value.update": true,
}
case types.RecordResourceType:
case types.NamespaceResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
"read": true,
"update": true,
"delete": true,
"manage": true,
"module.create": true,
"modules.search": true,
"chart.create": true,
"charts.search": true,
"page.create": true,
"pages.search": true,
}
case types.PageResourceType:
return map[string]bool{
@@ -584,7 +585,7 @@ func rbacResourceOperations(r string) map[string]bool {
"update": true,
"delete": true,
}
case types.ChartResourceType:
case types.RecordResourceType:
return map[string]bool{
"read": true,
"update": true,
@@ -604,13 +605,13 @@ func rbacResourceOperations(r string) map[string]bool {
return nil
}
// rbacNamespaceResourceValidator checks validity of RBAC resource and operations
// 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 rbacNamespaceResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.NamespaceResourceType) {
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")
}
@@ -618,14 +619,15 @@ func rbacNamespaceResourceValidator(r string, oo ...string) error {
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for namespace resource", o)
return fmt.Errorf("invalid operation '%s' for chart resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.NamespaceResourceType):], sep), sep)
pp = strings.Split(strings.Trim(r[len(types.ChartResourceType):], sep), sep)
prc = []string{
"NamespaceID",
"ID",
}
)
@@ -637,7 +639,7 @@ func rbacNamespaceResourceValidator(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 path wildcard level (%d) for namespace resource", i)
return fmt.Errorf("invalid path wildcard level (%d) for chart resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
@@ -670,7 +672,7 @@ func rbacModuleResourceValidator(r string, oo ...string) error {
var (
pp = strings.Split(strings.Trim(r[len(types.ModuleResourceType):], sep), sep)
prc = []string{
"namespaceID",
"NamespaceID",
"ID",
}
)
@@ -715,8 +717,8 @@ func rbacModuleFieldResourceValidator(r string, oo ...string) error {
var (
pp = strings.Split(strings.Trim(r[len(types.ModuleFieldResourceType):], sep), sep)
prc = []string{
"namespaceID",
"moduleID",
"NamespaceID",
"ModuleID",
"ID",
}
)
@@ -739,6 +741,72 @@ func rbacModuleFieldResourceValidator(r string, oo ...string) error {
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 {
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)
}
}
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 {
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
}
// rbacRecordResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
@@ -761,8 +829,8 @@ func rbacRecordResourceValidator(r string, oo ...string) error {
var (
pp = strings.Split(strings.Trim(r[len(types.RecordResourceType):], sep), sep)
prc = []string{
"namespaceID",
"moduleID",
"NamespaceID",
"ModuleID",
"ID",
}
)
@@ -785,96 +853,6 @@ func rbacRecordResourceValidator(r string, oo ...string) error {
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 {
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
+11 -16
View File
@@ -6,11 +6,6 @@ package service
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// - compose.module.yaml
// - compose.namespace.yaml
// - compose.page.yaml
import (
"context"
"github.com/cortezaproject/corteza-server/compose/types"
@@ -41,9 +36,9 @@ type (
}
ResourceTranslationsManagerService interface {
Module(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error)
Module(ctx context.Context, NamespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error)
Namespace(ctx context.Context, ID uint64) (locale.ResourceTranslationSet, error)
Page(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error)
Page(ctx context.Context, NamespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error)
Upsert(context.Context, locale.ResourceTranslationSet) error
Locale() locale.Resource
@@ -108,7 +103,7 @@ func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.Res
sysLocale = append(sysLocale, aux...)
aux = current.Old(rr)
aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
_ = aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
cc.UpdatedAt = now()
cc.UpdatedBy = me.Identity()
return nil
@@ -132,7 +127,7 @@ func (svc resourceTranslationsManager) Locale() locale.Resource {
return svc.locale
}
func (svc resourceTranslationsManager) Module(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error) {
func (svc resourceTranslationsManager) Module(ctx context.Context, NamespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error) {
var (
err error
out locale.ResourceTranslationSet
@@ -140,7 +135,7 @@ func (svc resourceTranslationsManager) Module(ctx context.Context, namespaceID u
k types.LocaleKey
)
res, err = svc.loadModule(ctx, svc.store, namespaceID, ID)
res, err = svc.loadModule(ctx, svc.store, NamespaceID, ID)
if err != nil {
return nil, err
}
@@ -156,8 +151,7 @@ func (svc resourceTranslationsManager) Module(ctx context.Context, namespaceID u
}
tmp, err := svc.moduleExtended(ctx, res)
return append(out, tmp...), err
return out, nil
}
func (svc resourceTranslationsManager) Namespace(ctx context.Context, ID uint64) (locale.ResourceTranslationSet, error) {
@@ -182,7 +176,7 @@ func (svc resourceTranslationsManager) Namespace(ctx context.Context, ID uint64)
Msg: svc.locale.TResourceFor(tag, res.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyNamespaceSubtitle
k = types.LocaleKeyNamespaceMetaSubtitle
out = append(out, &locale.ResourceTranslation{
Resource: res.ResourceTranslation(),
Lang: tag.String(),
@@ -190,7 +184,7 @@ func (svc resourceTranslationsManager) Namespace(ctx context.Context, ID uint64)
Msg: svc.locale.TResourceFor(tag, res.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyNamespaceDescription
k = types.LocaleKeyNamespaceMetaDescription
out = append(out, &locale.ResourceTranslation{
Resource: res.ResourceTranslation(),
Lang: tag.String(),
@@ -199,10 +193,11 @@ func (svc resourceTranslationsManager) Namespace(ctx context.Context, ID uint64)
})
}
return out, nil
}
func (svc resourceTranslationsManager) Page(ctx context.Context, namespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error) {
func (svc resourceTranslationsManager) Page(ctx context.Context, NamespaceID uint64, ID uint64) (locale.ResourceTranslationSet, error) {
var (
err error
out locale.ResourceTranslationSet
@@ -210,7 +205,7 @@ func (svc resourceTranslationsManager) Page(ctx context.Context, namespaceID uin
k types.LocaleKey
)
res, err = svc.loadPage(ctx, svc.store, namespaceID, ID)
res, err = svc.loadPage(ctx, svc.store, NamespaceID, ID)
if err != nil {
return nil, err
}
+8 -8
View File
@@ -28,14 +28,14 @@ func (svc resourceTranslationsManager) moduleExtended(ctx context.Context, res *
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldDescriptionView
k = types.LocaleKeyModuleFieldMetaDescriptionView
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldDescriptionEdit
k = types.LocaleKeyModuleFieldMetaDescriptionEdit
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
@@ -43,14 +43,14 @@ func (svc resourceTranslationsManager) moduleExtended(ctx context.Context, res *
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldHintView
k = types.LocaleKeyModuleFieldMetaHintView
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
Key: k.Path,
Msg: svc.locale.TResourceFor(tag, f.ResourceTranslation(), k.Path),
})
k = types.LocaleKeyModuleFieldHintEdit
k = types.LocaleKeyModuleFieldMetaHintEdit
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Lang: tag.String(),
@@ -86,7 +86,7 @@ func (svc resourceTranslationsManager) moduleFieldExpressionsHandler(ctx context
"{{validatorID}}", strconv.FormatUint(vContentID, 10),
)
tKey := rpl.Replace(types.LocaleKeyModuleFieldValidatorError.Path)
tKey := rpl.Replace(types.LocaleKeyModuleFieldExpressionValidatorValidatorIDError.Path)
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
@@ -128,7 +128,7 @@ func (svc resourceTranslationsManager) moduleFieldOptionsHandler(ctx context.Con
}
}
trKey := strings.NewReplacer("{{value}}", value).Replace(types.LocaleKeyModuleFieldOptionsOptionTexts.Path)
trKey := strings.NewReplacer("{{value}}", value).Replace(types.LocaleKeyModuleFieldMetaOptionsValueText.Path)
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
@@ -154,7 +154,7 @@ func (svc resourceTranslationsManager) pageExtended(ctx context.Context, res *ty
)
// base stuff
k = types.LocaleKeyPageBlockTitle
k = types.LocaleKeyPagePageBlockBlockIDTitle
out = append(out, &locale.ResourceTranslation{
Resource: res.ResourceTranslation(),
Lang: tag.String(),
@@ -162,7 +162,7 @@ func (svc resourceTranslationsManager) pageExtended(ctx context.Context, res *ty
Msg: svc.locale.TResourceFor(tag, res.ResourceTranslation(), rpl.Replace(k.Path)),
})
k = types.LocaleKeyPageBlockDescription
k = types.LocaleKeyPagePageBlockBlockIDDescription
out = append(out, &locale.ResourceTranslation{
Resource: res.ResourceTranslation(),
Lang: tag.String(),
+126 -175
View File
@@ -6,12 +6,6 @@ package types
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// - compose.module-field.yaml
// - compose.module.yaml
// - compose.namespace.yaml
// - compose.page.yaml
import (
"fmt"
"github.com/cortezaproject/corteza-server/pkg/locale"
@@ -29,167 +23,39 @@ type (
// Types and stuff
const (
ModuleFieldResourceTranslationType = "compose:module-field"
ModuleResourceTranslationType = "compose:module"
ModuleFieldResourceTranslationType = "compose:module-field"
NamespaceResourceTranslationType = "compose:namespace"
PageResourceTranslationType = "compose:page"
)
var (
LocaleKeyModuleFieldLabel = LocaleKey{
Name: "label",
Resource: ModuleFieldResourceTranslationType,
Path: "label",
}
LocaleKeyModuleFieldDescriptionView = LocaleKey{
Name: "descriptionView",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.description.view",
CustomHandler: "descriptionView",
}
LocaleKeyModuleFieldDescriptionEdit = LocaleKey{
Name: "descriptionEdit",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.description.edit",
CustomHandler: "descriptionEdit",
}
LocaleKeyModuleFieldHintView = LocaleKey{
Name: "hintView",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.hint.view",
CustomHandler: "hintView",
}
LocaleKeyModuleFieldHintEdit = LocaleKey{
Name: "hintEdit",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.hint.edit",
CustomHandler: "hintEdit",
}
LocaleKeyModuleFieldValidatorError = LocaleKey{
Name: "validatorError",
Resource: ModuleFieldResourceTranslationType,
Path: "expression.validator.{{validatorID}}.error",
CustomHandler: "validatorError",
}
LocaleKeyModuleFieldOptionsOptionTexts = LocaleKey{
Name: "optionsOptionTexts",
Resource: ModuleFieldResourceTranslationType,
Path: "meta.options.{{value}}.text",
CustomHandler: "optionsOptionTexts",
}
LocaleKeyModuleName = LocaleKey{
Name: "name",
Resource: ModuleResourceTranslationType,
Path: "name",
}
LocaleKeyNamespaceName = LocaleKey{
Name: "name",
Resource: NamespaceResourceTranslationType,
Path: "name",
}
LocaleKeyNamespaceSubtitle = LocaleKey{
Name: "subtitle",
Resource: NamespaceResourceTranslationType,
Path: "subtitle",
}
LocaleKeyNamespaceDescription = LocaleKey{
Name: "description",
Resource: NamespaceResourceTranslationType,
Path: "description",
}
LocaleKeyPageTitle = LocaleKey{
Name: "title",
Resource: PageResourceTranslationType,
Path: "title",
}
LocaleKeyPageDescription = LocaleKey{
Name: "description",
Resource: PageResourceTranslationType,
Path: "description",
}
LocaleKeyPageBlockTitle = LocaleKey{
Name: "blockTitle",
Resource: PageResourceTranslationType,
Path: "pageBlock.{{blockID}}.title",
}
LocaleKeyPageBlockDescription = LocaleKey{
Name: "blockDescription",
Resource: PageResourceTranslationType,
Path: "pageBlock.{{blockID}}.description",
}
LocaleKeyPageBlockAutomationButtonlabel = LocaleKey{
Name: "blockAutomationButtonlabel",
Resource: PageResourceTranslationType,
Path: "pageBlock.{{blockID}}.button.{{buttonID}}.label",
}
// @todo can we remove LocaleKey struct for string constant?
LocaleKeyModuleName = LocaleKey{Path: "name"}
LocaleKeyModuleFieldLabel = LocaleKey{Path: "label"}
LocaleKeyModuleFieldMetaDescriptionView = LocaleKey{Path: "meta.description.view"}
LocaleKeyModuleFieldMetaDescriptionEdit = LocaleKey{Path: "meta.description.edit"}
LocaleKeyModuleFieldMetaHintView = LocaleKey{Path: "meta.hint.view"}
LocaleKeyModuleFieldMetaHintEdit = LocaleKey{Path: "meta.hint.edit"}
LocaleKeyModuleFieldExpressionValidatorValidatorIDError = LocaleKey{Path: "expression.validator.{{validatorID}}.error"}
LocaleKeyModuleFieldMetaOptionsValueText = LocaleKey{Path: "meta.options.{{value}}.text"}
LocaleKeyNamespaceName = LocaleKey{Path: "name"}
LocaleKeyNamespaceMetaSubtitle = LocaleKey{Path: "meta.subtitle"}
LocaleKeyNamespaceMetaDescription = LocaleKey{Path: "meta.description"}
LocaleKeyPageTitle = LocaleKey{Path: "title"}
LocaleKeyPageDescription = LocaleKey{Path: "description"}
LocaleKeyPagePageBlockBlockIDTitle = LocaleKey{Path: "pageBlock.{{blockID}}.title"}
LocaleKeyPagePageBlockBlockIDDescription = LocaleKey{Path: "pageBlock.{{blockID}}.description"}
LocaleKeyPagePageBlockBlockIDButtonButtonIDLabel = LocaleKey{Path: "pageBlock.{{blockID}}.button.{{buttonID}}.label"}
)
// ResourceTranslation returns string representation of Locale resource for ModuleField by calling ModuleFieldResourceTranslation fn
//
// Locale resource is in "compose:module-field/..." format
//
// This function is auto-generated
func (r ModuleField) ResourceTranslation() string {
return ModuleFieldResourceTranslation(r.NamespaceID, r.ModuleID, r.ID)
}
// ModuleFieldResourceTranslation returns string representation of Locale resource for ModuleField
//
// Locale resource is in the compose:module-field/... format
//
// This function is auto-generated
func ModuleFieldResourceTranslation(namespaceID uint64, moduleID uint64, id uint64) string {
cpts := []interface{}{ModuleFieldResourceTranslationType}
cpts = append(cpts, strconv.FormatUint(namespaceID, 10), strconv.FormatUint(moduleID, 10), strconv.FormatUint(id, 10))
return fmt.Sprintf(ModuleFieldResourceTranslationTpl(), cpts...)
}
// @todo template
func ModuleFieldResourceTranslationTpl() string {
return "%s/%s/%s/%s"
}
func (r *ModuleField) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldLabel.Path); aux != nil {
r.Label = aux.Msg
}
r.decodeTranslationsDescriptionView(tt)
r.decodeTranslationsDescriptionEdit(tt)
r.decodeTranslationsHintView(tt)
r.decodeTranslationsHintEdit(tt)
r.decodeTranslationsValidatorError(tt)
r.decodeTranslationsOptionsOptionTexts(tt)
}
func (r *ModuleField) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if r.Label != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
Key: LocaleKeyModuleFieldLabel.Path,
Msg: locale.SanitizeMessage(r.Label),
})
}
out = append(out, r.encodeTranslationsDescriptionView()...)
out = append(out, r.encodeTranslationsDescriptionEdit()...)
out = append(out, r.encodeTranslationsHintView()...)
out = append(out, r.encodeTranslationsHintEdit()...)
out = append(out, r.encodeTranslationsValidatorError()...)
out = append(out, r.encodeTranslationsOptionsOptionTexts()...)
return out
}
// ResourceTranslation returns string representation of Locale resource for Module by calling ModuleResourceTranslation fn
//
// Locale resource is in "compose:module/..." format
//
// This function is auto-generated
func (r Module) ResourceTranslation() string {
return ModuleResourceTranslation(r.NamespaceID, r.ID)
return ModuleResourceTranslation(r.ID)
}
// ModuleResourceTranslation returns string representation of Locale resource for Module
@@ -197,29 +63,30 @@ func (r Module) ResourceTranslation() string {
// Locale resource is in the compose:module/... format
//
// This function is auto-generated
func ModuleResourceTranslation(namespaceID uint64, id uint64) string {
cpts := []interface{}{ModuleResourceTranslationType}
cpts = append(cpts, strconv.FormatUint(namespaceID, 10), strconv.FormatUint(id, 10))
func ModuleResourceTranslation(ID uint64) string {
cpts := []interface{}{
ModuleResourceTranslationType,
strconv.FormatUint(ID, 10),
}
return fmt.Sprintf(ModuleResourceTranslationTpl(), cpts...)
}
// @todo template
func ModuleResourceTranslationTpl() string {
return "%s/%s/%s"
return "%s/%s"
}
func (r *Module) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleName.Path); aux != nil {
r.Name = aux.Msg
}
r.decodeTranslations(tt)
}
func (r *Module) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if r.Name != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
@@ -228,7 +95,79 @@ func (r *Module) EncodeTranslations() (out locale.ResourceTranslationSet) {
})
}
out = append(out, r.encodeTranslations()...)
return out
}
// ResourceTranslation returns string representation of Locale resource for ModuleField by calling ModuleFieldResourceTranslation fn
//
// Locale resource is in "compose:module-field/..." format
//
// This function is auto-generated
func (r ModuleField) ResourceTranslation() string {
return ModuleFieldResourceTranslation(r.ID)
}
// ModuleFieldResourceTranslation returns string representation of Locale resource for ModuleField
//
// Locale resource is in the compose:module-field/... format
//
// This function is auto-generated
func ModuleFieldResourceTranslation(ID uint64) string {
cpts := []interface{}{
ModuleFieldResourceTranslationType,
strconv.FormatUint(ID, 10),
}
return fmt.Sprintf(ModuleFieldResourceTranslationTpl(), cpts...)
}
func ModuleFieldResourceTranslationTpl() string {
return "%s/%s"
}
func (r *ModuleField) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldLabel.Path); aux != nil {
r.Label = aux.Msg
}
r.decodeTranslationsMetaDescriptionView(tt)
r.decodeTranslationsMetaDescriptionEdit(tt)
r.decodeTranslationsMetaHintView(tt)
r.decodeTranslationsMetaHintEdit(tt)
r.decodeTranslationsExpressionValidatorValidatorIDError(tt)
r.decodeTranslationsMetaOptionsValueText(tt)
}
func (r *ModuleField) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if r.Label != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
Key: LocaleKeyModuleFieldLabel.Path,
Msg: locale.SanitizeMessage(r.Label),
})
}
out = append(out, r.encodeTranslationsMetaDescriptionView()...)
out = append(out, r.encodeTranslationsMetaDescriptionEdit()...)
out = append(out, r.encodeTranslationsMetaHintView()...)
out = append(out, r.encodeTranslationsMetaHintEdit()...)
out = append(out, r.encodeTranslationsExpressionValidatorValidatorIDError()...)
out = append(out, r.encodeTranslationsMetaOptionsValueText()...)
return out
}
@@ -247,33 +186,38 @@ func (r Namespace) ResourceTranslation() string {
// Locale resource is in the compose:namespace/... format
//
// This function is auto-generated
func NamespaceResourceTranslation(id uint64) string {
cpts := []interface{}{NamespaceResourceTranslationType}
cpts = append(cpts, strconv.FormatUint(id, 10))
func NamespaceResourceTranslation(ID uint64) string {
cpts := []interface{}{
NamespaceResourceTranslationType,
strconv.FormatUint(ID, 10),
}
return fmt.Sprintf(NamespaceResourceTranslationTpl(), cpts...)
}
// @todo template
func NamespaceResourceTranslationTpl() string {
return "%s/%s"
}
func (r *Namespace) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyNamespaceName.Path); aux != nil {
r.Name = aux.Msg
}
if aux = tt.FindByKey(LocaleKeyNamespaceSubtitle.Path); aux != nil {
if aux = tt.FindByKey(LocaleKeyNamespaceMetaSubtitle.Path); aux != nil {
r.Meta.Subtitle = aux.Msg
}
if aux = tt.FindByKey(LocaleKeyNamespaceDescription.Path); aux != nil {
if aux = tt.FindByKey(LocaleKeyNamespaceMetaDescription.Path); aux != nil {
r.Meta.Description = aux.Msg
}
}
func (r *Namespace) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if r.Name != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
@@ -281,17 +225,19 @@ func (r *Namespace) EncodeTranslations() (out locale.ResourceTranslationSet) {
Msg: locale.SanitizeMessage(r.Name),
})
}
if r.Meta.Subtitle != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
Key: LocaleKeyNamespaceSubtitle.Path,
Key: LocaleKeyNamespaceMetaSubtitle.Path,
Msg: locale.SanitizeMessage(r.Meta.Subtitle),
})
}
if r.Meta.Description != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
Key: LocaleKeyNamespaceDescription.Path,
Key: LocaleKeyNamespaceMetaDescription.Path,
Msg: locale.SanitizeMessage(r.Meta.Description),
})
}
@@ -305,7 +251,7 @@ func (r *Namespace) EncodeTranslations() (out locale.ResourceTranslationSet) {
//
// This function is auto-generated
func (r Page) ResourceTranslation() string {
return PageResourceTranslation(r.NamespaceID, r.ID)
return PageResourceTranslation(r.ID)
}
// PageResourceTranslation returns string representation of Locale resource for Page
@@ -313,23 +259,26 @@ func (r Page) ResourceTranslation() string {
// Locale resource is in the compose:page/... format
//
// This function is auto-generated
func PageResourceTranslation(namespaceID uint64, id uint64) string {
cpts := []interface{}{PageResourceTranslationType}
cpts = append(cpts, strconv.FormatUint(namespaceID, 10), strconv.FormatUint(id, 10))
func PageResourceTranslation(ID uint64) string {
cpts := []interface{}{
PageResourceTranslationType,
strconv.FormatUint(ID, 10),
}
return fmt.Sprintf(PageResourceTranslationTpl(), cpts...)
}
// @todo template
func PageResourceTranslationTpl() string {
return "%s/%s/%s"
return "%s/%s"
}
func (r *Page) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyPageTitle.Path); aux != nil {
r.Title = aux.Msg
}
if aux = tt.FindByKey(LocaleKeyPageDescription.Path); aux != nil {
r.Description = aux.Msg
}
@@ -339,6 +288,7 @@ func (r *Page) DecodeTranslations(tt locale.ResourceTranslationIndex) {
func (r *Page) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if r.Title != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
@@ -346,6 +296,7 @@ func (r *Page) EncodeTranslations() (out locale.ResourceTranslationSet) {
Msg: locale.SanitizeMessage(r.Title),
})
}
if r.Description != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
+24 -24
View File
@@ -56,7 +56,7 @@ var (
_ sort.Interface = &ModuleFieldSet{}
)
func (f *ModuleField) decodeTranslationsValidatorError(tt locale.ResourceTranslationIndex) {
func (f *ModuleField) decodeTranslationsExpressionValidatorValidatorIDError(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
for i, e := range f.Expressions.Validators {
@@ -65,40 +65,40 @@ func (f *ModuleField) decodeTranslationsValidatorError(tt locale.ResourceTransla
"{{validatorID}}", strconv.FormatUint(validatorID, 10),
)
if aux = tt.FindByKey(rpl.Replace(LocaleKeyModuleFieldValidatorError.Path)); aux != nil {
if aux = tt.FindByKey(rpl.Replace(LocaleKeyModuleFieldExpressionValidatorValidatorIDError.Path)); aux != nil {
f.Expressions.Validators[i].Error = aux.Msg
}
}
}
func (f *ModuleField) decodeTranslationsDescriptionView(tt locale.ResourceTranslationIndex) {
func (f *ModuleField) decodeTranslationsMetaDescriptionView(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldDescriptionView.Path); aux != nil {
if aux = tt.FindByKey(LocaleKeyModuleFieldMetaDescriptionView.Path); aux != nil {
f.setOptionKey(aux.Msg, "description", "edit")
}
}
func (f *ModuleField) decodeTranslationsDescriptionEdit(tt locale.ResourceTranslationIndex) {
func (f *ModuleField) decodeTranslationsMetaDescriptionEdit(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldDescriptionEdit.Path); aux != nil {
if aux = tt.FindByKey(LocaleKeyModuleFieldMetaDescriptionEdit.Path); aux != nil {
f.setOptionKey(aux.Msg, "description", "view")
}
}
func (f *ModuleField) decodeTranslationsHintView(tt locale.ResourceTranslationIndex) {
func (f *ModuleField) decodeTranslationsMetaHintView(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldHintView.Path); aux != nil {
if aux = tt.FindByKey(LocaleKeyModuleFieldMetaHintView.Path); aux != nil {
f.setOptionKey(aux.Msg, "hint", "edit")
}
}
func (f *ModuleField) decodeTranslationsHintEdit(tt locale.ResourceTranslationIndex) {
func (f *ModuleField) decodeTranslationsMetaHintEdit(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
if aux = tt.FindByKey(LocaleKeyModuleFieldHintEdit.Path); aux != nil {
if aux = tt.FindByKey(LocaleKeyModuleFieldMetaHintEdit.Path); aux != nil {
f.setOptionKey(aux.Msg, "hint", "view")
}
}
@@ -106,7 +106,7 @@ func (f *ModuleField) decodeTranslationsHintEdit(tt locale.ResourceTranslationIn
// Decodes translations and modifies options
//
// Why "options-option-texts"? Because we're translating option txts under options key-value
func (f *ModuleField) decodeTranslationsOptionsOptionTexts(tt locale.ResourceTranslationIndex) {
func (f *ModuleField) decodeTranslationsMetaOptionsValueText(tt locale.ResourceTranslationIndex) {
var (
tr *locale.ResourceTranslation
)
@@ -145,7 +145,7 @@ func (f *ModuleField) decodeTranslationsOptionsOptionTexts(tt locale.ResourceTra
// find the translation for that value
// and update the option (effectively overwriting
// the original text value (in case of map option)
trKey := strings.NewReplacer("{{value}}", outOpt["value"]).Replace(LocaleKeyModuleFieldOptionsOptionTexts.Path)
trKey := strings.NewReplacer("{{value}}", outOpt["value"]).Replace(LocaleKeyModuleFieldMetaOptionsValueText.Path)
if tr = tt.FindByKey(trKey); tr != nil {
outOpt["text"] = tr.Msg
}
@@ -155,7 +155,7 @@ func (f *ModuleField) decodeTranslationsOptionsOptionTexts(tt locale.ResourceTra
}
}
func (m *ModuleField) encodeTranslationsValidatorError() (out locale.ResourceTranslationSet) {
func (m *ModuleField) encodeTranslationsExpressionValidatorValidatorIDError() (out locale.ResourceTranslationSet) {
out = make(locale.ResourceTranslationSet, 0, 3)
// Module field expressions
@@ -167,7 +167,7 @@ func (m *ModuleField) encodeTranslationsValidatorError() (out locale.ResourceTra
out = append(out, &locale.ResourceTranslation{
Resource: m.ResourceTranslation(),
Key: rpl.Replace(LocaleKeyModuleFieldValidatorError.Path),
Key: rpl.Replace(LocaleKeyModuleFieldExpressionValidatorValidatorIDError.Path),
Msg: e.Error,
})
}
@@ -175,53 +175,53 @@ func (m *ModuleField) encodeTranslationsValidatorError() (out locale.ResourceTra
return
}
func (f *ModuleField) encodeTranslationsDescriptionView() (out locale.ResourceTranslationSet) {
func (f *ModuleField) encodeTranslationsMetaDescriptionView() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if v := f.getOptionKey("description", "edit"); v != nil {
aux := cast.ToString(v)
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldDescriptionView.Path,
Key: LocaleKeyModuleFieldMetaDescriptionView.Path,
Msg: aux,
})
}
return out
}
func (f *ModuleField) encodeTranslationsDescriptionEdit() (out locale.ResourceTranslationSet) {
func (f *ModuleField) encodeTranslationsMetaDescriptionEdit() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if v := f.getOptionKey("description", "view"); v != nil {
aux := cast.ToString(v)
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldDescriptionEdit.Path,
Key: LocaleKeyModuleFieldMetaDescriptionEdit.Path,
Msg: aux,
})
}
return out
}
func (f *ModuleField) encodeTranslationsHintView() (out locale.ResourceTranslationSet) {
func (f *ModuleField) encodeTranslationsMetaHintView() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if v := f.getOptionKey("hint", "edit"); v != nil {
aux := cast.ToString(v)
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldHintView.Path,
Key: LocaleKeyModuleFieldMetaHintView.Path,
Msg: aux,
})
}
return out
}
func (f *ModuleField) encodeTranslationsHintEdit() (out locale.ResourceTranslationSet) {
func (f *ModuleField) encodeTranslationsMetaHintEdit() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
if v := f.getOptionKey("hint", "view"); v != nil {
aux := cast.ToString(v)
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: LocaleKeyModuleFieldHintEdit.Path,
Key: LocaleKeyModuleFieldMetaHintEdit.Path,
Msg: aux,
})
}
@@ -229,7 +229,7 @@ func (f *ModuleField) encodeTranslationsHintEdit() (out locale.ResourceTranslati
}
// extracts option texts and converts (encodes) them to translations
func (f *ModuleField) encodeTranslationsOptionsOptionTexts() (out locale.ResourceTranslationSet) {
func (f *ModuleField) encodeTranslationsMetaOptionsValueText() (out locale.ResourceTranslationSet) {
out = make(locale.ResourceTranslationSet, 0, 3)
optsUnknown, has := f.Options["options"]
@@ -252,7 +252,7 @@ func (f *ModuleField) encodeTranslationsOptionsOptionTexts() (out locale.Resourc
out = append(out, &locale.ResourceTranslation{
Resource: f.ResourceTranslation(),
Key: strings.NewReplacer("{{value}}", value).
Replace(LocaleKeyModuleFieldOptionsOptionTexts.Path),
Replace(LocaleKeyModuleFieldMetaOptionsValueText.Path),
Msg: text,
})
}
+1 -1
View File
@@ -68,7 +68,7 @@ func TestModuleField_decodeTranslationsOptionsOptionTexts(t *testing.T) {
f = &ModuleField{Options: tt.opts}
)
f.decodeTranslationsOptionsOptionTexts(rti)
f.decodeTranslationsMetaOptionsValueText(rti)
if tt.out != nil {
req.Equal(tt.out, f.Options["options"])
-1
View File
@@ -6,7 +6,6 @@ import (
"time"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/pkg/errors"
)
+6 -6
View File
@@ -124,10 +124,10 @@ func (p *Page) decodeTranslations(tt locale.ResourceTranslationIndex) {
)
// - generic page block stuff
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPageBlockTitle.Path)); aux != nil {
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPagePageBlockBlockIDTitle.Path)); aux != nil {
p.Blocks[i].Title = aux.Msg
}
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPageBlockDescription.Path)); aux != nil {
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPagePageBlockBlockIDDescription.Path)); aux != nil {
p.Blocks[i].Description = aux.Msg
}
@@ -148,7 +148,7 @@ func (p *Page) decodeTranslations(tt locale.ResourceTranslationIndex) {
"{{buttonID}}", strconv.FormatUint(buttonID, 10),
)
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPageBlockAutomationButtonlabel.Path)); aux != nil {
if aux = tt.FindByKey(rpl.Replace(LocaleKeyPagePageBlockBlockIDButtonButtonIDLabel.Path)); aux != nil {
btn["label"] = aux.Msg
}
}
@@ -169,13 +169,13 @@ func (p *Page) encodeTranslations() (out locale.ResourceTranslationSet) {
// - generic page block stuff
out = append(out, &locale.ResourceTranslation{
Resource: p.ResourceTranslation(),
Key: rpl.Replace(LocaleKeyPageBlockTitle.Path),
Key: rpl.Replace(LocaleKeyPagePageBlockBlockIDTitle.Path),
Msg: block.Title,
})
out = append(out, &locale.ResourceTranslation{
Resource: p.ResourceTranslation(),
Key: rpl.Replace(LocaleKeyPageBlockDescription.Path),
Key: rpl.Replace(LocaleKeyPagePageBlockBlockIDDescription.Path),
Msg: block.Description,
})
@@ -202,7 +202,7 @@ func (p *Page) encodeTranslations() (out locale.ResourceTranslationSet) {
out = append(out, &locale.ResourceTranslation{
Resource: p.ResourceTranslation(),
Key: rpl.Replace(LocaleKeyPageBlockAutomationButtonlabel.Path),
Key: rpl.Replace(LocaleKeyPagePageBlockBlockIDButtonButtonIDLabel.Path),
Msg: btn["label"].(string),
})
}
+70 -77
View File
@@ -24,43 +24,49 @@ var (
)
const (
NamespaceResourceType = "corteza::compose:namespace"
ChartResourceType = "corteza::compose:chart"
ModuleResourceType = "corteza::compose:module"
ModuleFieldResourceType = "corteza::compose:module-field"
RecordResourceType = "corteza::compose:record"
NamespaceResourceType = "corteza::compose:namespace"
PageResourceType = "corteza::compose:page"
ChartResourceType = "corteza::compose:chart"
RecordResourceType = "corteza::compose:record"
ComponentResourceType = "corteza::compose"
)
// RbacResource returns string representation of RBAC resource for Namespace by calling NamespaceRbacResource fn
// RbacResource returns string representation of RBAC resource for Chart by calling ChartRbacResource fn
//
// RBAC resource is in the corteza::compose:namespace/... format
// RBAC resource is in the corteza::compose:chart/... format
//
// This function is auto-generated
func (r Namespace) RbacResource() string {
return NamespaceRbacResource(r.ID)
func (r Chart) RbacResource() string {
return ChartRbacResource(r.NamespaceID, r.ID)
}
// NamespaceRbacResource returns string representation of RBAC resource for Namespace
// ChartRbacResource returns string representation of RBAC resource for Chart
//
// RBAC resource is in the corteza::compose:namespace/... format
// RBAC resource is in the corteza::compose:chart/... format
//
// This function is auto-generated
func NamespaceRbacResource(ID uint64) string {
cpts := []interface{}{NamespaceResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
func ChartRbacResource(namespaceID uint64, id uint64) string {
cpts := []interface{}{ChartResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(NamespaceRbacResourceTpl(), cpts...)
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ChartRbacResourceTpl(), cpts...)
}
func NamespaceRbacResourceTpl() string {
return "%s/%s"
func ChartRbacResourceTpl() string {
return "%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Module by calling ModuleRbacResource fn
@@ -77,16 +83,16 @@ func (r Module) RbacResource() string {
// RBAC resource is in the corteza::compose:module/... format
//
// This function is auto-generated
func ModuleRbacResource(NamespaceID uint64, ID uint64) string {
func ModuleRbacResource(namespaceID uint64, id uint64) string {
cpts := []interface{}{ModuleResourceType}
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 ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
} else {
cpts = append(cpts, "*")
}
@@ -113,22 +119,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, "*")
}
@@ -141,46 +147,27 @@ func ModuleFieldRbacResourceTpl() string {
return "%s/%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Record by calling RecordRbacResource fn
// RbacResource returns string representation of RBAC resource for Namespace by calling NamespaceRbacResource fn
//
// RBAC resource is in the corteza::compose:record/... format
// RBAC resource is in the corteza::compose:namespace/... format
//
// This function is auto-generated
func (r Record) RbacResource() string {
return RecordRbacResource(r.NamespaceID, r.ModuleID, r.ID)
func (r Namespace) RbacResource() string {
return NamespaceRbacResource()
}
// RecordRbacResource returns string representation of RBAC resource for Record
// NamespaceRbacResource returns string representation of RBAC resource for Namespace
//
// RBAC resource is in the corteza::compose:record/... format
// RBAC resource is in the corteza::compose:namespace/ format
//
// This function is auto-generated
func RecordRbacResource(NamespaceID uint64, ModuleID uint64, ID uint64) string {
cpts := []interface{}{RecordResourceType}
if NamespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(NamespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if ModuleID != 0 {
cpts = append(cpts, strconv.FormatUint(ModuleID, 10))
} else {
cpts = append(cpts, "*")
}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(RecordRbacResourceTpl(), cpts...)
func NamespaceRbacResource() string {
return NamespaceResourceType + "/"
}
func RecordRbacResourceTpl() string {
return "%s/%s/%s/%s"
func NamespaceRbacResourceTpl() string {
return "%s"
}
// RbacResource returns string representation of RBAC resource for Page by calling PageRbacResource fn
@@ -197,16 +184,16 @@ func (r Page) RbacResource() string {
// RBAC resource is in the corteza::compose:page/... format
//
// This function is auto-generated
func PageRbacResource(NamespaceID uint64, ID uint64) string {
func PageRbacResource(namespaceID uint64, id uint64) string {
cpts := []interface{}{PageResourceType}
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 ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
if id != 0 {
cpts = append(cpts, strconv.FormatUint(id, 10))
} else {
cpts = append(cpts, "*")
}
@@ -219,40 +206,46 @@ func PageRbacResourceTpl() string {
return "%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Chart by calling ChartRbacResource fn
// RbacResource returns string representation of RBAC resource for Record by calling RecordRbacResource fn
//
// RBAC resource is in the corteza::compose:chart/... format
// RBAC resource is in the corteza::compose:record/... format
//
// This function is auto-generated
func (r Chart) RbacResource() string {
return ChartRbacResource(r.NamespaceID, r.ID)
func (r Record) RbacResource() string {
return RecordRbacResource(r.NamespaceID, r.ModuleID, r.ID)
}
// ChartRbacResource returns string representation of RBAC resource for Chart
// RecordRbacResource returns string representation of RBAC resource for Record
//
// RBAC resource is in the corteza::compose:chart/... format
// RBAC resource is in the corteza::compose:record/... 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 RecordRbacResource(namespaceID uint64, moduleID uint64, id uint64) string {
cpts := []interface{}{RecordResourceType}
if namespaceID != 0 {
cpts = append(cpts, strconv.FormatUint(namespaceID, 10))
} else {
cpts = append(cpts, "*")
}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
if moduleID != 0 {
cpts = append(cpts, strconv.FormatUint(moduleID, 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(RecordRbacResourceTpl(), cpts...)
}
func ChartRbacResourceTpl() string {
return "%s/%s/%s"
func RecordRbacResourceTpl() string {
return "%s/%s/%s/%s"
}
// RbacResource returns string representation of RBAC resource for Component by calling ComponentRbacResource fn
+8 -7
View File
@@ -4,23 +4,24 @@ import (
"strings"
)
#component: {
ident: #baseHandle
expIdent: #expIdent | *strings.ToTitle(ident)
#component: #_base & {
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
label: strings.ToTitle(ident)
platform: #baseHandle
resources: {
[key=_]: {handle: key, "component": ident, "platform": platform} & #resource
[key=_]: {"handle": key, "component": handle, "platform": platform} & #resource
}
fqrn: platform + "::" + handle
// All known RBAC operations for this component
rbac: #rbacComponent & {
resource: type: platform + "::" + ident
operations: {
grant: {
description: "Manage \(ident) permissions"
description: "Manage \(handle) permissions"
}
}
}
+33 -4
View File
@@ -1,29 +1,58 @@
package schema
import (
// "strings"
"strings"
"list"
)
#locale: {
resourceExpIdent: #expIdent
// @todo we need a better name here!
skipSvc: bool | *false
extended: bool | *false
resource: {
// @todo merge with RBAC res-ref and move 2 levels lower.
references: [ ...string] | *["ID"]
type: string
const: string | *("\(resourceExpIdent)ResourceTranslationType")
}
keys: {
[key=_]: #localeKey & {
name: key
_resourceExpIdent: resourceExpIdent
}
}
}
#localeKey: {
name: #handle
path: string | *(name)
custom?: true
customHandler?: string
_resourceExpIdent: #expIdent
path: [...(#ident | { part: #ident, var: bool | *false })] | *([name])
expandedPath: [for p in path {
if (p & { "p": #ident }) != _|_ { p, var: p.var }
if (p & string) != _|_ { "part": p, var: false }
}]
_suffix: strings.Join([for p in expandedPath { strings.ToTitle(p.part) }], "")
struct: string | *("LocaleKey" + _resourceExpIdent + _suffix)
// As soon as we use vars in the path,
// custom handler must be present
_hasVars: list.Contains([for p in path { p.var | false }], true)
customHandler: bool | *_hasVars
if customHandler {
decodeFunc: string | *("decodeTranslations" + _suffix)
encodeFunc: string | *("encodeTranslations" + _suffix)
serviceFunc: string | *("handle" + _resourceExpIdent + _suffix)
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
package schema
#platform: {
ident: #baseHandle
ident: #baseHandle | *"corteza"
components: [...{platform: ident} & #component]
+11 -16
View File
@@ -10,32 +10,27 @@ import (
}
operations: {
[key=_]: #rbacOperation & {handle: key}
[key=_]: #rbacOperation & {
handle: key
}
}
}
#rbacResource: {
resource: {
type: string
expIdent: #expIdent
references: [ ...string] | *["ID"]
}
resourceExpIdent: #expIdent
operations: {
[key=_]: #rbacOperation & {
handle: key
resourceExpIdent: resource.expIdent
description: string | *(strings.ToTitle(key) + " " + resource.type)
_resourceExpIdent: resourceExpIdent
}
}
}
#rbacOperation: {
handle: #handle
description: string
resourceExpIdent?: string
_isComponent: resourceExpIdent == _|_
handle: #handle
description: string | *handle
_resourceExpIdent?: string
// Some string manipulation that will result in
// more pronouncable access-control check function name
@@ -51,11 +46,11 @@ import (
_opFlip: [_opSplit[len(_opSplit)-1]] + _opSplit[0:len(_opSplit)-1]
_opFinal: strings.Replace(strings.ToTitle(strings.Join(_opFlip, " ")), " ", "", -1)
if _isComponent {
if _resourceExpIdent == _|_ {
checkFuncName: #expIdent | *("Can" + _opFinal)
}
if !_isComponent {
checkFuncName: #expIdent | *("Can" + _opFinal + resourceExpIdent)
if _resourceExpIdent != _|_ {
checkFuncName: #expIdent | *("Can" + _opFinal + _resourceExpIdent)
}
}
+61 -55
View File
@@ -1,32 +1,38 @@
package schema
import (
"strings"
)
#resource: #_base & {
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
#resource: {
handle: #baseHandle | *"unknown-resource"
component: #baseHandle | *"component"
platform: #baseHandle | *"corteza"
_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 parent resources
parents: [... #_base & {
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
refField: #expIdent | *(expIdent + "ID")
param: #ident | *(ident + "ID")
}]
// All known RBAC operations for this resource
rbac: #rbacResource & {
resourceExpIdent: expIdent
}
locale?: #locale & {
resourceExpIdent: expIdent
resource: {
type: fqrn
"expIdent": expIdent
// @todo can we merge this with RBAC type (FQRN?)
type: component + ":" + handle
}
}
@@ -40,25 +46,25 @@ import (
// }
}
#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"
}
}
//#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
@@ -70,24 +76,24 @@ import (
// 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
}
//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
//}
+21 -2
View File
@@ -1,10 +1,14 @@
package schema
// Resource definition identifier
import (
"strings"
)
// Identifier
#ident: =~"^[a-z][a-zA-Z0-9_]*$"
// Exported identifier
#expIdent: =~"^[A-Z][a-zA-Z0-9]*$"
#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]+$"
@@ -12,3 +16,18 @@ package schema
// More liberal then identifier, allows underscores and dots
#baseHandle: =~"^[a-z][a-z0-9-]*[a-z0-9]+$"
#_base: {
// lowercase dash-separated words
// used to build ident and exported identifiers
handle: #baseHandle | *"base"
_words: strings.Replace(strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1), ".", " ", -1)
// lowercased (unexported, golang) identifier
ident: #ident | *strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
// upercased (exported, golang) identifier
expIdent: #expIdent | *strings.Replace(strings.ToTitle(_words), " ", "", -1)
...
}
@@ -1,135 +0,0 @@
package {{ .Package }}
{{ template "header-gentext.tpl" }}
{{ template "header-definitions.tpl" . }}
import (
"fmt"
"strconv"
"github.com/cortezaproject/corteza-server/pkg/locale"
)
type (
LocaleKey struct {
Name string
Resource string
Path string
CustomHandler string
}
)
// Types and stuff
const (
{{- range .Def }}
{{ .Resource }}ResourceTranslationType = "{{ .Locale.ResourceType }}"
{{- end }}
)
var (
{{- range .Def }}
{{- $Resource := .Resource }}
{{- range .Locale.Keys}}
LocaleKey{{ $Resource }}{{coalesce (export .Name) (export .Path) }} = LocaleKey{
Name: "{{.Name}}",
Resource: {{ $Resource }}ResourceTranslationType,
Path: "{{.Path }}",{{ if .CustomHandler }}
CustomHandler: "{{ .CustomHandler }}",
{{- end }}
}
{{- end}}
{{- end }}
)
{{- range .Def }}
{{ $Resource := .Resource }}
{{ $GoType := printf "types.%s" .Resource }}
// ResourceTranslation returns string representation of Locale resource for {{ .Resource }} by calling {{ .Resource }}ResourceTranslation fn
//
// Locale resource is in "{{ .Locale.ResourceType }}/..." format
//
// This function is auto-generated
func (r {{ .Resource }}) ResourceTranslation() string {
return {{ .Resource }}ResourceTranslation({{ if .Locale.Resource }}{{ range .Locale.Resource.References }}r.{{ export .Field }},{{ end }}{{ end }})
}
// {{ .Resource }}ResourceTranslation returns string representation of Locale resource for {{ .Resource }}
//
// Locale resource is in the {{ .Locale.ResourceType }}/{{- if .Locale.Resource.References }}...{{ end }} format
//
// This function is auto-generated
func {{ .Resource }}ResourceTranslation({{ if .Locale.Resource }}{{ range .Locale.Resource.References }}{{ unexport .Field }} uint64,{{ end }}{{ end }}) string {
{{- if .Locale.Resource.References }}
cpts := []interface{{"{}"}}{{"{"}}{{ .Resource }}ResourceTranslationType{{"}"}}
cpts = append(cpts, {{range .Locale.Resource.References -}}
strconv.FormatUint({{ unexport .Field }}, 10),
{{- end }})
return fmt.Sprintf({{ .Resource }}ResourceTranslationTpl(), cpts...)
{{- end }}
}
// @todo template
func {{ .Resource }}ResourceTranslationTpl() string {
{{- if .Locale.Resource.References }}
return "%s
{{- range .Locale.Resource.References }}/%s{{- end }}"
{{- else }}
return "%s"
{{- end }}
}
func (r *{{ .Resource }}) DecodeTranslations(tt locale.ResourceTranslationIndex) {
var aux *locale.ResourceTranslation
{{- range .Locale.Keys}}
{{- if not .Custom }}
if aux = tt.FindByKey(LocaleKey{{ $Resource }}{{coalesce (export .Name) (export .Path) }}.Path); aux != nil {
r.{{ .Field }} = aux.Msg
}
{{- end}}
{{- end}}
{{- range .Locale.Keys}}
{{- if and .Custom .CustomHandler }}
r.decodeTranslations{{export .CustomHandler }}(tt)
{{- end}}
{{- end}}
{{- if .Locale.Extended }}
r.decodeTranslations(tt)
{{- end }}
}
func (r *{{ .Resource }}) EncodeTranslations() (out locale.ResourceTranslationSet) {
out = locale.ResourceTranslationSet{}
{{- range .Locale.Keys}}
{{- if not .Custom }}
if r.{{ .Field }} != "" {
out = append(out, &locale.ResourceTranslation{
Resource: r.ResourceTranslation(),
Key: LocaleKey{{ $Resource }}{{coalesce (export .Name) (export .Path) }}.Path,
Msg: locale.SanitizeMessage(r.{{ .Field }}),
})
}
{{- end}}
{{- end}}
{{range .Locale.Keys}}
{{- if and .Custom .CustomHandler }}
out = append(out, r.encodeTranslations{{export .CustomHandler}}()...)
{{- end}}
{{- end}}
{{- if .Locale.Extended }}
out = append(out, r.encodeTranslations()...)
{{- end }}
return out
}
{{- end }}
+1 -1
View File
@@ -5,7 +5,7 @@ import (
)
component: schema.#component & {
ident: "system"
handle: "system"
resources: {
"apigw-route": apigwRoute
+36 -220
View File
@@ -56,182 +56,182 @@ func (svc accessControl) List() (out []map[string]string) {
def := []map[string]string{
{
"type": types.ApigwRouteResourceType,
"any": types.ApigwRouteRbacResource(0),
"any": types.ApigwRouteRbacResource(),
"op": "read",
},
{
"type": types.ApigwRouteResourceType,
"any": types.ApigwRouteRbacResource(0),
"any": types.ApigwRouteRbacResource(),
"op": "update",
},
{
"type": types.ApigwRouteResourceType,
"any": types.ApigwRouteRbacResource(0),
"any": types.ApigwRouteRbacResource(),
"op": "delete",
},
{
"type": types.ApplicationResourceType,
"any": types.ApplicationRbacResource(0),
"any": types.ApplicationRbacResource(),
"op": "read",
},
{
"type": types.ApplicationResourceType,
"any": types.ApplicationRbacResource(0),
"any": types.ApplicationRbacResource(),
"op": "update",
},
{
"type": types.ApplicationResourceType,
"any": types.ApplicationRbacResource(0),
"any": types.ApplicationRbacResource(),
"op": "delete",
},
{
"type": types.AuthClientResourceType,
"any": types.AuthClientRbacResource(0),
"any": types.AuthClientRbacResource(),
"op": "read",
},
{
"type": types.AuthClientResourceType,
"any": types.AuthClientRbacResource(0),
"any": types.AuthClientRbacResource(),
"op": "update",
},
{
"type": types.AuthClientResourceType,
"any": types.AuthClientRbacResource(0),
"any": types.AuthClientRbacResource(),
"op": "delete",
},
{
"type": types.AuthClientResourceType,
"any": types.AuthClientRbacResource(0),
"any": types.AuthClientRbacResource(),
"op": "authorize",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"any": types.QueueRbacResource(),
"op": "render",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"any": types.QueueRbacResource(),
"op": "read",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"any": types.QueueRbacResource(),
"op": "update",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"any": types.QueueRbacResource(),
"op": "delete",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"any": types.QueueRbacResource(),
"op": "queue.read",
},
{
"type": types.QueueResourceType,
"any": types.QueueRbacResource(0),
"any": types.QueueRbacResource(),
"op": "queue.write",
},
{
"type": types.ReportResourceType,
"any": types.ReportRbacResource(0),
"any": types.ReportRbacResource(),
"op": "read",
},
{
"type": types.ReportResourceType,
"any": types.ReportRbacResource(0),
"any": types.ReportRbacResource(),
"op": "update",
},
{
"type": types.ReportResourceType,
"any": types.ReportRbacResource(0),
"any": types.ReportRbacResource(),
"op": "delete",
},
{
"type": types.ReportResourceType,
"any": types.ReportRbacResource(0),
"any": types.ReportRbacResource(),
"op": "run",
},
{
"type": types.RoleResourceType,
"any": types.RoleRbacResource(0),
"any": types.RoleRbacResource(),
"op": "read",
},
{
"type": types.RoleResourceType,
"any": types.RoleRbacResource(0),
"any": types.RoleRbacResource(),
"op": "update",
},
{
"type": types.RoleResourceType,
"any": types.RoleRbacResource(0),
"any": types.RoleRbacResource(),
"op": "delete",
},
{
"type": types.RoleResourceType,
"any": types.RoleRbacResource(0),
"any": types.RoleRbacResource(),
"op": "members.manage",
},
{
"type": types.TemplateResourceType,
"any": types.TemplateRbacResource(0),
"any": types.TemplateRbacResource(),
"op": "read",
},
{
"type": types.TemplateResourceType,
"any": types.TemplateRbacResource(0),
"any": types.TemplateRbacResource(),
"op": "update",
},
{
"type": types.TemplateResourceType,
"any": types.TemplateRbacResource(0),
"any": types.TemplateRbacResource(),
"op": "delete",
},
{
"type": types.TemplateResourceType,
"any": types.TemplateRbacResource(0),
"any": types.TemplateRbacResource(),
"op": "render",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "read",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "update",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "delete",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "suspend",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "unsuspend",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "email.unmask",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "name.unmask",
},
{
"type": types.UserResourceType,
"any": types.UserRbacResource(0),
"any": types.UserRbacResource(),
"op": "impersonate",
},
{
@@ -1014,29 +1014,6 @@ func rbacApigwRouteResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ApigwRouteResourceType):], 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 apigwRoute resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1058,29 +1035,6 @@ func rbacApplicationResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ApplicationResourceType):], 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 application resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1102,29 +1056,6 @@ func rbacAuthClientResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.AuthClientResourceType):], 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 authClient resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1146,29 +1077,6 @@ func rbacQueueResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.QueueResourceType):], 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 queue resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1190,29 +1098,6 @@ func rbacReportResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.ReportResourceType):], 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 report resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1234,29 +1119,6 @@ func rbacRoleResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.RoleResourceType):], 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 role resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1278,29 +1140,6 @@ func rbacTemplateResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.TemplateResourceType):], 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 template resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
@@ -1322,29 +1161,6 @@ func rbacUserResourceValidator(r string, oo ...string) error {
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.UserResourceType):], 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 user resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
+40 -96
View File
@@ -41,28 +41,21 @@ const (
//
// This function is auto-generated
func (r ApigwRoute) RbacResource() string {
return ApigwRouteRbacResource(r.ID)
return ApigwRouteRbacResource()
}
// ApigwRouteRbacResource returns string representation of RBAC resource for ApigwRoute
//
// RBAC resource is in the corteza::system:apigw-route/... format
// RBAC resource is in the corteza::system:apigw-route/ format
//
// This function is auto-generated
func ApigwRouteRbacResource(ID uint64) string {
cpts := []interface{}{ApigwRouteResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ApigwRouteRbacResourceTpl(), cpts...)
func ApigwRouteRbacResource() string {
return ApigwRouteResourceType + "/"
}
func ApigwRouteRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for Application by calling ApplicationRbacResource fn
@@ -71,28 +64,21 @@ func ApigwRouteRbacResourceTpl() string {
//
// This function is auto-generated
func (r Application) RbacResource() string {
return ApplicationRbacResource(r.ID)
return ApplicationRbacResource()
}
// ApplicationRbacResource returns string representation of RBAC resource for Application
//
// RBAC resource is in the corteza::system:application/... format
// RBAC resource is in the corteza::system:application/ format
//
// This function is auto-generated
func ApplicationRbacResource(ID uint64) string {
cpts := []interface{}{ApplicationResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ApplicationRbacResourceTpl(), cpts...)
func ApplicationRbacResource() string {
return ApplicationResourceType + "/"
}
func ApplicationRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for AuthClient by calling AuthClientRbacResource fn
@@ -101,28 +87,21 @@ func ApplicationRbacResourceTpl() string {
//
// This function is auto-generated
func (r AuthClient) RbacResource() string {
return AuthClientRbacResource(r.ID)
return AuthClientRbacResource()
}
// AuthClientRbacResource returns string representation of RBAC resource for AuthClient
//
// RBAC resource is in the corteza::system:auth-client/... format
// RBAC resource is in the corteza::system:auth-client/ format
//
// This function is auto-generated
func AuthClientRbacResource(ID uint64) string {
cpts := []interface{}{AuthClientResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(AuthClientRbacResourceTpl(), cpts...)
func AuthClientRbacResource() string {
return AuthClientResourceType + "/"
}
func AuthClientRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for Queue by calling QueueRbacResource fn
@@ -131,28 +110,21 @@ func AuthClientRbacResourceTpl() string {
//
// This function is auto-generated
func (r Queue) RbacResource() string {
return QueueRbacResource(r.ID)
return QueueRbacResource()
}
// QueueRbacResource returns string representation of RBAC resource for Queue
//
// RBAC resource is in the corteza::system:queue/... format
// RBAC resource is in the corteza::system:queue/ format
//
// This function is auto-generated
func QueueRbacResource(ID uint64) string {
cpts := []interface{}{QueueResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(QueueRbacResourceTpl(), cpts...)
func QueueRbacResource() string {
return QueueResourceType + "/"
}
func QueueRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for Report by calling ReportRbacResource fn
@@ -161,28 +133,21 @@ func QueueRbacResourceTpl() string {
//
// This function is auto-generated
func (r Report) RbacResource() string {
return ReportRbacResource(r.ID)
return ReportRbacResource()
}
// ReportRbacResource returns string representation of RBAC resource for Report
//
// RBAC resource is in the corteza::system:report/... format
// RBAC resource is in the corteza::system:report/ format
//
// This function is auto-generated
func ReportRbacResource(ID uint64) string {
cpts := []interface{}{ReportResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(ReportRbacResourceTpl(), cpts...)
func ReportRbacResource() string {
return ReportResourceType + "/"
}
func ReportRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for Role by calling RoleRbacResource fn
@@ -191,28 +156,21 @@ func ReportRbacResourceTpl() string {
//
// This function is auto-generated
func (r Role) RbacResource() string {
return RoleRbacResource(r.ID)
return RoleRbacResource()
}
// RoleRbacResource returns string representation of RBAC resource for Role
//
// RBAC resource is in the corteza::system:role/... format
// RBAC resource is in the corteza::system:role/ format
//
// This function is auto-generated
func RoleRbacResource(ID uint64) string {
cpts := []interface{}{RoleResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(RoleRbacResourceTpl(), cpts...)
func RoleRbacResource() string {
return RoleResourceType + "/"
}
func RoleRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for Template by calling TemplateRbacResource fn
@@ -221,28 +179,21 @@ func RoleRbacResourceTpl() string {
//
// This function is auto-generated
func (r Template) RbacResource() string {
return TemplateRbacResource(r.ID)
return TemplateRbacResource()
}
// TemplateRbacResource returns string representation of RBAC resource for Template
//
// RBAC resource is in the corteza::system:template/... format
// RBAC resource is in the corteza::system:template/ format
//
// This function is auto-generated
func TemplateRbacResource(ID uint64) string {
cpts := []interface{}{TemplateResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(TemplateRbacResourceTpl(), cpts...)
func TemplateRbacResource() string {
return TemplateResourceType + "/"
}
func TemplateRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for User by calling UserRbacResource fn
@@ -251,28 +202,21 @@ func TemplateRbacResourceTpl() string {
//
// This function is auto-generated
func (r User) RbacResource() string {
return UserRbacResource(r.ID)
return UserRbacResource()
}
// UserRbacResource returns string representation of RBAC resource for User
//
// RBAC resource is in the corteza::system:user/... format
// RBAC resource is in the corteza::system:user/ format
//
// This function is auto-generated
func UserRbacResource(ID uint64) string {
cpts := []interface{}{UserResourceType}
if ID != 0 {
cpts = append(cpts, strconv.FormatUint(ID, 10))
} else {
cpts = append(cpts, "*")
}
return fmt.Sprintf(UserRbacResourceTpl(), cpts...)
func UserRbacResource() string {
return UserResourceType + "/"
}
func UserRbacResourceTpl() string {
return "%s/%s"
return "%s"
}
// RbacResource returns string representation of RBAC resource for Component by calling ComponentRbacResource fn