3
0

add(system) application permission check

This commit is contained in:
Mitja Zivkovic 2019-03-09 22:38:13 +01:00 committed by Denis Arh
parent 05006f7dd8
commit ab39783e50
4 changed files with 73 additions and 10 deletions

View File

@ -3,6 +3,7 @@ package service
import (
"context"
"github.com/pkg/errors"
"github.com/titpetric/factory"
"github.com/crusttech/crust/system/repository"
@ -14,6 +15,8 @@ type (
db *factory.DB
ctx context.Context
prm PermissionsService
application repository.ApplicationRepository
}
@ -30,7 +33,9 @@ type (
)
func Application() ApplicationService {
return (&application{}).With(context.Background())
return (&application{
prm: DefaultPermissions,
}).With(context.Background())
}
func (svc *application) With(ctx context.Context) ApplicationService {
@ -38,28 +43,51 @@ func (svc *application) With(ctx context.Context) ApplicationService {
return &application{
db: db,
ctx: ctx,
prm: svc.prm.With(ctx),
application: repository.Application(ctx, db),
}
}
func (svc *application) FindByID(id uint64) (*types.Application, error) {
// @todo: permission check if current user has access to this application
return svc.application.FindByID(id)
app, err := svc.application.FindByID(id)
if err != nil {
return nil, err
}
if !svc.prm.CanReadApplication(app) {
return nil, errors.New("Not allowed to access application")
}
return app, nil
}
func (svc *application) Find() (types.ApplicationSet, error) {
// @todo: permission check to return only applications that current user has access to
return svc.application.Find()
apps, err := svc.application.Find()
if err != nil {
return nil, err
}
ret := []*types.Application{}
for _, app := range apps {
if svc.prm.CanReadApplication(app) {
ret = append(ret, app)
}
}
return ret, nil
}
func (svc *application) Create(mod *types.Application) (*types.Application, error) {
// @todo: permission check if current user can add/edit application
if !svc.prm.CanCreateApplication() {
return nil, errors.New("Not allowed to create application")
}
return svc.application.Create(mod)
}
func (svc *application) Update(mod *types.Application) (t *types.Application, err error) {
// @todo: permission check if current user can add/edit application
if !svc.prm.CanUpdateApplication(mod) {
return nil, errors.New("Not allowed to update application")
}
// @todo: make sure archived & deleted entries can not be edited
return t, svc.db.Transaction(func() (err error) {
@ -83,7 +111,11 @@ func (svc *application) Update(mod *types.Application) (t *types.Application, er
func (svc *application) DeleteByID(id uint64) error {
// @todo: make history unavailable
// @todo: notify users that application has been removed (remove from web UI)
// @todo: permissions check if current user can remove application
app := &types.Application{ID: id}
if !svc.prm.CanDeleteApplication(app) {
return errors.New("Not allowed to delete application")
}
return svc.application.DeleteByID(id)
}

View File

@ -27,6 +27,10 @@ type (
CanUpdateRole(rl *types.Role) bool
CanDeleteRole(rl *types.Role) bool
CanManageRoleMembers(rl *types.Role) bool
CanReadApplication(app *types.Application) bool
CanUpdateApplication(app *types.Application) bool
CanDeleteApplication(app *types.Application) bool
}
)
@ -74,6 +78,18 @@ func (p *permissions) CanManageRoleMembers(rl *types.Role) bool {
return p.checkAccess(rl.Resource().String(), "members.manage")
}
func (p *permissions) CanReadApplication(app *types.Application) bool {
return p.checkAccess(app.Resource().String(), "read")
}
func (p *permissions) CanUpdateApplication(app *types.Application) bool {
return p.checkAccess(app.Resource().String(), "update")
}
func (p *permissions) CanDeleteApplication(app *types.Application) bool {
return p.checkAccess(app.Resource().String(), "delete")
}
func (p *permissions) checkAccess(resource string, operation string, fallbacks ...internalRules.CheckAccessFunc) bool {
access := p.rules.Check(resource, operation, fallbacks...)
if access == internalRules.Allow {

View File

@ -23,7 +23,7 @@ var (
"delete": true,
"members.manage": true,
},
"application:role": map[string]bool{
"system:application": map[string]bool{
"read": true,
"update": true,
"delete": true,

View File

@ -6,6 +6,8 @@ import (
"time"
"github.com/pkg/errors"
"github.com/crusttech/crust/internal/rules"
)
type (
@ -41,6 +43,19 @@ func (u *Application) Identity() uint64 {
return u.ID
}
// Resource returns a system resource ID for this type
func (u *Application) Resource() rules.Resource {
resource := rules.Resource{
Service: "system",
Scope: "application",
}
if u != nil {
resource.ID = u.ID
resource.Name = u.Name
}
return resource
}
func (au *ApplicationUnify) Scan(value interface{}) error {
switch value.(type) {
case nil: