From 565651e1420484c277dcab2d43acd7807194462d Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Tue, 14 May 2019 14:06:19 +0200 Subject: [PATCH] Add permission resource type & access control for module field --- compose/internal/service/access_control.go | 14 +++++++++ compose/rest/module.go | 34 ++++++++++++++++++++++ compose/types/module_field.go | 7 +++++ compose/types/permission_resources.go | 1 + 4 files changed, 56 insertions(+) diff --git a/compose/internal/service/access_control.go b/compose/internal/service/access_control.go index ac2e4084e..8b38d12d1 100644 --- a/compose/internal/service/access_control.go +++ b/compose/internal/service/access_control.go @@ -79,6 +79,14 @@ func (svc accessControl) CanDeleteModule(ctx context.Context, r *types.Module) b return svc.can(ctx, r, "delete") } +func (svc accessControl) CanReadRecordValue(ctx context.Context, r *types.ModuleField) bool { + return svc.can(ctx, r, "record.value.read", permissions.Allowed) +} + +func (svc accessControl) CanUpdateRecordValue(ctx context.Context, r *types.ModuleField) bool { + return svc.can(ctx, r, "record.value.update", permissions.Allowed) +} + func (svc accessControl) CanCreateRecord(ctx context.Context, r *types.Module) bool { return svc.can(ctx, r, "record.create") } @@ -234,6 +242,12 @@ func (svc accessControl) Whitelist() permissions.Whitelist { "record.delete", ) + wl.Set( + types.ModuleFieldPermissionResource, + "record.value.read", + "record.value.update", + ) + wl.Set( types.ChartPermissionResource, "read", diff --git a/compose/rest/module.go b/compose/rest/module.go index 70518d34c..9f89a1d7f 100644 --- a/compose/rest/module.go +++ b/compose/rest/module.go @@ -14,6 +14,8 @@ type ( modulePayload struct { *types.Module + Fields []*moduleFieldPayload `json:"fields"` + CanUpdateModule bool `json:"canUpdateModule"` CanDeleteModule bool `json:"canDeleteModule"` CanCreateRecord bool `json:"canCreateRecord"` @@ -22,6 +24,13 @@ type ( CanDeleteRecord bool `json:"canDeleteRecord"` } + moduleFieldPayload struct { + *types.ModuleField + + CanReadRecordValue bool `json:"canReadRecordValue"` + CanUpdateRecordValue bool `json:"canUpdateRecordValue"` + } + moduleSetPayload struct { Filter types.ModuleFilter `json:"filter"` Set []*modulePayload `json:"set"` @@ -40,6 +49,9 @@ type ( CanReadRecord(context.Context, *types.Module) bool CanUpdateRecord(context.Context, *types.Module) bool CanDeleteRecord(context.Context, *types.Module) bool + + CanReadRecordValue(context.Context, *types.ModuleField) bool + CanUpdateRecordValue(context.Context, *types.ModuleField) bool } ) @@ -113,9 +125,16 @@ func (ctrl Module) makePayload(ctx context.Context, m *types.Module, err error) return nil, err } + mfp, err := ctrl.makeFieldsPayload(ctx, m) + if err != nil { + return nil, err + } + return &modulePayload{ Module: m, + Fields: mfp, + CanUpdateModule: ctrl.ac.CanUpdateModule(ctx, m), CanDeleteModule: ctrl.ac.CanDeleteModule(ctx, m), CanCreateRecord: ctrl.ac.CanCreateRecord(ctx, m), @@ -125,6 +144,21 @@ func (ctrl Module) makePayload(ctx context.Context, m *types.Module, err error) }, nil } +func (ctrl Module) makeFieldsPayload(ctx context.Context, m *types.Module) (out []*moduleFieldPayload, err error) { + out = make([]*moduleFieldPayload, len(m.Fields)) + + for i, f := range m.Fields { + out[i] = &moduleFieldPayload{ + ModuleField: f, + + CanReadRecordValue: ctrl.ac.CanReadRecordValue(ctx, f), + CanUpdateRecordValue: ctrl.ac.CanUpdateRecordValue(ctx, f), + } + } + + return +} + func (ctrl Module) makeFilterPayload(ctx context.Context, nn types.ModuleSet, f types.ModuleFilter, err error) (*moduleSetPayload, error) { if err != nil { return nil, err diff --git a/compose/types/module_field.go b/compose/types/module_field.go index fcb7f1c51..088e917ed 100644 --- a/compose/types/module_field.go +++ b/compose/types/module_field.go @@ -6,6 +6,8 @@ import ( "time" "github.com/jmoiron/sqlx/types" + + "github.com/crusttech/crust/internal/permissions" ) type ( @@ -32,6 +34,11 @@ type ( } ) +// Resource returns a system resource ID for this type +func (m ModuleField) PermissionResource() permissions.Resource { + return ModuleFieldPermissionResource.AppendID(m.ID) +} + func (set *ModuleFieldSet) Scan(src interface{}) error { if data, ok := src.([]byte); ok { return json.Unmarshal(data, set) diff --git a/compose/types/permission_resources.go b/compose/types/permission_resources.go index 6af7e1050..a968d3052 100644 --- a/compose/types/permission_resources.go +++ b/compose/types/permission_resources.go @@ -8,5 +8,6 @@ const ComposePermissionResource = permissions.Resource("compose") const NamespacePermissionResource = permissions.Resource("compose:namespace:") const ChartPermissionResource = permissions.Resource("compose:chart:") const ModulePermissionResource = permissions.Resource("compose:module:") +const ModuleFieldPermissionResource = permissions.Resource("compose:module-field:") const PagePermissionResource = permissions.Resource("compose:page:") const TriggerPermissionResource = permissions.Resource("compose:trigger:")