From 9da9f7eb7882efb2e68efcddce4a42c39cda6018 Mon Sep 17 00:00:00 2001 From: Senad Uka Date: Thu, 3 May 2018 07:57:08 +0200 Subject: [PATCH 1/4] Upstream sync --- config.dev.toml | 1 - config.prd.toml | 1 - config.stg.toml | 1 - data/datamysql/notification.go | 4 +- infra/cache/cache.go | 3 +- infra/config/config.go | 2 - server/authorization/authorization.go | 1 + server/authorization/organization.go | 28 +++++++++ server/authorization/profile.go | 62 +++++++++++++++++++ server/authorization/user.go | 86 ++++++++++++++++++++++++++ server/router/routeutils/response.go | 5 ++ server/router/usersroute/controller.go | 5 ++ server/serverconfig/authorization.go | 2 - server/serverconfig/serverconfig.go | 2 +- 14 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 server/authorization/authorization.go create mode 100644 server/authorization/organization.go create mode 100644 server/authorization/profile.go create mode 100644 server/authorization/user.go diff --git a/config.dev.toml b/config.dev.toml index 522d299..9919890 100644 --- a/config.dev.toml +++ b/config.dev.toml @@ -37,7 +37,6 @@ db = 0 pass = "3rdaP3KL2x%V" prefix = "nemt-portal-api-dev" default-expiration = "5m" -master-name = "devmaster01" [log] log-to-file = false diff --git a/config.prd.toml b/config.prd.toml index cf9324c..d8309e8 100644 --- a/config.prd.toml +++ b/config.prd.toml @@ -37,7 +37,6 @@ db = 0 pass = "3rdaP3KL2x%V" prefix = "portal-api-prod" default-expiration = "5m" -master-name = "master01" [log] log-to-file = false diff --git a/config.stg.toml b/config.stg.toml index 6375f45..050b811 100644 --- a/config.stg.toml +++ b/config.stg.toml @@ -37,7 +37,6 @@ db = 0 pass = "3rdaP3KL2x%V" prefix = "portal-api-test" default-expiration = "5m" -master-name = "devmaster01" [log] log-to-file = false diff --git a/data/datamysql/notification.go b/data/datamysql/notification.go index c6b9166..3d5f834 100644 --- a/data/datamysql/notification.go +++ b/data/datamysql/notification.go @@ -80,9 +80,7 @@ func (c *notificationRepo) getQuery() string { INNER JOIN tab_login e ON c.user_id = e.user_id INNER JOIN tab_login f - ON d.user_id = f.user_id - INNER JOIN tab_ride g - ON g.ride_id = a.ride_id ` + ON d.user_id = f.user_id` } func (c *notificationRepo) GetLastNotificationFromPhoneNumber(notificationType string, phoneNumber string, status string) (entity.Notification, error) { diff --git a/infra/cache/cache.go b/infra/cache/cache.go index 8c4eb11..d7c4f31 100644 --- a/infra/cache/cache.go +++ b/infra/cache/cache.go @@ -31,11 +31,10 @@ type RedisCache struct { func Instance(cfg *config.Config) contract.CacheManager { once.Do(func() { client := redis.NewFailoverClient(&redis.FailoverOptions{ - MasterName: cfg.Cache.Master, + MasterName: "master01", SentinelAddrs: []string{fmt.Sprintf("%s:%v", cfg.Cache.Server, cfg.Cache.Port)}, Password: cfg.Cache.Pass, DB: cfg.Cache.DB, - MaxRetries: 10, }) instance = &RedisCache{cfg, client} diff --git a/infra/config/config.go b/infra/config/config.go index d3b1f98..2497985 100644 --- a/infra/config/config.go +++ b/infra/config/config.go @@ -119,7 +119,6 @@ type CacheConfig struct { Pass string Prefix string DefaultExpiration time.Duration - Master string } // CacheConfig represents the configuration values about the documentation config. @@ -195,7 +194,6 @@ func Read() (*Config, error) { Pass: viper.GetString("cache.pass"), Prefix: viper.GetString("cache.prefix"), DefaultExpiration: viper.GetDuration("cache.default-expiration"), - Master: viper.GetString("cache.master-name"), }, Lyft: LyftConfig{ Client: viper.GetString("lyft.key"), diff --git a/server/authorization/authorization.go b/server/authorization/authorization.go new file mode 100644 index 0000000..9f58f24 --- /dev/null +++ b/server/authorization/authorization.go @@ -0,0 +1 @@ +package authorization diff --git a/server/authorization/organization.go b/server/authorization/organization.go new file mode 100644 index 0000000..7b42fa6 --- /dev/null +++ b/server/authorization/organization.go @@ -0,0 +1,28 @@ +package authorization + +import ( + "fmt" + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" +) + +func isAChildOrganization(potentialParent viewmodel.Organization, potentialChild viewmodel.Organization) bool { + for _, org := range potentialParent.ChildOrgs { + if potentialChild.UUID == org.UUID { + return true + } + } + return false +} + +func isSameOrganization(organizationA viewmodel.Organization, organizationB viewmodel.Organization) bool { + return organizationA.UUID == organizationB.UUID +} + +func grabOrgFromUser(user viewmodel.User) (viewmodel.Organization, error) { + if len(user.Organizations) < 1 { + return viewmodel.Organization{}, fmt.Errorf("User has no organizations %v", user) + } + + return user.Organizations[0], nil +} diff --git a/server/authorization/profile.go b/server/authorization/profile.go new file mode 100644 index 0000000..1a43031 --- /dev/null +++ b/server/authorization/profile.go @@ -0,0 +1,62 @@ +package authorization + +import ( + "fmt" + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" +) + +const ( + superAdmin = "AD" + scheduler = "SP" + support = "SPT" + member = "US" + brighterDevAdmin = "BDCAD" + bcbsiAdmin = "BCBSIAD" + planAdmin = "PLANAD" + providerAdmin = "SCHDAD" +) + +func grabProfileFromUser(user viewmodel.User) (viewmodel.Profile, error) { + if len(user.Profiles) < 1 { + return viewmodel.Profile{}, fmt.Errorf("User has no profiles %v", user) + } + return user.Profiles[0], nil +} + +func morePrivileged(who viewmodel.Profile, towardsWhom viewmodel.Profile) bool { + order := []string{superAdmin, brighterDevAdmin, bcbsiAdmin, planAdmin, providerAdmin, support, scheduler, member} + for _, value := range order { + if value == who.Key { + return true + } + + if value == towardsWhom.Key { + return false + } + } + // should hapen only in case profile key is empty + // and that's something fishy so let's deny! + return false +} + +func equallyOrMorePrivileged(who viewmodel.Profile, towardsWhom viewmodel.Profile) bool { + if who.Key == towardsWhom.Key { + return true + } + + return morePrivileged(who, towardsWhom) + +} + +func lessPrivilegedThanAdmin(who viewmodel.Profile) bool { + switch who.Key { + case member: + return true + case scheduler: + return true + case support: + return true + } + return false +} diff --git a/server/authorization/user.go b/server/authorization/user.go new file mode 100644 index 0000000..6e23a4c --- /dev/null +++ b/server/authorization/user.go @@ -0,0 +1,86 @@ +package authorization + +import "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" + +/* +CanCreateUser returns true if currentUser is allowed to create updatingUser according to +authorization rules +*/ +func CanCreateUser(currentUser viewmodel.User, updatingUser viewmodel.User) bool { + + if len(currentUser.Profiles) < 1 { + return false + } + + if len(updatingUser.Profiles) < 1 { + return false + } + + currentUserOrganization, err := grabOrgFromUser(currentUser) + if err != nil { + return false + } + + updatingUserOrganization, err := grabOrgFromUser(updatingUser) + if err != nil { + return false + } + + currentUserRole, err := grabProfileFromUser(currentUser) + if err != nil { + return false + } + + updatingUserRole, err := grabProfileFromUser(updatingUser) + if err != nil { + return false + } + + /* + Admin Provider + Manage all Authorized Users of the provider Organization or child organization + + The (Provider) Admin can manage Authorized Users of their Parent/ Top-level Org , but not Admins + */ + + currentUserHigherOrEqualOrg := isSameOrganization(currentUserOrganization, updatingUserOrganization) || isAChildOrganization(currentUserOrganization, updatingUserOrganization) + currentUserLowerOrg := isAChildOrganization(updatingUserOrganization, currentUserOrganization) + if currentUserRole.Key == providerAdmin && currentUserHigherOrEqualOrg && equallyOrMorePrivileged(currentUserRole, updatingUserRole) { + return true + } + if currentUserRole.Key == providerAdmin && currentUserLowerOrg && lessPrivilegedThanAdmin(updatingUserRole) { + return true + } + + /* Admin BCBSI + Manage all Authorized Users except Admins + + return false + */ + + if currentUserRole.Key == bcbsiAdmin && lessPrivilegedThanAdmin(updatingUserRole) { + return true + } + + /* Admin Technical Support Manage all Authorized Users except Admins */ + + if currentUserRole.Key == brighterDevAdmin && lessPrivilegedThanAdmin(updatingUserRole) { + return true + } + + /* Admin Plan Manage all Authorized Users of a single participating Plan except Admins */ + + if currentUserRole.Key == planAdmin && lessPrivilegedThanAdmin(updatingUserRole) && isSameOrganization(currentUserOrganization, updatingUserOrganization) { + return true + } + + /* Super Admin Technical Support + Manage all Members, INCLUDING Admins */ + + if currentUserRole.Key == superAdmin { + return true + } + + return false + +} diff --git a/server/router/routeutils/response.go b/server/router/routeutils/response.go index 0d95b6f..bb4404b 100644 --- a/server/router/routeutils/response.go +++ b/server/router/routeutils/response.go @@ -49,6 +49,11 @@ func ResponseAPIAuthError(c echo.Context, message string, redirect bool) error { return ResponseAPIError(c, http.StatusUnauthorized, message, redirect) } +// ResponseAPIAuthorizationError returns a standard API auth error to the response +func ResponseAPIAuthorizationError(c echo.Context) error { + return ResponseAPIError(c, http.StatusForbidden, "Forbidden by controller", false) +} + // ResponseAPIServiceError returns a standard API service unavailable error to the response func ResponseAPIServiceError(c echo.Context, message string) error { return ResponseAPIError(c, http.StatusServiceUnavailable, message, false) diff --git a/server/router/usersroute/controller.go b/server/router/usersroute/controller.go index 34ff679..55fc78a 100644 --- a/server/router/usersroute/controller.go +++ b/server/router/usersroute/controller.go @@ -13,6 +13,7 @@ import ( "bitbucket.org/nemt/nemt-portal-api/infra/auth" "bitbucket.org/nemt/nemt-portal-api/infra/cache" "bitbucket.org/nemt/nemt-portal-api/infra/config" + "bitbucket.org/nemt/nemt-portal-api/server/authorization" "bitbucket.org/nemt/nemt-portal-api/server/router/routeutils" "github.com/labstack/echo" ) @@ -389,6 +390,10 @@ func (c *controller) handlePortal(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + if !authorization.CanCreateUser(authUser, user) { + return routeutils.ResponseAPIAuthorizationError(ctx) + } + if len(user.Profiles) == 0 { return routeutils.ResponseAPIAuthError(ctx, "profile is required", false) } diff --git a/server/serverconfig/authorization.go b/server/serverconfig/authorization.go index 1797e3f..d61c762 100644 --- a/server/serverconfig/authorization.go +++ b/server/serverconfig/authorization.go @@ -193,8 +193,6 @@ func (a *Config) objectRelation(object interface{}, currentUser viewmodel.User) case viewmodel.User: if obj.ID == currentUser.ID { return "[self]" - } else { - return "[other]" } } return "[other]" diff --git a/server/serverconfig/serverconfig.go b/server/serverconfig/serverconfig.go index 04687a3..6b34b93 100644 --- a/server/serverconfig/serverconfig.go +++ b/server/serverconfig/serverconfig.go @@ -18,7 +18,7 @@ func SetMiddlewares(server *echo.Echo, cfg *config.Config, log *logger.Logger, s setCORSMiddleware(server, cfg) setBodyLimitMiddleware(server) setRateLimitMiddleware(server) - //setAuthorizationMiddleware(server, log, cfg, appsvc) + setAuthorizationMiddleware(server, log, cfg, appsvc) err := setJWTMiddleware(server, cfg) if err != nil { -- 2.47.3 From ef783567b9b5d382bec42b8281d69dd87a7a7338 Mon Sep 17 00:00:00 2001 From: GotPPay Date: Thu, 3 May 2018 18:29:24 +0200 Subject: [PATCH 2/4] create structure for rules checking --- server/authorization/address.go | 51 +++++++++++++++++++ server/authorization/contact.go | 51 +++++++++++++++++++ server/authorization/organization.go | 41 +++++++++++++++ server/router/organizationroute/controller.go | 25 +++++++++ 4 files changed, 168 insertions(+) create mode 100644 server/authorization/address.go create mode 100644 server/authorization/contact.go diff --git a/server/authorization/address.go b/server/authorization/address.go new file mode 100644 index 0000000..ea0d4a4 --- /dev/null +++ b/server/authorization/address.go @@ -0,0 +1,51 @@ +package authorization + +import ( + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" +) + +func CanCreateAddress(user viewmodel.User, address viewmodel.OrganizationAddress) bool { + //TODO : implement checking + + userRole, err := grabProfileFromUser(user) + if err != nil { + return false + } + + /*Admin Provider Manage all Organizations */ + if userRole.Key == providerAdmin{ + return true + } + + /* Admin BCBSI Manage all Organizations */ + if userRole.Key == bcbsiAdmin{ + return true + } + + /* Admin Technical Support Manage all Organizations */ + if userRole.Key == brighterDevAdmin{ + return true + } + + /* Admin Plan + Manage the authenticated Authorized User's Plan (Organization) and children of this Plan*/ + if userRole.Key == planAdmin { + return true + } + + /* Super Admin Technical Support Manage all Organizations*/ + if userRole.Key == superAdmin { + return true + } + + return false +} + +func CanUpdateAddress(user viewmodel.User, address viewmodel.OrganizationAddress) bool { + return CanCreateAddress(user, address) +} + +func CanDeleteAddress(user viewmodel.User, address viewmodel.OrganizationAddress) bool { + return CanCreateAddress(user, address) +} \ No newline at end of file diff --git a/server/authorization/contact.go b/server/authorization/contact.go new file mode 100644 index 0000000..13ade04 --- /dev/null +++ b/server/authorization/contact.go @@ -0,0 +1,51 @@ +package authorization + +import ( + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" +) + +func CanCreateContact(user viewmodel.User, contact viewmodel.OrganizationContact) bool { + //TODO : implement checking + + userRole, err := grabProfileFromUser(user) + if err != nil { + return false + } + + /*Admin Provider Manage all Organizations */ + if userRole.Key == providerAdmin{ + return true + } + + /* Admin BCBSI Manage all Organizations */ + if userRole.Key == bcbsiAdmin{ + return true + } + + /* Admin Technical Support Manage all Organizations */ + if userRole.Key == brighterDevAdmin{ + return true + } + + /* Admin Plan + Manage the authenticated Authorized User's Plan (Organization) and children of this Plan*/ + if userRole.Key == planAdmin { + return true + } + + /* Super Admin Technical Support Manage all Organizations*/ + if userRole.Key == superAdmin { + return true + } + + return false +} + +func CanUpdateContact(user viewmodel.User, contact viewmodel.OrganizationContact) bool { + return CanCreateContact(user, contact) +} + +func CanDeleteContact(user viewmodel.User, contact viewmodel.OrganizationContact) bool { + return CanCreateContact(user, contact) +} \ No newline at end of file diff --git a/server/authorization/organization.go b/server/authorization/organization.go index 7b42fa6..d6229e5 100644 --- a/server/authorization/organization.go +++ b/server/authorization/organization.go @@ -26,3 +26,44 @@ func grabOrgFromUser(user viewmodel.User) (viewmodel.Organization, error) { return user.Organizations[0], nil } + +func CanCreateOrganization(user viewmodel.User, organization viewmodel.Organization ) bool { + //TODO : implement checking + + userRole, err := grabProfileFromUser(user) + if err != nil { + return false + } + + /*Admin Provider Manage all Organizations */ + if userRole.Key == providerAdmin{ + return true + } + + /* Admin BCBSI Manage all Organizations */ + if userRole.Key == bcbsiAdmin{ + return true + } + + /* Admin Technical Support Manage all Organizations */ + if userRole.Key == brighterDevAdmin{ + return true + } + + /* Admin Plan + Manage the authenticated Authorized User's Plan (Organization) and children of this Plan*/ + if userRole.Key == planAdmin { + return true + } + + /* Super Admin Technical Support Manage all Organizations*/ + if userRole.Key == superAdmin { + return true + } + + return false +} + +func CanUpdateOrganization(user viewmodel.User, organization viewmodel.Organization) bool { + return CanCreateOrganization(user,organization) +} diff --git a/server/router/organizationroute/controller.go b/server/router/organizationroute/controller.go index 682a896..a1816f1 100644 --- a/server/router/organizationroute/controller.go +++ b/server/router/organizationroute/controller.go @@ -10,6 +10,7 @@ import ( "bitbucket.org/nemt/nemt-portal-api/infra/cache" "bitbucket.org/nemt/nemt-portal-api/infra/config" "bitbucket.org/nemt/nemt-portal-api/server/router/routeutils" + "bitbucket.org/nemt/nemt-portal-api/server/authorization" "github.com/labstack/echo" ) @@ -64,6 +65,11 @@ func (c *controller) handleAddOrganization(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + + if !authorization.CanCreateOrganization(authUser, org) { + return routeutils.ResponseAPIAuthorizationError(ctx) + } + org.Author.ID = authUser.ID org.LastEditor.ID = authUser.ID @@ -215,6 +221,10 @@ func (c *controller) handleRemoveAddress(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + if !authorization.CanDeleteAddress(authUser, address) { + return routeutils.ResponseAPIAuthorizationError(ctx) + } + address.UpdatedUser.ID = authUser.ID err = c.svc.Organization.InactivateOrganizationAddress(orgUUID, address, authUser) @@ -246,6 +256,11 @@ func (c *controller) handleAddAddress(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + + if !authorization.CanCreateAddress(authUser, address) { + return routeutils.ResponseAPIAuthorizationError(ctx) + } + address.CreatedUser.ID = authUser.ID address.UpdatedUser.ID = authUser.ID @@ -278,6 +293,11 @@ func (c *controller) handleRemoveContact(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + + if !authorization.CanDeleteContact(authUser, contact) { + return routeutils.ResponseAPIAuthorizationError(ctx) + } + contact.UpdatedUser.ID = authUser.ID err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact, authUser) @@ -309,6 +329,11 @@ func (c *controller) handleAddContact(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + + if !authorization.CanCreateContact(authUser, contact) { + return routeutils.ResponseAPIAuthorizationError(ctx) + } + contact.CreatedUser.ID = authUser.ID contact.UpdatedUser.ID = authUser.ID -- 2.47.3 From d820d47fcd38ae6f8a7c441b0c0868acde48557a Mon Sep 17 00:00:00 2001 From: GotPPay Date: Fri, 4 May 2018 16:36:51 +0200 Subject: [PATCH 3/4] implement rules checking for orgnz, addr and contact creation and update --- server/authorization/address.go | 46 ++--------------- server/authorization/contact.go | 46 ++--------------- server/authorization/organization.go | 49 +++++++++---------- server/router/organizationroute/controller.go | 42 ++++++++++++---- 4 files changed, 66 insertions(+), 117 deletions(-) diff --git a/server/authorization/address.go b/server/authorization/address.go index ea0d4a4..467fcc9 100644 --- a/server/authorization/address.go +++ b/server/authorization/address.go @@ -5,47 +5,11 @@ import ( "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" ) -func CanCreateAddress(user viewmodel.User, address viewmodel.OrganizationAddress) bool { - //TODO : implement checking - - userRole, err := grabProfileFromUser(user) - if err != nil { - return false - } - - /*Admin Provider Manage all Organizations */ - if userRole.Key == providerAdmin{ - return true - } - - /* Admin BCBSI Manage all Organizations */ - if userRole.Key == bcbsiAdmin{ - return true - } - - /* Admin Technical Support Manage all Organizations */ - if userRole.Key == brighterDevAdmin{ - return true - } - - /* Admin Plan - Manage the authenticated Authorized User's Plan (Organization) and children of this Plan*/ - if userRole.Key == planAdmin { - return true - } - - /* Super Admin Technical Support Manage all Organizations*/ - if userRole.Key == superAdmin { - return true - } - - return false +func CanCreateAddress(user viewmodel.User, organization viewmodel.Organization) bool { + //rules are the same for address creation and for organization creation + return CanCreateOrganization(user, organization) } -func CanUpdateAddress(user viewmodel.User, address viewmodel.OrganizationAddress) bool { - return CanCreateAddress(user, address) -} - -func CanDeleteAddress(user viewmodel.User, address viewmodel.OrganizationAddress) bool { - return CanCreateAddress(user, address) +func CanUpdateAddress(user viewmodel.User, organization viewmodel.Organization) bool { + return CanCreateAddress(user, organization) } \ No newline at end of file diff --git a/server/authorization/contact.go b/server/authorization/contact.go index 13ade04..97612f9 100644 --- a/server/authorization/contact.go +++ b/server/authorization/contact.go @@ -5,47 +5,11 @@ import ( "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" ) -func CanCreateContact(user viewmodel.User, contact viewmodel.OrganizationContact) bool { - //TODO : implement checking - - userRole, err := grabProfileFromUser(user) - if err != nil { - return false - } - - /*Admin Provider Manage all Organizations */ - if userRole.Key == providerAdmin{ - return true - } - - /* Admin BCBSI Manage all Organizations */ - if userRole.Key == bcbsiAdmin{ - return true - } - - /* Admin Technical Support Manage all Organizations */ - if userRole.Key == brighterDevAdmin{ - return true - } - - /* Admin Plan - Manage the authenticated Authorized User's Plan (Organization) and children of this Plan*/ - if userRole.Key == planAdmin { - return true - } - - /* Super Admin Technical Support Manage all Organizations*/ - if userRole.Key == superAdmin { - return true - } - - return false +func CanCreateContact(user viewmodel.User, organization viewmodel.Organization) bool { + //rules are the same for contact creation and for organization creation + return CanCreateOrganization(user, organization) } -func CanUpdateContact(user viewmodel.User, contact viewmodel.OrganizationContact) bool { - return CanCreateContact(user, contact) -} - -func CanDeleteContact(user viewmodel.User, contact viewmodel.OrganizationContact) bool { - return CanCreateContact(user, contact) +func CanUpdateContact(user viewmodel.User, organization viewmodel.Organization) bool { + return CanCreateAddress(user, organization) } \ No newline at end of file diff --git a/server/authorization/organization.go b/server/authorization/organization.go index d6229e5..07b0936 100644 --- a/server/authorization/organization.go +++ b/server/authorization/organization.go @@ -28,42 +28,41 @@ func grabOrgFromUser(user viewmodel.User) (viewmodel.Organization, error) { } func CanCreateOrganization(user viewmodel.User, organization viewmodel.Organization ) bool { - //TODO : implement checking - userRole, err := grabProfileFromUser(user) if err != nil { return false } - /*Admin Provider Manage all Organizations */ - if userRole.Key == providerAdmin{ + /* + Admin BCBSI + Admin Technical Support + Super Admin Technical Support + + Manage all Organizations*/ + if userRole.Key == bcbsiAdmin || userRole.Key == brighterDevAdmin || userRole.Key == superAdmin{ return true } - /* Admin BCBSI Manage all Organizations */ - if userRole.Key == bcbsiAdmin{ - return true + userOrg, err := grabOrgFromUser(user) + if err != nil{ + return false } - - /* Admin Technical Support Manage all Organizations */ - if userRole.Key == brighterDevAdmin{ - return true - } - - /* Admin Plan - Manage the authenticated Authorized User's Plan (Organization) and children of this Plan*/ - if userRole.Key == planAdmin { - return true - } - - /* Super Admin Technical Support Manage all Organizations*/ - if userRole.Key == superAdmin { - return true + + /* + Admin Provider + Admin Plan + + Manage the authenticated Authorized User's Organization and child Organizations */ + if userRole.Key == providerAdmin || userRole.Key == planAdmin{ + if isSameOrganization(userOrg, organization) || isAChildOrganization(userOrg, organization) { + return true + } + return false } return false } -func CanUpdateOrganization(user viewmodel.User, organization viewmodel.Organization) bool { - return CanCreateOrganization(user,organization) -} +func CanUpdateOrganization(user viewmodel.User, organization viewmodel.Organization) bool{ + return CanCreateOrganization(user, organization) +} \ No newline at end of file diff --git a/server/router/organizationroute/controller.go b/server/router/organizationroute/controller.go index a1816f1..1044379 100644 --- a/server/router/organizationroute/controller.go +++ b/server/router/organizationroute/controller.go @@ -133,6 +133,15 @@ func (c *controller) handleParent(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + organization, err := c.svc.Organization.GetByUUID(orgUUID, authUser) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + if !authorization.CanUpdateOrganization(authUser, organization){ + return routeutils.ResponseAPIAuthorizationError(ctx) + } + resp, err := c.svc.Organization.SetParentOrganization(orgUUID, parent.UUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) @@ -158,6 +167,15 @@ func (c *controller) handleChild(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + organization, err := c.svc.Organization.GetByUUID(orgUUID, authUser) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + if !authorization.CanUpdateOrganization(authUser, organization){ + return routeutils.ResponseAPIAuthorizationError(ctx) + } + _, err = c.svc.Organization.SetParentOrganization(child.UUID, orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) @@ -221,10 +239,6 @@ func (c *controller) handleRemoveAddress(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - if !authorization.CanDeleteAddress(authUser, address) { - return routeutils.ResponseAPIAuthorizationError(ctx) - } - address.UpdatedUser.ID = authUser.ID err = c.svc.Organization.InactivateOrganizationAddress(orgUUID, address, authUser) @@ -257,10 +271,17 @@ func (c *controller) handleAddAddress(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - if !authorization.CanCreateAddress(authUser, address) { + organization, err := c.svc.Organization.GetByUUID(orgUUID, authUser) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + if !authorization.CanCreateAddress(authUser, organization) { return routeutils.ResponseAPIAuthorizationError(ctx) } + return routeutils.ResponseAPIAuthorizationError(ctx) + address.CreatedUser.ID = authUser.ID address.UpdatedUser.ID = authUser.ID @@ -294,10 +315,6 @@ func (c *controller) handleRemoveContact(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - if !authorization.CanDeleteContact(authUser, contact) { - return routeutils.ResponseAPIAuthorizationError(ctx) - } - contact.UpdatedUser.ID = authUser.ID err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact, authUser) @@ -330,7 +347,12 @@ func (c *controller) handleAddContact(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - if !authorization.CanCreateContact(authUser, contact) { + organization, err := c.svc.Organization.GetByUUID(orgUUID, authUser) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + if !authorization.CanCreateContact(authUser, organization) { return routeutils.ResponseAPIAuthorizationError(ctx) } -- 2.47.3 From 9c1ccdcf68451b292457228f7346d31bd0027a82 Mon Sep 17 00:00:00 2001 From: GotPPay Date: Fri, 4 May 2018 16:57:19 +0200 Subject: [PATCH 4/4] added DELETE rule to authorization_policy --- authorization_policy.csv | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/authorization_policy.csv b/authorization_policy.csv index 107e45f..0f3e882 100644 --- a/authorization_policy.csv +++ b/authorization_policy.csv @@ -79,18 +79,23 @@ p, *, *, *, *, *, *, /v1/nemt/organization/type, GET p, AD, *, *, *, *, *, /v1/nemt/organization/*, GET p, AD, *, *, *, *, *, /v1/nemt/organization/*, POST p, AD, *, *, *, *, *, /v1/nemt/organization/*, PUT +p, AD, *, *, *, *, *, /v1/nemt/organization/*, DELETE p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, GET p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, POST p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, PUT +p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, DELETE p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, GET p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, POST p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, PUT +p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, DELETE p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, GET p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, POST p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, PUT +p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, DELETE p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, GET p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, POST p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, PUT +p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, DELETE p, SPT, *, programsupport, *, *, *, /v1/nemt/organization/*, GET p, SP, *, provider, *, *, *, /v1/nemt/organization, GET p, SP, *, plan, *, *, *, /v1/nemt/organization, GET @@ -108,4 +113,3 @@ p, BCBSIAD, *, bcbsi, *, *, *, /v1/nemt/eligibility, POST p, BDCAD, *, techsupport, *, *, *, /v1/nemt/eligibility, POST p, PLANAD, *, plan, *, *, *, /v1/nemt/eligibility, POST p, AD, *, *, *, *, *, /v1/nemt/eligibility, POST - -- 2.47.3