add(system) permissions helper service and checks

This commit is contained in:
Mitja Zivkovic
2019-03-11 11:47:36 +01:00
committed by Denis Arh
parent 73c9debe2f
commit 05006f7dd8
4 changed files with 151 additions and 24 deletions
+6 -6
View File
@@ -28,8 +28,8 @@ type (
MoveByID(id, targetOrganisationID uint64) error
MemberFindByRoleID(roleID uint64) ([]*types.RoleMember, error)
MemberAddByID(id, userID uint64) error
MemberRemoveByID(id, userID uint64) error
MemberAddByID(roleID, userID uint64) error
MemberRemoveByID(roleID, userID uint64) error
}
role struct {
@@ -147,17 +147,17 @@ func (r *role) MemberFindByRoleID(roleID uint64) (mm []*types.RoleMember, err er
return rval, r.db().Select(&rval, sql, roleID)
}
func (r *role) MemberAddByID(id, userID uint64) error {
func (r *role) MemberAddByID(roleID, userID uint64) error {
mod := &types.RoleMember{
RoleID: id,
RoleID: roleID,
UserID: userID,
}
return r.db().Replace(r.members, mod)
}
func (r *role) MemberRemoveByID(id, userID uint64) error {
func (r *role) MemberRemoveByID(roleID, userID uint64) error {
mod := &types.RoleMember{
RoleID: id,
RoleID: roleID,
UserID: userID,
}
return r.db().Delete(r.members, mod, "rel_role", "rel_user")
+83
View File
@@ -0,0 +1,83 @@
package service
import (
"context"
internalRules "github.com/crusttech/crust/internal/rules"
"github.com/crusttech/crust/system/repository"
"github.com/crusttech/crust/system/types"
)
type (
permissions struct {
db db
ctx context.Context
rules RulesService
}
PermissionsService interface {
With(context.Context) PermissionsService
CanCreateOrganisation() bool
CanCreateRole() bool
CanCreateApplication() bool
CanReadRole(rl *types.Role) bool
CanUpdateRole(rl *types.Role) bool
CanDeleteRole(rl *types.Role) bool
CanManageRoleMembers(rl *types.Role) bool
}
)
func Permissions() PermissionsService {
return (&permissions{
rules: DefaultRules,
}).With(context.Background())
}
func (p *permissions) With(ctx context.Context) PermissionsService {
db := repository.DB(ctx)
return &permissions{
db: db,
ctx: ctx,
rules: p.rules.With(ctx),
}
}
func (p *permissions) CanCreateOrganisation() bool {
return p.checkAccess("system", "application.create")
}
func (p *permissions) CanCreateRole() bool {
return p.checkAccess("system", "role.create")
}
func (p *permissions) CanCreateApplication() bool {
return p.checkAccess("system", "application.create")
}
func (p *permissions) CanReadRole(rl *types.Role) bool {
return p.checkAccess(rl.Resource().String(), "read")
}
func (p *permissions) CanUpdateRole(rl *types.Role) bool {
return p.checkAccess(rl.Resource().String(), "update")
}
func (p *permissions) CanDeleteRole(rl *types.Role) bool {
return p.checkAccess(rl.Resource().String(), "delete")
}
func (p *permissions) CanManageRoleMembers(rl *types.Role) bool {
return p.checkAccess(rl.Resource().String(), "members.manage")
}
func (p *permissions) checkAccess(resource string, operation string, fallbacks ...internalRules.CheckAccessFunc) bool {
access := p.rules.Check(resource, operation, fallbacks...)
if access == internalRules.Allow {
return true
}
return false
}
+60 -18
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
role repository.RoleRepository
}
@@ -39,36 +42,62 @@ type (
)
func Role() RoleService {
return (&role{}).With(context.Background())
return (&role{
prm: DefaultPermissions,
}).With(context.Background())
}
func (svc *role) With(ctx context.Context) RoleService {
db := repository.DB(ctx)
return &role{
db: db,
ctx: ctx,
db: db,
ctx: ctx,
prm: svc.prm.With(ctx),
role: repository.Role(ctx, db),
}
}
func (svc *role) FindByID(id uint64) (*types.Role, error) {
// @todo: permission check if current user has access to this role
return svc.role.FindByID(id)
role, err := svc.role.FindByID(id)
if err != nil {
return nil, err
}
if !svc.prm.CanReadRole(role) {
return nil, errors.New("Not allowed to read role")
}
return role, nil
}
func (svc *role) Find(filter *types.RoleFilter) ([]*types.Role, error) {
// @todo: permission check to return only roles that current user has access to
return svc.role.Find(filter)
roles, err := svc.role.Find(filter)
if err != nil {
return nil, err
}
ret := []*types.Role{}
for _, role := range roles {
if svc.prm.CanReadRole(role) {
ret = append(ret, role)
}
}
return ret, nil
}
func (svc *role) Create(mod *types.Role) (*types.Role, error) {
// @todo: permission check if current user can add/edit role
if !svc.prm.CanCreateRole() {
return nil, errors.New("Not allowed to create role")
}
return svc.role.Create(mod)
}
func (svc *role) Update(mod *types.Role) (t *types.Role, err error) {
// @todo: permission check if current user can add/edit role
if !svc.prm.CanUpdateRole(mod) {
return nil, errors.New("Not allowed to update role")
}
// @todo: make sure archived & deleted entries can not be edited
return t, svc.db.Transaction(func() (err error) {
@@ -91,7 +120,11 @@ func (svc *role) Update(mod *types.Role) (t *types.Role, err error) {
func (svc *role) Delete(id uint64) error {
// @todo: make history unavailable
// @todo: notify users that role has been removed (remove from web UI)
// @todo: permissions check if current user can remove role
rl := &types.Role{ID: id}
if !svc.prm.CanDeleteRole(rl) {
return errors.New("Not allowed to delete role")
}
return svc.role.DeleteByID(id)
}
@@ -120,18 +153,27 @@ func (svc *role) Move(id, targetOrganisationID uint64) error {
}
func (svc *role) MemberList(roleID uint64) ([]*types.RoleMember, error) {
// @todo: permission check if current user can read role members
rl := &types.Role{ID: roleID}
if !svc.prm.CanManageRoleMembers(rl) {
return nil, errors.New("Not allowed to manage role members")
}
return svc.role.MemberFindByRoleID(roleID)
}
func (svc *role) MemberAdd(id, userID uint64) error {
// @todo: permission check if current user can add user in to a role
return svc.role.MemberAddByID(id, userID)
func (svc *role) MemberAdd(roleID, userID uint64) error {
rl := &types.Role{ID: roleID}
if !svc.prm.CanManageRoleMembers(rl) {
return errors.New("Not allowed to manage role members")
}
return svc.role.MemberAddByID(roleID, userID)
}
func (svc *role) MemberRemove(id, userID uint64) error {
// @todo: permission check if current user can remove user from a role
return svc.role.MemberRemoveByID(id, userID)
func (svc *role) MemberRemove(roleID, userID uint64) error {
rl := &types.Role{ID: roleID}
if !svc.prm.CanManageRoleMembers(rl) {
return errors.New("Not allowed to manage role members")
}
return svc.role.MemberRemoveByID(roleID, userID)
}
var _ RoleService = &role{}
+2
View File
@@ -18,6 +18,7 @@ var (
DefaultRules RulesService
DefaultOrganisation OrganisationService
DefaultApplication ApplicationService
DefaultPermissions PermissionsService
)
func Init() {
@@ -28,5 +29,6 @@ func Init() {
DefaultRules = Rules()
DefaultOrganisation = Organisation()
DefaultApplication = Application()
DefaultPermissions = Permissions()
})
}