Refactor read perm check for charts, modules, namespaces & pages
This commit is contained in:
@@ -104,6 +104,10 @@ func (r chart) Find(filter types.ChartFilter) (set types.ChartSet, f types.Chart
|
||||
query = query.Where("LOWER(handle) = ?", strings.ToLower(f.Handle))
|
||||
}
|
||||
|
||||
if f.IsReadable != nil {
|
||||
query = query.Where(f.IsReadable)
|
||||
}
|
||||
|
||||
if f.Count, err = r.count(query); err != nil || f.Count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -123,6 +123,10 @@ func (r module) Find(filter types.ModuleFilter) (set types.ModuleSet, f types.Mo
|
||||
query = query.Where("LOWER(handle) = ?", strings.ToLower(f.Handle))
|
||||
}
|
||||
|
||||
if f.IsReadable != nil {
|
||||
query = query.Where(f.IsReadable)
|
||||
}
|
||||
|
||||
if f.Count, err = r.count(query); err != nil || f.Count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -105,6 +105,10 @@ func (r *namespace) Find(filter types.NamespaceFilter) (set types.NamespaceSet,
|
||||
query = query.Where("LOWER(slug) = LOWER(?)", f.Slug)
|
||||
}
|
||||
|
||||
if f.IsReadable != nil {
|
||||
query = query.Where(f.IsReadable)
|
||||
}
|
||||
|
||||
if f.Count, err = r.count(query); err != nil || f.Count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -120,6 +120,10 @@ func (r page) Find(filter types.PageFilter) (set types.PageSet, f types.PageFilt
|
||||
query = query.Where("title LIKE ? OR description LIKE ?", q, q)
|
||||
}
|
||||
|
||||
if f.IsReadable != nil {
|
||||
query = query.Where(f.IsReadable)
|
||||
}
|
||||
|
||||
if f.Count, err = r.count(query); err != nil || f.Count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,6 +68,10 @@ func (svc accessControl) CanReadNamespace(ctx context.Context, r *types.Namespac
|
||||
return svc.can(ctx, r, "read", permissions.Allowed)
|
||||
}
|
||||
|
||||
func (svc accessControl) FilterReadableNamespaces(ctx context.Context) *permissions.ResourceFilter {
|
||||
return svc.permissions.ResourceFilter(ctx, types.NamespacePermissionResource, "read", permissions.Deny)
|
||||
}
|
||||
|
||||
func (svc accessControl) CanUpdateNamespace(ctx context.Context, r *types.Namespace) bool {
|
||||
return svc.can(ctx, r, "update")
|
||||
}
|
||||
@@ -92,6 +96,10 @@ func (svc accessControl) CanReadModule(ctx context.Context, r *types.Module) boo
|
||||
return svc.can(ctx, r, "read")
|
||||
}
|
||||
|
||||
func (svc accessControl) FilterReadableModules(ctx context.Context) *permissions.ResourceFilter {
|
||||
return svc.permissions.ResourceFilter(ctx, types.ModulePermissionResource, "read", permissions.Deny)
|
||||
}
|
||||
|
||||
func (svc accessControl) CanUpdateModule(ctx context.Context, r *types.Module) bool {
|
||||
return svc.can(ctx, r, "update")
|
||||
}
|
||||
@@ -136,6 +144,10 @@ func (svc accessControl) CanReadChart(ctx context.Context, r *types.Chart) bool
|
||||
return svc.can(ctx, r, "read")
|
||||
}
|
||||
|
||||
func (svc accessControl) FilterReadableCharts(ctx context.Context) *permissions.ResourceFilter {
|
||||
return svc.permissions.ResourceFilter(ctx, types.ChartPermissionResource, "read", permissions.Deny)
|
||||
}
|
||||
|
||||
func (svc accessControl) CanUpdateChart(ctx context.Context, r *types.Chart) bool {
|
||||
return svc.can(ctx, r, "update")
|
||||
}
|
||||
@@ -153,6 +165,10 @@ func (svc accessControl) CanReadPage(ctx context.Context, r *types.Page) bool {
|
||||
return svc.can(ctx, r, "read")
|
||||
}
|
||||
|
||||
func (svc accessControl) FilterReadablePages(ctx context.Context) *permissions.ResourceFilter {
|
||||
return svc.permissions.ResourceFilter(ctx, types.PagePermissionResource, "read", permissions.Deny)
|
||||
}
|
||||
|
||||
func (svc accessControl) CanUpdatePage(ctx context.Context, r *types.Page) bool {
|
||||
return svc.can(ctx, r, "update")
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza-server/pkg/permissions"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -31,6 +32,8 @@ type (
|
||||
CanReadChart(context.Context, *types.Chart) bool
|
||||
CanUpdateChart(context.Context, *types.Chart) bool
|
||||
CanDeleteChart(context.Context, *types.Chart) bool
|
||||
|
||||
FilterReadableCharts(ctx context.Context) *permissions.ResourceFilter
|
||||
}
|
||||
|
||||
ChartService interface {
|
||||
@@ -99,15 +102,13 @@ func (svc chart) checkPermissions(c *types.Chart, err error) (*types.Chart, erro
|
||||
}
|
||||
|
||||
func (svc chart) Find(filter types.ChartFilter) (set types.ChartSet, f types.ChartFilter, err error) {
|
||||
f.IsReadable = svc.ac.FilterReadableCharts(svc.ctx)
|
||||
|
||||
set, f, err = svc.chartRepo.Find(filter)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
set, _ = set.Filter(func(m *types.Chart) (bool, error) {
|
||||
return svc.ac.CanReadChart(svc.ctx, m), nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza-server/pkg/permissions"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -32,6 +33,8 @@ type (
|
||||
CanReadModule(context.Context, *types.Module) bool
|
||||
CanUpdateModule(context.Context, *types.Module) bool
|
||||
CanDeleteModule(context.Context, *types.Module) bool
|
||||
|
||||
FilterReadableModules(ctx context.Context) *permissions.ResourceFilter
|
||||
}
|
||||
|
||||
ModuleService interface {
|
||||
@@ -120,6 +123,8 @@ func (svc module) loader(m *types.Module, err error) (*types.Module, error) {
|
||||
}
|
||||
|
||||
func (svc module) Find(filter types.ModuleFilter) (set types.ModuleSet, f types.ModuleFilter, err error) {
|
||||
f.IsReadable = svc.ac.FilterReadableModules(svc.ctx)
|
||||
|
||||
set, f, err = svc.moduleRepo.Find(filter)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -32,6 +32,8 @@ type (
|
||||
CanDeleteNamespace(context.Context, *types.Namespace) bool
|
||||
|
||||
Grant(ctx context.Context, rr ...*permissions.Rule) error
|
||||
|
||||
FilterReadableNamespaces(ctx context.Context) *permissions.ResourceFilter
|
||||
}
|
||||
|
||||
NamespaceService interface {
|
||||
@@ -95,15 +97,13 @@ func (svc namespace) checkPermissions(p *types.Namespace, err error) (*types.Nam
|
||||
}
|
||||
|
||||
func (svc namespace) Find(filter types.NamespaceFilter) (set types.NamespaceSet, f types.NamespaceFilter, err error) {
|
||||
f.IsReadable = svc.ac.FilterReadableNamespaces(svc.ctx)
|
||||
|
||||
set, f, err = svc.namespaceRepo.Find(filter)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
set, _ = set.Filter(func(ns *types.Namespace) (bool, error) {
|
||||
return svc.ac.CanReadNamespace(svc.ctx, ns), nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/handle"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza-server/pkg/permissions"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -32,6 +33,8 @@ type (
|
||||
CanReadPage(context.Context, *types.Page) bool
|
||||
CanUpdatePage(context.Context, *types.Page) bool
|
||||
CanDeletePage(context.Context, *types.Page) bool
|
||||
|
||||
FilterReadablePages(ctx context.Context) *permissions.ResourceFilter
|
||||
}
|
||||
|
||||
PageService interface {
|
||||
@@ -118,21 +121,25 @@ func (svc page) FindBySelfID(namespaceID, parentID uint64) (pp types.PageSet, f
|
||||
return nil, f, ErrNamespaceRequired.withStack()
|
||||
}
|
||||
|
||||
return svc.filterPageSetByPermission(svc.pageRepo.Find(types.PageFilter{
|
||||
return svc.pageRepo.Find(types.PageFilter{
|
||||
NamespaceID: namespaceID,
|
||||
ParentID: parentID,
|
||||
|
||||
// This will enable parentID=0 query
|
||||
Root: true,
|
||||
}))
|
||||
|
||||
IsReadable: svc.ac.FilterReadablePages(svc.ctx),
|
||||
})
|
||||
}
|
||||
|
||||
func (svc page) Find(filter types.PageFilter) (set types.PageSet, f types.PageFilter, err error) {
|
||||
f.IsReadable = svc.ac.FilterReadablePages(svc.ctx)
|
||||
|
||||
if filter.NamespaceID == 0 {
|
||||
return nil, f, ErrNamespaceRequired.withStack()
|
||||
}
|
||||
|
||||
return svc.filterPageSetByPermission(svc.pageRepo.Find(filter))
|
||||
return svc.pageRepo.Find(filter)
|
||||
}
|
||||
|
||||
func (svc page) Tree(namespaceID uint64) (pages types.PageSet, err error) {
|
||||
@@ -144,11 +151,12 @@ func (svc page) Tree(namespaceID uint64) (pages types.PageSet, err error) {
|
||||
tree types.PageSet
|
||||
filter = types.PageFilter{
|
||||
NamespaceID: namespaceID,
|
||||
IsReadable: svc.ac.FilterReadablePages(svc.ctx),
|
||||
}
|
||||
)
|
||||
|
||||
return tree, svc.db.Transaction(func() (err error) {
|
||||
if pages, _, err = svc.filterPageSetByPermission(svc.pageRepo.Find(filter)); err != nil {
|
||||
if pages, _, err = svc.pageRepo.Find(filter); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -176,19 +184,6 @@ func (svc page) Tree(namespaceID uint64) (pages types.PageSet, err error) {
|
||||
})
|
||||
}
|
||||
|
||||
func (svc page) filterPageSetByPermission(pp types.PageSet, f types.PageFilter, err error) (types.PageSet, types.PageFilter, error) {
|
||||
if err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
|
||||
// @todo Filter-by-permission can/will mess up filter's count & paging...
|
||||
pp, err = pp.Filter(func(m *types.Page) (bool, error) {
|
||||
return svc.ac.CanReadPage(svc.ctx, m), nil
|
||||
})
|
||||
|
||||
return pp, f, err
|
||||
}
|
||||
|
||||
func (svc page) Reorder(namespaceID, selfID uint64, pageIDs []uint64) error {
|
||||
if ns, err := svc.loadNamespace(namespaceID); err != nil {
|
||||
return err
|
||||
|
||||
@@ -46,6 +46,9 @@ type (
|
||||
PerPage uint `json:"perPage"`
|
||||
// Sort string `json:"sort"`
|
||||
Count uint `json:"count"`
|
||||
|
||||
// Resource permission check filter
|
||||
IsReadable *permissions.ResourceFilter `json:"-"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ type (
|
||||
PerPage uint `json:"perPage"`
|
||||
// Sort string `json:"sort"`
|
||||
Count uint `json:"count"`
|
||||
|
||||
// Resource permission check filter
|
||||
IsReadable *permissions.ResourceFilter `json:"-"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ type (
|
||||
PerPage uint `json:"perPage"`
|
||||
Sort string `json:"sort"`
|
||||
Count uint `json:"count"`
|
||||
|
||||
// Resource permission check filter
|
||||
IsReadable *permissions.ResourceFilter `json:"-"`
|
||||
}
|
||||
|
||||
NamespaceMeta struct {
|
||||
|
||||
@@ -60,6 +60,9 @@ type (
|
||||
Page uint `json:"page"`
|
||||
PerPage uint `json:"perPage"`
|
||||
Count uint `json:"count"`
|
||||
|
||||
// Resource permission check filter
|
||||
IsReadable *permissions.ResourceFilter `json:"-"`
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user