3
0

Implement access control for resource translation management

This commit is contained in:
Denis Arh
2021-09-18 07:04:56 +02:00
committed by Tomaž Jerman
parent f58384d95f
commit 948e587ed9
14 changed files with 153 additions and 71 deletions

View File

@@ -117,6 +117,11 @@ func (svc accessControl) List() (out []map[string]string) {
"any": types.ComponentRbacResource(), "any": types.ComponentRbacResource(),
"op": "workflows.search", "op": "workflows.search",
}, },
{
"type": types.ComponentResourceType,
"any": types.ComponentRbacResource(),
"op": "resource-translations.manage",
},
} }
func(svc interface{}) { func(svc interface{}) {
@@ -263,6 +268,13 @@ func (svc accessControl) CanSearchWorkflows(ctx context.Context) bool {
return svc.can(ctx, "workflows.search", &types.Component{}) return svc.can(ctx, "workflows.search", &types.Component{})
} }
// CanManageResourceTranslations checks if current user can list, search, create, or update resource translations
//
// This function is auto-generated
func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool {
return svc.can(ctx, "resource-translations.manage", &types.Component{})
}
// rbacResourceValidator validates known component's resource by routing it to the appropriate validator // rbacResourceValidator validates known component's resource by routing it to the appropriate validator
// //
// This function is auto-generated // This function is auto-generated
@@ -294,11 +306,12 @@ func rbacResourceOperations(r string) map[string]bool {
} }
case types.ComponentResourceType: case types.ComponentResourceType:
return map[string]bool{ return map[string]bool{
"grant": true, "grant": true,
"workflow.create": true, "workflow.create": true,
"triggers.search": true, "triggers.search": true,
"sessions.search": true, "sessions.search": true,
"workflows.search": true, "workflows.search": true,
"resource-translations.manage": true,
} }
} }

View File

@@ -11,10 +11,12 @@ package service
import ( import (
"context" "context"
"github.com/cortezaproject/corteza-server/automation/types" "github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/actionlog" "github.com/cortezaproject/corteza-server/pkg/actionlog"
intAuth "github.com/cortezaproject/corteza-server/pkg/auth" 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/locale"
"github.com/cortezaproject/corteza-server/store" "github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types" systemTypes "github.com/cortezaproject/corteza-server/system/types"
@@ -29,7 +31,7 @@ type (
} }
localeAccessController interface { localeAccessController interface {
// CanManageResourceTranslation(context.Context) bool CanManageResourceTranslations(context.Context) bool
} }
ResourceTranslationsManagerService interface { ResourceTranslationsManagerService interface {
@@ -40,6 +42,8 @@ type (
} }
) )
var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager { func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
return &resourceTranslationsManager{ return &resourceTranslationsManager{
actionlog: DefaultActionlog, actionlog: DefaultActionlog,
@@ -50,10 +54,15 @@ func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManage
} }
func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) { func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
// @todo AC // User is allowed to manage resource translations when:
//if (!svc.ac.CanManageResourceTranslation(ctx)) { // - managed resource translation strings are all for default language
// return *****ErrNotAllowedToCreate() // or
//} // - user is allowed to manage resource translations
if rr.ContainsForeign(svc.Locale().Default().Tag) {
if !svc.ac.CanManageResourceTranslations(ctx) {
return ErrNotAllowedToManageResourceTranslations
}
}
// @todo validation // @todo validation

View File

@@ -217,6 +217,11 @@ func (svc accessControl) List() (out []map[string]string) {
"any": types.ComponentRbacResource(), "any": types.ComponentRbacResource(),
"op": "namespaces.search", "op": "namespaces.search",
}, },
{
"type": types.ComponentResourceType,
"any": types.ComponentRbacResource(),
"op": "resource-translations.manage",
},
} }
func(svc interface{}) { func(svc interface{}) {
@@ -496,6 +501,13 @@ func (svc accessControl) CanSearchNamespaces(ctx context.Context) bool {
return svc.can(ctx, "namespaces.search", &types.Component{}) return svc.can(ctx, "namespaces.search", &types.Component{})
} }
// CanManageResourceTranslations checks if current user can list, search, create, or update resource translations
//
// This function is auto-generated
func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool {
return svc.can(ctx, "resource-translations.manage", &types.Component{})
}
// rbacResourceValidator validates known component's resource by routing it to the appropriate validator // rbacResourceValidator validates known component's resource by routing it to the appropriate validator
// //
// This function is auto-generated // This function is auto-generated
@@ -571,11 +583,12 @@ func rbacResourceOperations(r string) map[string]bool {
} }
case types.ComponentResourceType: case types.ComponentResourceType:
return map[string]bool{ return map[string]bool{
"grant": true, "grant": true,
"settings.read": true, "settings.read": true,
"settings.manage": true, "settings.manage": true,
"namespace.create": true, "namespace.create": true,
"namespaces.search": true, "namespaces.search": true,
"resource-translations.manage": true,
} }
} }

View File

@@ -14,10 +14,12 @@ package service
import ( import (
"context" "context"
"github.com/cortezaproject/corteza-server/compose/types" "github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/actionlog" "github.com/cortezaproject/corteza-server/pkg/actionlog"
intAuth "github.com/cortezaproject/corteza-server/pkg/auth" 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/locale"
"github.com/cortezaproject/corteza-server/store" "github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types" systemTypes "github.com/cortezaproject/corteza-server/system/types"
@@ -32,7 +34,7 @@ type (
} }
localeAccessController interface { localeAccessController interface {
// CanManageResourceTranslation(context.Context) bool CanManageResourceTranslations(context.Context) bool
} }
ResourceTranslationsManagerService interface { ResourceTranslationsManagerService interface {
@@ -46,6 +48,8 @@ type (
} }
) )
var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager { func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
return &resourceTranslationsManager{ return &resourceTranslationsManager{
actionlog: DefaultActionlog, actionlog: DefaultActionlog,
@@ -56,10 +60,15 @@ func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManage
} }
func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) { func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
// @todo AC // User is allowed to manage resource translations when:
//if (!svc.ac.CanManageResourceTranslation(ctx)) { // - managed resource translation strings are all for default language
// return *****ErrNotAllowedToCreate() // or
//} // - user is allowed to manage resource translations
if rr.ContainsForeign(svc.Locale().Default().Tag) {
if !svc.ac.CanManageResourceTranslations(ctx) {
return ErrNotAllowedToManageResourceTranslations
}
}
// @todo validation // @todo validation

View File

@@ -99,8 +99,8 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, c Config)
DefaultActionlog = actionlog.NewService(DefaultStore, log, tee, policy) DefaultActionlog = actionlog.NewService(DefaultStore, log, tee, policy)
} }
DefaultResourceTranslation = ResourceTranslationsManager(locale.Global())
DefaultAccessControl = AccessControl() DefaultAccessControl = AccessControl()
DefaultResourceTranslation = ResourceTranslationsManager(locale.Global())
if DefaultObjectStore == nil { if DefaultObjectStore == nil {
const svcPath = "compose" const svcPath = "compose"

View File

@@ -16,3 +16,6 @@ rbac:
workflows.search: workflows.search:
description: List, search or filter workflows description: List, search or filter workflows
resource-translations.manage:
description: List, search, create, or update resource translations

View File

@@ -14,3 +14,6 @@ rbac:
description: Create namespace description: Create namespace
namespaces.search: namespaces.search:
description: List, search or filter namespaces description: List, search or filter namespaces
resource-translations.manage:
description: List, search, create, or update resource translations

View File

@@ -65,5 +65,5 @@ rbac:
apigw-filters.search: apigw-filters.search:
description: List, search or filter API gateway filters description: List, search or filter API gateway filters
resource-translation.Manage: resource-translations.manage:
description: List, search, create, or update resource translations description: List, search, create, or update resource translations

View File

@@ -12,6 +12,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/actionlog" "github.com/cortezaproject/corteza-server/pkg/actionlog"
intAuth "github.com/cortezaproject/corteza-server/pkg/auth" 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/locale"
"github.com/cortezaproject/corteza-server/store" "github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types" systemTypes "github.com/cortezaproject/corteza-server/system/types"
@@ -26,7 +27,7 @@ type (
} }
localeAccessController interface { localeAccessController interface {
// CanManageResourceTranslation(context.Context) bool CanManageResourceTranslations(context.Context) bool
} }
ResourceTranslationsManagerService interface { ResourceTranslationsManagerService interface {
@@ -39,6 +40,8 @@ type (
} }
) )
var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager { func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
return &resourceTranslationsManager{ return &resourceTranslationsManager{
actionlog: DefaultActionlog, actionlog: DefaultActionlog,
@@ -49,10 +52,15 @@ func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManage
} }
func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) { func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
// @todo AC // User is allowed to manage resource translations when:
//if (!svc.ac.CanManageResourceTranslation(ctx)) { // - managed resource translation strings are all for default language
// return *****ErrNotAllowedToCreate() // or
//} // - user is allowed to manage resource translations
if rr.ContainsForeign(svc.Locale().Default().Tag) {
if !svc.ac.CanManageResourceTranslations(ctx) {
return ErrNotAllowedToManageResourceTranslations
}
}
// @todo validation // @todo validation

View File

@@ -23,11 +23,25 @@ func ContentID(cID uint64, i int) uint64 {
} }
func (rr ResourceTranslationSet) SetLanguage(tag language.Tag) { func (rr ResourceTranslationSet) SetLanguage(tag language.Tag) {
str := tag.String()
for _, r := range rr { for _, r := range rr {
r.Lang = tag.String() r.Lang = str
} }
} }
// Returns true if resource translation set contains foreign (non-native) languages
func (rr ResourceTranslationSet) ContainsForeign(native language.Tag) bool {
str := native.String()
for _, r := range rr {
if r.Lang != str {
return true
}
}
return false
}
func (rx ResourceTranslationIndex) FindByKey(k string) *ResourceTranslation { func (rx ResourceTranslationIndex) FindByKey(k string) *ResourceTranslation {
return rx[k] return rx[k]
} }

View File

@@ -31,6 +31,7 @@ type (
TResourceFor(tag language.Tag, ns, key string, rr ...string) string TResourceFor(tag language.Tag, ns, key string, rr ...string) string
Tags() []language.Tag Tags() []language.Tag
ResourceTranslations(code language.Tag, resource string) ResourceTranslationIndex ResourceTranslations(code language.Tag, resource string) ResourceTranslationIndex
Default() *Language
} }
service struct { service struct {

View File

@@ -357,7 +357,7 @@ func (svc accessControl) List() (out []map[string]string) {
{ {
"type": types.ComponentResourceType, "type": types.ComponentResourceType,
"any": types.ComponentRbacResource(), "any": types.ComponentRbacResource(),
"op": "resource-translation.Manage", "op": "resource-translations.manage",
}, },
} }
@@ -827,11 +827,11 @@ func (svc accessControl) CanSearchApigwFilters(ctx context.Context) bool {
return svc.can(ctx, "apigw-filters.search", &types.Component{}) return svc.can(ctx, "apigw-filters.search", &types.Component{})
} }
// CanManageResourceTranslation checks if current user can list, search, create, or update resource translations // CanManageResourceTranslations checks if current user can list, search, create, or update resource translations
// //
// This function is auto-generated // This function is auto-generated
func (svc accessControl) CanManageResourceTranslation(ctx context.Context) bool { func (svc accessControl) CanManageResourceTranslations(ctx context.Context) bool {
return svc.can(ctx, "resource-translation.Manage", &types.Component{}) return svc.can(ctx, "resource-translations.manage", &types.Component{})
} }
// rbacResourceValidator validates known component's resource by routing it to the appropriate validator // rbacResourceValidator validates known component's resource by routing it to the appropriate validator
@@ -926,32 +926,32 @@ func rbacResourceOperations(r string) map[string]bool {
} }
case types.ComponentResourceType: case types.ComponentResourceType:
return map[string]bool{ return map[string]bool{
"grant": true, "grant": true,
"action-log.read": true, "action-log.read": true,
"settings.read": true, "settings.read": true,
"settings.manage": true, "settings.manage": true,
"auth-client.create": true, "auth-client.create": true,
"auth-clients.search": true, "auth-clients.search": true,
"role.create": true, "role.create": true,
"roles.search": true, "roles.search": true,
"user.create": true, "user.create": true,
"users.search": true, "users.search": true,
"application.create": true, "application.create": true,
"applications.search": true, "applications.search": true,
"application.flag.self": true, "application.flag.self": true,
"application.flag.global": true, "application.flag.global": true,
"template.create": true, "template.create": true,
"templates.search": true, "templates.search": true,
"report.create": true, "report.create": true,
"reports.search": true, "reports.search": true,
"reminder.assign": true, "reminder.assign": true,
"queue.create": true, "queue.create": true,
"queues.search": true, "queues.search": true,
"apigw-route.create": true, "apigw-route.create": true,
"apigw-routes.search": true, "apigw-routes.search": true,
"apigw-filter.create": true, "apigw-filter.create": true,
"apigw-filters.search": true, "apigw-filters.search": true,
"resource-translation.Manage": true, "resource-translations.manage": true,
} }
} }

View File

@@ -11,10 +11,12 @@ package service
import ( import (
"context" "context"
"github.com/cortezaproject/corteza-server/system/types" "github.com/cortezaproject/corteza-server/system/types"
"github.com/cortezaproject/corteza-server/pkg/actionlog" "github.com/cortezaproject/corteza-server/pkg/actionlog"
intAuth "github.com/cortezaproject/corteza-server/pkg/auth" 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/locale"
"github.com/cortezaproject/corteza-server/store" "github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types" systemTypes "github.com/cortezaproject/corteza-server/system/types"
@@ -29,7 +31,7 @@ type (
} }
localeAccessController interface { localeAccessController interface {
// CanManageResourceTranslation(context.Context) bool CanManageResourceTranslations(context.Context) bool
} }
ResourceTranslationsManagerService interface { ResourceTranslationsManagerService interface {
@@ -40,6 +42,8 @@ type (
} }
) )
var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager { func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
return &resourceTranslationsManager{ return &resourceTranslationsManager{
actionlog: DefaultActionlog, actionlog: DefaultActionlog,
@@ -50,10 +54,15 @@ func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManage
} }
func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) { func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
// @todo AC // User is allowed to manage resource translations when:
//if (!svc.ac.CanManageResourceTranslation(ctx)) { // - managed resource translation strings are all for default language
// return *****ErrNotAllowedToCreate() // or
//} // - user is allowed to manage resource translations
if rr.ContainsForeign(svc.Locale().Default().Tag) {
if !svc.ac.CanManageResourceTranslations(ctx) {
return ErrNotAllowedToManageResourceTranslations
}
}
// @todo validation // @todo validation

View File

@@ -17,7 +17,7 @@ type (
} }
resourceTranslationAccessController interface { resourceTranslationAccessController interface {
CanManageResourceTranslation(context.Context) bool CanManageResourceTranslations(context.Context) bool
} }
ResourceTranslationService interface { ResourceTranslationService interface {
@@ -48,7 +48,7 @@ func (svc resourceTranslation) Read(ctx context.Context, ID uint64) (cc *types.R
return TemplateErrInvalidID() return TemplateErrInvalidID()
} }
if !svc.ac.CanManageResourceTranslation(ctx) { if !svc.ac.CanManageResourceTranslations(ctx) {
return ResourceTranslationErrNotAllowedToManage() return ResourceTranslationErrNotAllowedToManage()
} }
@@ -70,7 +70,7 @@ func (svc resourceTranslation) List(ctx context.Context, filter types.ResourceTr
) )
err = func() error { err = func() error {
if !svc.ac.CanManageResourceTranslation(ctx) { if !svc.ac.CanManageResourceTranslations(ctx) {
return ResourceTranslationErrNotAllowedToManage() return ResourceTranslationErrNotAllowedToManage()
} }
@@ -90,7 +90,7 @@ func (svc resourceTranslation) Create(ctx context.Context, new *types.ResourceTr
) )
err = func() (err error) { err = func() (err error) {
if !svc.ac.CanManageResourceTranslation(ctx) { if !svc.ac.CanManageResourceTranslations(ctx) {
return ResourceTranslationErrNotAllowedToManage() return ResourceTranslationErrNotAllowedToManage()
} }
@@ -123,7 +123,7 @@ func (svc resourceTranslation) Update(ctx context.Context, upd *types.ResourceTr
return ResourceTranslationErrInvalidID() return ResourceTranslationErrInvalidID()
} }
if !svc.ac.CanManageResourceTranslation(ctx) { if !svc.ac.CanManageResourceTranslations(ctx) {
return ResourceTranslationErrNotAllowedToManage() return ResourceTranslationErrNotAllowedToManage()
} }
@@ -164,7 +164,7 @@ func (svc resourceTranslation) Delete(ctx context.Context, ID uint64) (err error
return ResourceTranslationErrInvalidID() return ResourceTranslationErrInvalidID()
} }
if !svc.ac.CanManageResourceTranslation(ctx) { if !svc.ac.CanManageResourceTranslations(ctx) {
return ResourceTranslationErrNotAllowedToManage() return ResourceTranslationErrNotAllowedToManage()
} }
@@ -198,7 +198,7 @@ func (svc resourceTranslation) Undelete(ctx context.Context, ID uint64) (err err
return ResourceTranslationErrInvalidID() return ResourceTranslationErrInvalidID()
} }
if !svc.ac.CanManageResourceTranslation(ctx) { if !svc.ac.CanManageResourceTranslations(ctx) {
return ResourceTranslationErrNotAllowedToManage() return ResourceTranslationErrNotAllowedToManage()
} }