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 - diff --git a/server/authorization/address.go b/server/authorization/address.go new file mode 100644 index 0000000..467fcc9 --- /dev/null +++ b/server/authorization/address.go @@ -0,0 +1,15 @@ +package authorization + +import ( + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" +) + +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, 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 new file mode 100644 index 0000000..97612f9 --- /dev/null +++ b/server/authorization/contact.go @@ -0,0 +1,15 @@ +package authorization + +import ( + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" +) + +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, 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 7b42fa6..07b0936 100644 --- a/server/authorization/organization.go +++ b/server/authorization/organization.go @@ -26,3 +26,43 @@ func grabOrgFromUser(user viewmodel.User) (viewmodel.Organization, error) { return user.Organizations[0], nil } + +func CanCreateOrganization(user viewmodel.User, organization viewmodel.Organization ) bool { + userRole, err := grabProfileFromUser(user) + if err != nil { + return false + } + + /* + Admin BCBSI + Admin Technical Support + Super Admin Technical Support + + Manage all Organizations*/ + if userRole.Key == bcbsiAdmin || userRole.Key == brighterDevAdmin || userRole.Key == superAdmin{ + return true + } + + userOrg, err := grabOrgFromUser(user) + if err != nil{ + return false + } + + /* + 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) +} \ No newline at end of file diff --git a/server/router/organizationroute/controller.go b/server/router/organizationroute/controller.go index 682a896..1044379 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 @@ -127,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) @@ -152,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) @@ -246,6 +270,18 @@ func (c *controller) handleAddAddress(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + + 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 @@ -278,6 +314,7 @@ func (c *controller) handleRemoveContact(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + contact.UpdatedUser.ID = authUser.ID err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact, authUser) @@ -309,6 +346,16 @@ func (c *controller) handleAddContact(ctx echo.Context) error { if err != nil { return routeutils.HandleAPIError(ctx, err) } + + 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) + } + contact.CreatedUser.ID = authUser.ID contact.UpdatedUser.ID = authUser.ID