add(system) permissions helper service and checks
This commit is contained in:
committed by
Denis Arh
parent
73c9debe2f
commit
05006f7dd8
@@ -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")
|
||||
|
||||
@@ -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
@@ -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{}
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user