Refactor rules endpoint
- Removes specific params - Improves RuleSet.FilterResource to accept multiple resources - Rework FindRules method in access-controller tpl
This commit is contained in:
@@ -276,7 +276,6 @@ endpoints:
|
||||
- Client ID
|
||||
- Session ID
|
||||
imports:
|
||||
- github.com/cortezaproject/corteza-server/pkg/filter
|
||||
- github.com/cortezaproject/corteza-server/pkg/rbac
|
||||
apis:
|
||||
- name: list
|
||||
@@ -320,10 +319,6 @@ endpoints:
|
||||
required: true
|
||||
title: Role ID
|
||||
get:
|
||||
- name: specific
|
||||
required: false
|
||||
title: Exclude (0, default), include (1) or return only (2) specific rules
|
||||
type: "filter.State"
|
||||
- name: resource
|
||||
type: "[]string"
|
||||
required: false
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/automation/service"
|
||||
"github.com/cortezaproject/corteza-server/automation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/api"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
)
|
||||
|
||||
@@ -20,7 +19,7 @@ type (
|
||||
Trace(context.Context, uint64, []uint64, ...string) ([]*rbac.Trace, error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, rr ...string) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
}
|
||||
)
|
||||
@@ -44,7 +43,7 @@ func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (i
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Read(ctx context.Context, r *request.PermissionsRead) (interface{}, error) {
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Specific, r.Resource...)
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Delete(ctx context.Context, r *request.PermissionsDelete) (interface{}, error) {
|
||||
|
||||
@@ -11,7 +11,6 @@ package request
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -68,11 +67,6 @@ type (
|
||||
// Role ID
|
||||
RoleID uint64 `json:",string"`
|
||||
|
||||
// Specific GET parameter
|
||||
//
|
||||
// Exclude (0, default), include (1) or return only (2) specific rules
|
||||
Specific filter.State
|
||||
|
||||
// Resource GET parameter
|
||||
//
|
||||
// Show only rules for a specific resource
|
||||
@@ -228,7 +222,6 @@ func NewPermissionsRead() *PermissionsRead {
|
||||
func (r PermissionsRead) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"roleID": r.RoleID,
|
||||
"specific": r.Specific,
|
||||
"resource": r.Resource,
|
||||
}
|
||||
}
|
||||
@@ -238,11 +231,6 @@ func (r PermissionsRead) GetRoleID() uint64 {
|
||||
return r.RoleID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetSpecific() filter.State {
|
||||
return r.Specific
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetResource() []string {
|
||||
return r.Resource
|
||||
@@ -255,12 +243,6 @@ func (r *PermissionsRead) Fill(req *http.Request) (err error) {
|
||||
// GET params
|
||||
tmp := req.URL.Query()
|
||||
|
||||
if val, ok := tmp["specific"]; ok && len(val) > 0 {
|
||||
r.Specific, err = payload.ParseFilterState(val[0]), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if val, ok := tmp["resource[]"]; ok {
|
||||
r.Resource, err = val, nil
|
||||
if err != nil {
|
||||
|
||||
36
automation/service/access_control.gen.go
generated
36
automation/service/access_control.gen.go
generated
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/automation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
@@ -266,25 +265,17 @@ func (svc accessControl) logGrants(ctx context.Context, rr []*rbac.Rule) {
|
||||
// FindRules find all rules based on filters
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (out rbac.RuleSet, err error) {
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, rr ...string) (out rbac.RuleSet, err error) {
|
||||
if !svc.CanGrant(ctx) {
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
rules, err := svc.FindRulesByRoleID(ctx, roleID)
|
||||
out, err = svc.FindRulesByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *rbac.Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
)
|
||||
|
||||
// Filter based on resource
|
||||
var resources []rbac.Resource
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
@@ -298,26 +289,7 @@ func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
for _, res := range resources {
|
||||
for _, rule := range rules.FilterResource(res.RbacResource()) {
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter for Excluded, Include, or Exclusive specific rules
|
||||
switch specific {
|
||||
// Exclude all the specific rules
|
||||
case filter.StateExcluded:
|
||||
out = out.FilterRules(false)
|
||||
// Returns only all the specific rules
|
||||
case filter.StateExclusive:
|
||||
out = out.FilterRules(true)
|
||||
}
|
||||
|
||||
return
|
||||
return out.FilterResource(resources...), nil
|
||||
}
|
||||
|
||||
// FindRulesByRoleID find all rules for a specific role
|
||||
|
||||
@@ -211,25 +211,17 @@ func (svc accessControl) logGrants(ctx context.Context, rr []*rbac.Rule) {
|
||||
// FindRules find all rules based on filters
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (out rbac.RuleSet, err error) {
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, rr ...string) (out rbac.RuleSet, err error) {
|
||||
if !svc.CanGrant(ctx) {
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
rules, err := svc.FindRulesByRoleID(ctx, roleID)
|
||||
out, err = svc.FindRulesByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *rbac.Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
)
|
||||
|
||||
// Filter based on resource
|
||||
var resources []rbac.Resource
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
@@ -243,26 +235,7 @@ func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
for _, res := range resources {
|
||||
for _, rule := range rules.FilterResource(res.RbacResource()) {
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter for Excluded, Include, or Exclusive specific rules
|
||||
switch specific {
|
||||
// Exclude all the specific rules
|
||||
case filter.StateExcluded:
|
||||
out = out.FilterRules(false)
|
||||
// Returns only all the specific rules
|
||||
case filter.StateExclusive:
|
||||
out = out.FilterRules(true)
|
||||
}
|
||||
|
||||
return
|
||||
return out.FilterResource(resources...), nil
|
||||
}
|
||||
|
||||
// FindRulesByRoleID find all rules for a specific role
|
||||
|
||||
@@ -1291,7 +1291,6 @@ endpoints:
|
||||
- Client ID
|
||||
- Session ID
|
||||
imports:
|
||||
- github.com/cortezaproject/corteza-server/pkg/filter
|
||||
- github.com/cortezaproject/corteza-server/pkg/rbac
|
||||
apis:
|
||||
- name: list
|
||||
@@ -1335,10 +1334,6 @@ endpoints:
|
||||
required: true
|
||||
title: Role ID
|
||||
get:
|
||||
- name: specific
|
||||
required: false
|
||||
title: Exclude (0, default), include (1) or return only (2) specific rules
|
||||
type: "filter.State"
|
||||
- name: resource
|
||||
type: "[]string"
|
||||
required: false
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/service"
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/api"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
)
|
||||
|
||||
@@ -20,7 +19,7 @@ type (
|
||||
Trace(context.Context, uint64, []uint64, ...string) ([]*rbac.Trace, error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, rr ...string) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
}
|
||||
)
|
||||
@@ -44,7 +43,7 @@ func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (i
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Read(ctx context.Context, r *request.PermissionsRead) (interface{}, error) {
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Specific, r.Resource...)
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Delete(ctx context.Context, r *request.PermissionsDelete) (interface{}, error) {
|
||||
|
||||
@@ -11,7 +11,6 @@ package request
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -68,11 +67,6 @@ type (
|
||||
// Role ID
|
||||
RoleID uint64 `json:",string"`
|
||||
|
||||
// Specific GET parameter
|
||||
//
|
||||
// Exclude (0, default), include (1) or return only (2) specific rules
|
||||
Specific filter.State
|
||||
|
||||
// Resource GET parameter
|
||||
//
|
||||
// Show only rules for a specific resource
|
||||
@@ -228,7 +222,6 @@ func NewPermissionsRead() *PermissionsRead {
|
||||
func (r PermissionsRead) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"roleID": r.RoleID,
|
||||
"specific": r.Specific,
|
||||
"resource": r.Resource,
|
||||
}
|
||||
}
|
||||
@@ -238,11 +231,6 @@ func (r PermissionsRead) GetRoleID() uint64 {
|
||||
return r.RoleID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetSpecific() filter.State {
|
||||
return r.Specific
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetResource() []string {
|
||||
return r.Resource
|
||||
@@ -255,12 +243,6 @@ func (r *PermissionsRead) Fill(req *http.Request) (err error) {
|
||||
// GET params
|
||||
tmp := req.URL.Query()
|
||||
|
||||
if val, ok := tmp["specific"]; ok && len(val) > 0 {
|
||||
r.Specific, err = payload.ParseFilterState(val[0]), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if val, ok := tmp["resource[]"]; ok {
|
||||
r.Resource, err = val, nil
|
||||
if err != nil {
|
||||
|
||||
36
compose/service/access_control.gen.go
generated
36
compose/service/access_control.gen.go
generated
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
@@ -377,25 +376,17 @@ func (svc accessControl) logGrants(ctx context.Context, rr []*rbac.Rule) {
|
||||
// FindRules find all rules based on filters
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (out rbac.RuleSet, err error) {
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, rr ...string) (out rbac.RuleSet, err error) {
|
||||
if !svc.CanGrant(ctx) {
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
rules, err := svc.FindRulesByRoleID(ctx, roleID)
|
||||
out, err = svc.FindRulesByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *rbac.Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
)
|
||||
|
||||
// Filter based on resource
|
||||
var resources []rbac.Resource
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
@@ -409,26 +400,7 @@ func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
for _, res := range resources {
|
||||
for _, rule := range rules.FilterResource(res.RbacResource()) {
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter for Excluded, Include, or Exclusive specific rules
|
||||
switch specific {
|
||||
// Exclude all the specific rules
|
||||
case filter.StateExcluded:
|
||||
out = out.FilterRules(false)
|
||||
// Returns only all the specific rules
|
||||
case filter.StateExclusive:
|
||||
out = out.FilterRules(true)
|
||||
}
|
||||
|
||||
return
|
||||
return out.FilterResource(resources...), nil
|
||||
}
|
||||
|
||||
// FindRulesByRoleID find all rules for a specific role
|
||||
|
||||
@@ -503,7 +503,6 @@ endpoints:
|
||||
- Client ID
|
||||
- Session ID
|
||||
imports:
|
||||
- github.com/cortezaproject/corteza-server/pkg/filter
|
||||
- github.com/cortezaproject/corteza-server/pkg/rbac
|
||||
apis:
|
||||
- name: list
|
||||
@@ -547,10 +546,6 @@ endpoints:
|
||||
required: true
|
||||
title: Role ID
|
||||
get:
|
||||
- name: specific
|
||||
required: false
|
||||
title: Exclude (0, default), include (1) or return only (2) specific rules
|
||||
type: "filter.State"
|
||||
- name: resource
|
||||
type: "[]string"
|
||||
required: false
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/federation/service"
|
||||
"github.com/cortezaproject/corteza-server/federation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/api"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
)
|
||||
|
||||
@@ -20,7 +19,7 @@ type (
|
||||
Trace(context.Context, uint64, []uint64, ...string) ([]*rbac.Trace, error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, rr ...string) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
}
|
||||
)
|
||||
@@ -44,7 +43,7 @@ func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (i
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Read(ctx context.Context, r *request.PermissionsRead) (interface{}, error) {
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Specific, r.Resource...)
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Delete(ctx context.Context, r *request.PermissionsDelete) (interface{}, error) {
|
||||
|
||||
@@ -11,7 +11,6 @@ package request
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -68,11 +67,6 @@ type (
|
||||
// Role ID
|
||||
RoleID uint64 `json:",string"`
|
||||
|
||||
// Specific GET parameter
|
||||
//
|
||||
// Exclude (0, default), include (1) or return only (2) specific rules
|
||||
Specific filter.State
|
||||
|
||||
// Resource GET parameter
|
||||
//
|
||||
// Show only rules for a specific resource
|
||||
@@ -228,7 +222,6 @@ func NewPermissionsRead() *PermissionsRead {
|
||||
func (r PermissionsRead) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"roleID": r.RoleID,
|
||||
"specific": r.Specific,
|
||||
"resource": r.Resource,
|
||||
}
|
||||
}
|
||||
@@ -238,11 +231,6 @@ func (r PermissionsRead) GetRoleID() uint64 {
|
||||
return r.RoleID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetSpecific() filter.State {
|
||||
return r.Specific
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetResource() []string {
|
||||
return r.Resource
|
||||
@@ -255,12 +243,6 @@ func (r *PermissionsRead) Fill(req *http.Request) (err error) {
|
||||
// GET params
|
||||
tmp := req.URL.Query()
|
||||
|
||||
if val, ok := tmp["specific"]; ok && len(val) > 0 {
|
||||
r.Specific, err = payload.ParseFilterState(val[0]), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if val, ok := tmp["resource[]"]; ok {
|
||||
r.Resource, err = val, nil
|
||||
if err != nil {
|
||||
|
||||
36
federation/service/access_control.gen.go
generated
36
federation/service/access_control.gen.go
generated
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/federation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
@@ -253,25 +252,17 @@ func (svc accessControl) logGrants(ctx context.Context, rr []*rbac.Rule) {
|
||||
// FindRules find all rules based on filters
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (out rbac.RuleSet, err error) {
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, rr ...string) (out rbac.RuleSet, err error) {
|
||||
if !svc.CanGrant(ctx) {
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
rules, err := svc.FindRulesByRoleID(ctx, roleID)
|
||||
out, err = svc.FindRulesByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *rbac.Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
)
|
||||
|
||||
// Filter based on resource
|
||||
var resources []rbac.Resource
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
@@ -285,26 +276,7 @@ func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
for _, res := range resources {
|
||||
for _, rule := range rules.FilterResource(res.RbacResource()) {
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter for Excluded, Include, or Exclusive specific rules
|
||||
switch specific {
|
||||
// Exclude all the specific rules
|
||||
case filter.StateExcluded:
|
||||
out = out.FilterRules(false)
|
||||
// Returns only all the specific rules
|
||||
case filter.StateExclusive:
|
||||
out = out.FilterRules(true)
|
||||
}
|
||||
|
||||
return
|
||||
return out.FilterResource(resources...), nil
|
||||
}
|
||||
|
||||
// FindRulesByRoleID find all rules for a specific role
|
||||
|
||||
@@ -60,23 +60,23 @@ func (set RuleSet) FilterAccess(a Access) (out RuleSet) {
|
||||
return out
|
||||
}
|
||||
|
||||
func (set RuleSet) FilterResource(res string) (out RuleSet) {
|
||||
for _, r := range set {
|
||||
if !matchResource(res, r.Resource) {
|
||||
continue
|
||||
func (set RuleSet) FilterResource(rr ...Resource) (out RuleSet) {
|
||||
var (
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
out = append(out, r)
|
||||
}
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FilterRules will filter the rules based on given parameter(specific),
|
||||
// If params is true then it will return only the specific rules otherwise it will return non-specific rules
|
||||
func (set RuleSet) FilterRules(specific bool) (out RuleSet) {
|
||||
for _, r := range set {
|
||||
if specific == isSpecific(r.Resource) {
|
||||
out = append(out, r)
|
||||
for _, res := range rr {
|
||||
for _, rule := range set {
|
||||
if !matchResource(res.RbacResource(), rule.Resource) {
|
||||
continue
|
||||
}
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1219,7 +1219,6 @@ endpoints:
|
||||
- Client ID
|
||||
- Session ID
|
||||
imports:
|
||||
- github.com/cortezaproject/corteza-server/pkg/filter
|
||||
- github.com/cortezaproject/corteza-server/pkg/rbac
|
||||
apis:
|
||||
- name: list
|
||||
@@ -1264,10 +1263,6 @@ endpoints:
|
||||
required: true
|
||||
title: Role ID
|
||||
get:
|
||||
- name: specific
|
||||
required: false
|
||||
title: Exclude (0, default), include (1) or return only (2) specific rules
|
||||
type: "filter.State"
|
||||
- name: resource
|
||||
type: "[]string"
|
||||
required: false
|
||||
|
||||
@@ -3,7 +3,6 @@ package rest
|
||||
import (
|
||||
"context"
|
||||
"github.com/cortezaproject/corteza-server/pkg/api"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/system/rest/request"
|
||||
"github.com/cortezaproject/corteza-server/system/service"
|
||||
@@ -20,7 +19,7 @@ type (
|
||||
Trace(context.Context, uint64, []uint64, ...string) ([]*rbac.Trace, error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (rbac.RuleSet, error)
|
||||
FindRules(ctx context.Context, roleID uint64, rr ...string) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
}
|
||||
)
|
||||
@@ -44,7 +43,7 @@ func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (i
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Read(ctx context.Context, r *request.PermissionsRead) (interface{}, error) {
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Specific, r.Resource...)
|
||||
return ctrl.ac.FindRules(ctx, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Delete(ctx context.Context, r *request.PermissionsDelete) (interface{}, error) {
|
||||
|
||||
@@ -11,7 +11,6 @@ package request
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/payload"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/go-chi/chi/v5"
|
||||
@@ -68,11 +67,6 @@ type (
|
||||
// Role ID
|
||||
RoleID uint64 `json:",string"`
|
||||
|
||||
// Specific GET parameter
|
||||
//
|
||||
// Exclude (0, default), include (1) or return only (2) specific rules
|
||||
Specific filter.State
|
||||
|
||||
// Resource GET parameter
|
||||
//
|
||||
// Show only rules for a specific resource
|
||||
@@ -228,7 +222,6 @@ func NewPermissionsRead() *PermissionsRead {
|
||||
func (r PermissionsRead) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"roleID": r.RoleID,
|
||||
"specific": r.Specific,
|
||||
"resource": r.Resource,
|
||||
}
|
||||
}
|
||||
@@ -238,11 +231,6 @@ func (r PermissionsRead) GetRoleID() uint64 {
|
||||
return r.RoleID
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetSpecific() filter.State {
|
||||
return r.Specific
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r PermissionsRead) GetResource() []string {
|
||||
return r.Resource
|
||||
@@ -255,13 +243,6 @@ func (r *PermissionsRead) Fill(req *http.Request) (err error) {
|
||||
// GET params
|
||||
tmp := req.URL.Query()
|
||||
|
||||
if val, ok := tmp["specific"]; ok && len(val) > 0 {
|
||||
|
||||
r.Specific, err = payload.ParseFilterState(val[0]), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if val, ok := tmp["resource[]"]; ok {
|
||||
r.Resource, err = val, nil
|
||||
if err != nil {
|
||||
|
||||
36
system/service/access_control.gen.go
generated
36
system/service/access_control.gen.go
generated
@@ -11,7 +11,6 @@ import (
|
||||
"fmt"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
@@ -555,25 +554,17 @@ func (svc accessControl) logGrants(ctx context.Context, rr []*rbac.Rule) {
|
||||
// FindRules find all rules based on filters
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific filter.State, rr ...string) (out rbac.RuleSet, err error) {
|
||||
func (svc accessControl) FindRules(ctx context.Context, roleID uint64, rr ...string) (out rbac.RuleSet, err error) {
|
||||
if !svc.CanGrant(ctx) {
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
rules, err := svc.FindRulesByRoleID(ctx, roleID)
|
||||
out, err = svc.FindRulesByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
ruleMap = make(map[string]bool)
|
||||
uniqRuleID = func(r *rbac.Rule) string {
|
||||
return fmt.Sprintf("%s|%s|%d", r.Resource, r.Operation, r.RoleID)
|
||||
}
|
||||
)
|
||||
|
||||
// Filter based on resource
|
||||
var resources []rbac.Resource
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
@@ -587,26 +578,7 @@ func (svc accessControl) FindRules(ctx context.Context, roleID uint64, specific
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
for _, res := range resources {
|
||||
for _, rule := range rules.FilterResource(res.RbacResource()) {
|
||||
if _, ok := ruleMap[uniqRuleID(rule)]; !ok {
|
||||
out = append(out, rule)
|
||||
ruleMap[uniqRuleID(rule)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter for Excluded, Include, or Exclusive specific rules
|
||||
switch specific {
|
||||
// Exclude all the specific rules
|
||||
case filter.StateExcluded:
|
||||
out = out.FilterRules(false)
|
||||
// Returns only all the specific rules
|
||||
case filter.StateExclusive:
|
||||
out = out.FilterRules(true)
|
||||
}
|
||||
|
||||
return
|
||||
return out.FilterResource(resources...), nil
|
||||
}
|
||||
|
||||
// FindRulesByRoleID find all rules for a specific role
|
||||
|
||||
@@ -67,23 +67,11 @@ func TestPermissionsReadWithFilter(t *testing.T) {
|
||||
// Specific resource related rules
|
||||
testID := id.Next()
|
||||
helpers.AllowMe(h, types.UserRbacResource(testID), "read")
|
||||
helpers.AllowMe(h, types.UserRbacResource(testID), "update")
|
||||
helpers.AllowMe(h, types.UserRbacResource(id.Next()), "update")
|
||||
|
||||
// Only non-specific resource rules with `specific: 0` filter
|
||||
// all rules
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("specific", "0").
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response`, 2)).
|
||||
End()
|
||||
|
||||
// Including all specific and non-specific resource rules with `specific: 1` filter
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("specific", "1").
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
@@ -91,10 +79,10 @@ func TestPermissionsReadWithFilter(t *testing.T) {
|
||||
Assert(jsonpath.Len(`$.response`, 4)).
|
||||
End()
|
||||
|
||||
// Only specific resource rules with `specific: 2` filter
|
||||
// Resource related rules
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("specific", "2").
|
||||
Query("resource", "corteza::system:user/*").
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
@@ -102,16 +90,15 @@ func TestPermissionsReadWithFilter(t *testing.T) {
|
||||
Assert(jsonpath.Len(`$.response`, 2)).
|
||||
End()
|
||||
|
||||
// Only resource related rules with `resource: corteza::system:user/{ID}`
|
||||
// Only specific resource rules with `specific: 2` filter
|
||||
h.apiInit().
|
||||
Getf("/permissions/%d/rules", h.roleID).
|
||||
Query("specific", "1").
|
||||
Query("resource", fmt.Sprintf("corteza::system:user/%d", testID)).
|
||||
Header("Accept", "application/json").
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
Assert(jsonpath.Len(`$.response`, 2)).
|
||||
Assert(jsonpath.Len(`$.response`, 1)).
|
||||
End()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user