From f712e5e35205e52775ff671cc3f34d37f80fe60d Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Wed, 12 Aug 2020 19:03:06 +0200 Subject: [PATCH] Add RBAC operation for impersonation --- system/service/access_control.go | 5 +++++ system/service/auth.go | 23 +++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/system/service/access_control.go b/system/service/access_control.go index b5c0b6524..efda19445 100644 --- a/system/service/access_control.go +++ b/system/service/access_control.go @@ -161,6 +161,10 @@ func (svc accessControl) CanDeleteUser(ctx context.Context, u *types.User) bool return svc.can(ctx, u, "delete") } +func (svc accessControl) CanImpersonateUser(ctx context.Context, u *types.User) bool { + return svc.can(ctx, u, "impersonate", permissions.Denied) +} + func (svc accessControl) CanUnmaskEmail(ctx context.Context, u *types.User) bool { if internalAuth.GetIdentityFromContext(ctx).Identity() == u.ID { // Make an exception when users are reading their own info @@ -256,6 +260,7 @@ func (svc accessControl) Whitelist() permissions.Whitelist { "unsuspend", "unmask.email", "unmask.name", + "impersonate", ) wl.Set( diff --git a/system/service/auth.go b/system/service/auth.go index a3fc17773..16d4ddfd0 100644 --- a/system/service/auth.go +++ b/system/service/auth.go @@ -3,7 +3,6 @@ package service import ( "context" "fmt" - "github.com/cortezaproject/corteza-server/pkg/slice" "regexp" "strconv" "time" @@ -28,6 +27,7 @@ type ( ctx context.Context actionlog actionlog.Recorder + ac authAccessController eventbus eventDispatcher subscription authSubscriptionChecker @@ -69,6 +69,10 @@ type ( changePassword(uint64, string) error } + authAccessController interface { + CanImpersonateUser(context.Context, *types.User) bool + } + authSubscriptionChecker interface { CanRegister(uint) error } @@ -96,6 +100,7 @@ func defaultProviderValidator(provider string) error { func Auth(ctx context.Context) AuthService { return (&auth{ eventbus: eventbus.Service(), + ac: DefaultAccessControl, subscription: CurrentSubscription, settings: CurrentSettings, notifications: DefaultAuthNotification, @@ -123,6 +128,7 @@ func (svc auth) With(ctx context.Context) AuthService { users: repository.User(ctx, db), roles: repository.Role(ctx, db), + ac: svc.ac, subscription: svc.subscription, settings: svc.settings, notifications: svc.notifications, @@ -603,24 +609,17 @@ func (svc auth) SetPassword(userID uint64, password string) (err error) { func (svc auth) Impersonate(userID uint64) (u *types.User, err error) { var ( aam = &authActionProps{user: u} - - identity = internalAuth.GetIdentityFromContext(svc.ctx) ) err = func() error { - if !slice.HasUint64(identity.Roles(), permissions.AdminsRoleID) { - // A primitive access control - // - // For now, we do not want to add or change RBAC operation-set - // and we just check if user that wants to impersonate someone - // is member of administrators - return AuthErrNotAllowedToImpersonate() - } - if u, err = svc.users.FindByID(userID); err != nil { return err } + if !svc.ac.CanImpersonateUser(svc.ctx, u) { + return AuthErrNotAllowedToImpersonate() + } + return err }()