diff --git a/application/applicationservice/organization.go b/application/applicationservice/organization.go index 9d4d635..e297d7f 100644 --- a/application/applicationservice/organization.go +++ b/application/applicationservice/organization.go @@ -35,37 +35,42 @@ func (s *organizationService) GetAllTypes() ([]viewmodel.OrganizationType, error return s.mapEntity.Organization.ToOrganizationTypeModelSlice(result), nil } -func (s *organizationService) GetByType(organizationTypeKey string) ([]viewmodel.Organization, error) { - result, err := s.svc.Organization.GetByType(organizationTypeKey) +func (s *organizationService) GetByType(organizationTypeKey string, user viewmodel.User) ([]viewmodel.Organization, error) { + userEntity := s.mapEntity.User.ToUserEntity(user) + result, err := s.svc.Organization.GetByType(organizationTypeKey, userEntity) if err != nil { return nil, err } + return s.mapEntity.Organization.ToOrganizationModelSlice(result), nil } -func (s *organizationService) GetByUUID(organizationUUID string) (viewmodel.Organization, error) { - result, err := s.svc.Organization.GetByUUID(organizationUUID) +func (s *organizationService) GetByUUID(organizationUUID string, user viewmodel.User) (viewmodel.Organization, error) { + userEntity := s.mapEntity.User.ToUserEntity(user) + result, err := s.svc.Organization.GetByUUID(organizationUUID, userEntity) if err != nil { return viewmodel.Organization{}, err } return s.mapEntity.Organization.ToOrganizationModel(result), nil } -func (s *organizationService) GetByName(name string, searchType string) ([]viewmodel.Organization, error) { - result, err := s.svc.Organization.GetByName(name, searchType) +func (s *organizationService) GetByName(name string, searchType string, user viewmodel.User) ([]viewmodel.Organization, error) { + userEntity := s.mapEntity.User.ToUserEntity(user) + result, err := s.svc.Organization.GetByName(name, searchType, userEntity) if err != nil { return nil, err } return s.mapEntity.Organization.ToOrganizationModelSlice(result), nil } -func (s *organizationService) SetParentOrganization(organizationUUID string, parentOrganizationUUID string) (viewmodel.Organization, error) { - child, err := s.svc.Organization.GetByUUID(organizationUUID) +func (s *organizationService) SetParentOrganization(organizationUUID string, parentOrganizationUUID string, user viewmodel.User) (viewmodel.Organization, error) { + userEntity := s.mapEntity.User.ToUserEntity(user) + child, err := s.svc.Organization.GetByUUID(organizationUUID, userEntity) if err != nil { return viewmodel.Organization{}, err } - parent, err := s.svc.Organization.GetByUUID(parentOrganizationUUID) + parent, err := s.svc.Organization.GetByUUID(parentOrganizationUUID, userEntity) if err != nil { return viewmodel.Organization{}, err } @@ -74,10 +79,11 @@ func (s *organizationService) SetParentOrganization(organizationUUID string, par return viewmodel.Organization{}, err } - return s.GetByUUID(organizationUUID) + return s.GetByUUID(organizationUUID, user) } -func (s *organizationService) InactivateOrganizationAddress(organizationUUID string, address viewmodel.OrganizationAddress) error { +func (s *organizationService) InactivateOrganizationAddress(organizationUUID string, address viewmodel.OrganizationAddress, userView viewmodel.User) error { + userEntity := s.mapEntity.User.ToUserEntity(userView) entityAddress := s.mapEntity.Organization.ToOrganizationAddressEntity(address) entityAddress.Organization = &entity.Organization{ UUID: organizationUUID, @@ -89,14 +95,15 @@ func (s *organizationService) InactivateOrganizationAddress(organizationUUID str } entityAddress.UpdatedUser = user - if err := s.svc.Organization.InactivateOrganizationAddress(entityAddress); err != nil { + if err := s.svc.Organization.InactivateOrganizationAddress(entityAddress, userEntity); err != nil { return err } else { return nil } } -func (s *organizationService) SetOrganizationAddress(organizationUUID string, address viewmodel.OrganizationAddress) (viewmodel.OrganizationAddress, error) { +func (s *organizationService) SetOrganizationAddress(organizationUUID string, address viewmodel.OrganizationAddress, userView viewmodel.User) (viewmodel.OrganizationAddress, error) { + userEntity := s.mapEntity.User.ToUserEntity(userView) entityAddress := s.mapEntity.Organization.ToOrganizationAddressEntity(address) entityAddress.Organization = &entity.Organization{ UUID: organizationUUID, @@ -110,7 +117,7 @@ func (s *organizationService) SetOrganizationAddress(organizationUUID string, ad entityAddress.CreatedUser = user entityAddress.UpdatedUser = user - entityAddress, err = s.svc.Organization.SetOrganizationAddress(entityAddress) + entityAddress, err = s.svc.Organization.SetOrganizationAddress(entityAddress, userEntity) if err != nil { return viewmodel.OrganizationAddress{}, err } @@ -118,7 +125,8 @@ func (s *organizationService) SetOrganizationAddress(organizationUUID string, ad return s.mapEntity.Organization.ToOrganizationAddressModel(entityAddress), nil } -func (s *organizationService) InactivateOrganizationContact(organizationUUID string, contact viewmodel.OrganizationContact) error { +func (s *organizationService) InactivateOrganizationContact(organizationUUID string, contact viewmodel.OrganizationContact, userView viewmodel.User) error { + userEntity := s.mapEntity.User.ToUserEntity(userView) entityContact := s.mapEntity.Organization.ToOrganizationContactEntity(contact) entityContact.Organization = &entity.Organization{ UUID: organizationUUID, @@ -130,14 +138,15 @@ func (s *organizationService) InactivateOrganizationContact(organizationUUID str } entityContact.UpdatedUser = user - if err := s.svc.Organization.InactivateOrganizationContact(entityContact); err != nil { + if err := s.svc.Organization.InactivateOrganizationContact(entityContact, userEntity); err != nil { return err } else { return nil } } -func (s *organizationService) SetOrganizationContact(organizationUUID string, contact viewmodel.OrganizationContact) (viewmodel.OrganizationContact, error) { +func (s *organizationService) SetOrganizationContact(organizationUUID string, contact viewmodel.OrganizationContact, userView viewmodel.User) (viewmodel.OrganizationContact, error) { + userEntity := s.mapEntity.User.ToUserEntity(userView) entityContact := s.mapEntity.Organization.ToOrganizationContactEntity(contact) entityContact.Organization = &entity.Organization{ UUID: organizationUUID, @@ -151,7 +160,7 @@ func (s *organizationService) SetOrganizationContact(organizationUUID string, co entityContact.CreatedUser = user entityContact.UpdatedUser = user - entityContact, err = s.svc.Organization.SetOrganizationContact(entityContact) + entityContact, err = s.svc.Organization.SetOrganizationContact(entityContact, userEntity) if err != nil { return viewmodel.OrganizationContact{}, err } @@ -221,10 +230,10 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio } } - enOrg, err = s.svc.Organization.AddOrganization(enOrg) + enOrg, err = s.svc.Organization.AddOrganization(enOrg, enUser) if err != nil { return viewmodel.Organization{}, nil } - return s.GetByUUID(enOrg.UUID) + return s.GetByUUID(enOrg.UUID, user) } diff --git a/application/applicationservice/user.go b/application/applicationservice/user.go index 0c9224b..1772486 100644 --- a/application/applicationservice/user.go +++ b/application/applicationservice/user.go @@ -71,11 +71,12 @@ func (s *userService) Login(email string, pass string) (retVal viewmodel.User, e return s.mapEntity.User.ToUserModel(user), nil } -func (s *userService) Create(user viewmodel.User) (retVal viewmodel.User, err error) { +func (s *userService) Create(user viewmodel.User, author viewmodel.User) (retVal viewmodel.User, err error) { entity := s.mapEntity.User.ToUserEntity(user) + enAuthor := s.mapEntity.User.ToUserEntity(author) for i, _ := range entity.Organizations { - entity.Organizations[i], err = s.svc.Organization.GetByUUID(entity.Organizations[i].UUID) + entity.Organizations[i], err = s.svc.Organization.GetByUUID(entity.Organizations[i].UUID, enAuthor) if err != nil { return retVal, err } @@ -89,13 +90,14 @@ func (s *userService) Create(user viewmodel.User) (retVal viewmodel.User, err er return s.mapEntity.User.ToUserModel(entity), nil } -func (s *userService) CreateBulk(users []viewmodel.User) (retVal []viewmodel.User, err error) { +func (s *userService) CreateBulk(users []viewmodel.User, author viewmodel.User) (retVal []viewmodel.User, err error) { entities := s.mapEntity.User.ToUserEntitySlice(users) + enAuthor := s.mapEntity.User.ToUserEntity(author) organizations := make([]entity.Organization, 0) for i, _ := range entities { if i == 0 { for o, _ := range entities[i].Organizations { - org, err := s.svc.Organization.GetByUUID(entities[i].Organizations[o].UUID) + org, err := s.svc.Organization.GetByUUID(entities[i].Organizations[o].UUID, enAuthor) if err != nil { return nil, err } diff --git a/authorization_model.conf b/authorization_model.conf index 1353c1e..afc86f8 100644 --- a/authorization_model.conf +++ b/authorization_model.conf @@ -1,11 +1,11 @@ [request_definition] -r = role, objectsRole, orgRelation, objectsRelation, obj, act +r = role, objectsRole, orgType, objectsOrgType, orgRelation, objectsRelation, obj, act [policy_definition] -p = role, objectsRole, orgRelation, objectsRelation, obj, act +p = role, objectsRole, orgType, objectsOrgType, orgRelation, objectsRelation, obj, act [policy_effect] e = some(where (p.eft == allow)) && !some(where (p.eft == deny)) [matchers] -m = keyMatch(r.role, p.role) && keyMatch(r.objectsRole, p.objectsRole) && keyMatch(r.objectsRelation, p.objectsRelation) && keyMatch(r.orgRelation, p.orgRelation) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*") \ No newline at end of file +m = keyMatch(r.role, p.role) && keyMatch(r.objectsRole, p.objectsRole) && keyMatch(r.orgType, p.orgType) && keyMatch(r.objectsOrgType, p.objectsOrgType) && keyMatch(r.objectsRelation, p.objectsRelation) && keyMatch(r.orgRelation, p.orgRelation) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*") \ No newline at end of file diff --git a/authorization_policy.csv b/authorization_policy.csv index 7c80d6e..b5082b3 100644 --- a/authorization_policy.csv +++ b/authorization_policy.csv @@ -1,27 +1,92 @@ -p, *, *, *, *, /v1/authenticate/portal, POST -p, *, *, *, *, /health/, GET -p, *, *, *, [self], /v1/users/*/, GET -p, *, *, *, [self], /v1/users/portal/*, DELETE -p, *, *, *, [self], /v1/users/portal/*, POST -p, *, *, *, [self], /v1/users/portal/*, GET -p, *AD, *, *, *, /v1/users/, GET -p, BDCAD, BCBSIAD, *, [other], /v1/users/*/, GET -p, BDCAD, BCBSIAD, *, [other], /v1/users/portal/*, DELETE -p, BDCAD, BCBSIAD, *, [other], /v1/users/portal/*, POST -p, BDCAD, BCBSIAD, *, [other], /v1/users/portal/*, GET -p, BDCAD, PLANAD, *, [other], /v1/users/*/, GET -p, BDCAD, PLANAD, *, [other], /v1/users/portal/*, DELETE -p, BDCAD, PLANAD, *, [other], /v1/users/portal/*, POST -p, BDCAD, PLANAD, *, [other], /v1/users/portal/*, GET -p, BCBSIAD, SP, *, [other], /v1/users/*/, GET -p, BCBSIAD, SP, *, [other], /v1/users/portal/*, DELETE -p, BCBSIAD, SP, *, [other], /v1/users/portal/*, POST -p, BCBSIAD, SP, *, [other], /v1/users/portal/*, GET -p, BCBSIAD, US, *, [other], /v1/users/*/, GET -p, BCBSIAD, US, *, [other], /v1/users/portal/*, DELETE -p, BCBSIAD, US, *, [other], /v1/users/portal/*, POST -p, BCBSIAD, US, *, [other], /v1/users/portal/*, GET -p, PLANAD, US, [equal], [other], /v1/users/*/, GET -p, PLANAD, US, [equal], [other], /v1/users/portal/*, DELETE -p, PLANAD, US, [equal], [other], /v1/users/portal/*, POST -p, PLANAD, US, [equal], [other], /v1/users/portal/*, GET \ No newline at end of file +p, AD, *, *, *, *, *, *, * +p, *, *, *, *, *, *, /v1/authenticate/portal, POST +p, *, *, *, *, *, *, /health/, GET +p, *, *, *, *, *, [self], /v1/nemt/nemt/users/*/, GET +p, *, *, *, *, *, [self], /v1/nemt/users/portal/*, DELETE +p, *, *, *, *, *, [self], /v1/nemt/users/portal/*, POST +p, *, *, *, *, *, [self], /v1/nemt/users/portal/*, GET +p, *AD, *, *, *, *, *, /v1/nemt/users/, GET +p, BDCAD, SP, *, *, *, [other], /v1/nemt/users/*/, GET +p, BDCAD, SP, *, *, *, [other], /v1/nemt/users/portal/*, DELETE +p, BDCAD, SP, *, *, *, [other], /v1/nemt/users/portal/*, POST +p, BDCAD, SP, *, *, *, [other], /v1/nemt/users/portal/*, GET +p, BDCAD, SPT, *, *, *, [other], /v1/nemt/users/*/, GET +p, BDCAD, SPT, *, *, *, [other], /v1/nemt/users/portal/*, DELETE +p, BDCAD, SPT, *, *, *, [other], /v1/nemt/users/portal/*, POST +p, BDCAD, SPT, *, *, *, [other], /v1/nemt/users/portal/*, GET +p, BDCAD, US, *, *, *, [other], /v1/nemt/users/*/, GET +p, BDCAD, US, *, *, *, [other], /v1/nemt/users/portal/*, DELETE +p, BDCAD, US, *, *, *, [other], /v1/nemt/users/portal/*, POST +p, BDCAD, US, *, *, *, [other], /v1/nemt/users/portal/*, GET +p, BCBSIAD, SP, *, *, *, [other], /v1/nemt/users/*/, GET +p, BCBSIAD, SP, *, *, *, [other], /v1/nemt/users/portal/*, DELETE +p, BCBSIAD, SP, *, *, *, [other], /v1/nemt/users/portal/*, POST +p, BCBSIAD, SP, *, *, *, [other], /v1/nemt/users/portal/*, GET +p, BCBSIAD, US, *, *, *, [other], /v1/nemt/users/*/, GET +p, BCBSIAD, US, *, *, *, [other], /v1/nemt/users/portal/*, DELETE +p, BCBSIAD, US, *, *, *, [other], /v1/nemt/users/portal/*, POST +p, BCBSIAD, US, *, *, *, [other], /v1/nemt/users/portal/*, GET +p, BCBSIAD, SPT, *, *, *, [other], /v1/nemt/users/*/, GET +p, BCBSIAD, SPT, *, *, *, [other], /v1/nemt/users/portal/*, DELETE +p, BCBSIAD, SPT, *, *, *, [other], /v1/nemt/users/portal/*, POST +p, BCBSIAD, SPT, *, *, *, [other], /v1/nemt/users/portal/*, GET +p, PLANAD, SPT, *, *, [equal], [other], /v1/nemt/users/*/, GET +p, PLANAD, SPT, *, *, [equal], [other], /v1/nemt/users/portal/*, DELETE +p, PLANAD, SPT, *, *, [equal], [other], /v1/nemt/users/portal/*, POST +p, PLANAD, SPT, *, *, [equal], [other], /v1/nemt/users/portal/*, GET +p, PLANAD, US, *, *, [equal], [other], /v1/nemt/users/*/, GET +p, PLANAD, US, *, *, [equal], [other], /v1/nemt/users/portal/*, DELETE +p, PLANAD, US, *, *, [equal], [other], /v1/nemt/users/portal/*, POST +p, PLANAD, US, *, *, [equal], [other], /v1/nemt/users/portal/*, GET +p, PLANAD, SP, *, *, [equal], [other], /v1/nemt/users/*/, GET +p, PLANAD, SP, *, *, [equal], [other], /v1/nemt/users/portal/*, DELETE +p, PLANAD, SP, *, *, [equal], [other], /v1/nemt/users/portal/*, POST +p, PLANAD, SP, *, *, [equal], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, US, *, *, [parent], [other], /v1/nemt/users/*/, GET +p, SCHDAD, US, *, *, [parent], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, US, *, *, [parent], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, US, *, *, [parent], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, SP, *, *, [parent], [other], /v1/nemt/users/*/, GET +p, SCHDAD, SP, *, *, [parent], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, SP, *, *, [parent], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, SP, *, *, [parent], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, SPT, *, *, [parent], [other], /v1/nemt/users/*/, GET +p, SCHDAD, SPT, *, *, [parent], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, SPT, *, *, [parent], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, SPT, *, *, [parent], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, SP, *, *, [equal*], [other], /v1/nemt/users/*/, GET +p, SCHDAD, SP, *, *, [equal*], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, SP, *, *, [equal*], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, SP, *, *, [equal*], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, US, *, *, [equal*], [other], /v1/nemt/users/*/, GET +p, SCHDAD, US, *, *, [equal*], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, US, *, *, [equal*], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, US, *, *, [equal*], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, SPT, *, *, [equal*], [other], /v1/nemt/users/*/, GET +p, SCHDAD, SPT, *, *, [equal*], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, SPT, *, *, [equal*], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, SPT, *, *, [equal*], [other], /v1/nemt/users/portal/*, GET +p, SCHDAD, SCHDAD, *, *, [equal*], [other], /v1/nemt/users/*/, GET +p, SCHDAD, SCHDAD, *, *, [equal*], [other], /v1/nemt/users/portal/*, DELETE +p, SCHDAD, SCHDAD, *, *, [equal*], [other], /v1/nemt/users/portal/*, POST +p, SCHDAD, SCHDAD, *, *, [equal*], [other], /v1/nemt/users/portal/*, GET +p, SPT, *, programsupport, *, *, [other], /v1/nemt/users/, GET +p, SPT, *, programsupport, *, *, [other], /v1/nemt/users/*, GET +p, AD, *, *, *, *, *, /v1/nemt/organization/*, GET +p, AD, *, *, *, *, *, /v1/nemt/organization/*, POST +p, AD, *, *, *, *, *, /v1/nemt/organization/*, PUT +p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, GET +p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, POST +p, SCHDAD, *, *, *, [equal*], *, /v1/nemt/organization/*, PUT +p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, GET +p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, POST +p, PLANAD, *, *, *, [equal*], *, /v1/nemt/organization/*, PUT +p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, GET +p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, POST +p, BDCAD, *, *, *, *, *, /v1/nemt/organization/*, PUT +p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, GET +p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, POST +p, BCBSIAD, *, *, *, *, *, /v1/nemt/organization/*, PUT +p, SPT, *, programsupport, *, *, *, /v1/nemt/organization/*, GET + + diff --git a/data/datamysql/organization.go b/data/datamysql/organization.go index 9dccc9b..41d9bf6 100644 --- a/data/datamysql/organization.go +++ b/data/datamysql/organization.go @@ -20,6 +20,63 @@ func newOrganizationRepo(conn executor) *organizationRepo { } } +func (c *organizationRepo) getProfileQuery(user entity.User) (query string, where string, err error) { + if len(user.Profiles) > 0 { + for _, p := range user.Profiles { + switch p.Key { + case "AD", "BCBSIAD", "BDCAD", "PLANAD": + switch p.Organization.Type.Key { + case "techsupport", "bcbsi", "bcbsa": + return + case "plan": + query = ` INNER JOIN tab_provider e + ON e.provider_id = a.organization_reference_id + AND b.organization_type_key = 'plan' + LEFT JOIN tab_organization f + ON f.organization_id = a.organization_parent_id ` + where = fmt.Sprintf(` AND (a.organization_uuid = '%s' OR f.organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID) + case "provider": + query = ` INNER JOIN tab_provider e + ON e.provider_id = a.organization_reference_id + AND b.organization_type_key = 'provider' + LEFT JOIN tab_organization f + ON f.organization_id = a.organization_parent_id ` + where = fmt.Sprintf(` AND (a.organization_uuid = '%s' OR f.organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID) + return + } + case "SP", "SPT": + switch p.Organization.Type.Key { + case "techsupport", "bcbsi", "bcbsa": + return + case "plan": + query = ` INNER JOIN tab_provider e + ON e.provider_id = a.organization_reference_id + AND b.organization_type_key = 'plan' + LEFT JOIN tab_organization f + ON f.organization_id = a.organization_parent_id ` + where = fmt.Sprintf(` AND (a.organization_uuid = '%s' OR f.organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID) + case "provider": + query = ` INNER JOIN tab_provider e + ON e.provider_id = a.organization_reference_id + AND b.organization_type_key = 'provider' + LEFT JOIN tab_organization f + ON f.organization_id = a.organization_parent_id ` + where = fmt.Sprintf(` AND (a.organization_uuid = '%s' OR f.organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID) + return + } + } + } + + if query == "" && where == "" { + return "", "", fmt.Errorf("Invalid Query") + } else { + return + } + } else { + return "", "", fmt.Errorf("User has no profile to search") + } +} + func (c *organizationRepo) getQuery() string { const ( query = `SELECT @@ -237,42 +294,73 @@ func (c *organizationRepo) GetAllTypes() ([]entity.OrganizationType, error) { } func (c *organizationRepo) GetTypeByKey(key string) (entity.OrganizationType, error) { - return c.parseTypeEntity(c.conn.QueryRow(c.getTypeQuery()+" WHERE organization_type_key=?", key)) + return c.parseTypeEntity(c.conn.QueryRow(c.getTypeQuery()+" WHERE b.organization_type_key=?", key)) } -func (c *organizationRepo) GetByType(organizationTypeKey string) ([]entity.Organization, error) { +func (c *organizationRepo) GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error) { + query, where, err := c.getProfileQuery(user) + if err != nil { + return nil, err + } + if organizationTypeKey == "" { - return c.parseSet(c.conn.Query(c.getQuery())) + return c.parseSet(c.conn.Query(c.getQuery() + query + " WHERE 1 = 1 " + where)) } else { - return c.parseSet(c.conn.Query(c.getQuery()+" WHERE b.organization_type_key = ? ", organizationTypeKey)) + return c.parseSet(c.conn.Query(c.getQuery()+query+" WHERE b.organization_type_key = ? "+where, organizationTypeKey)) } } -func (c *organizationRepo) GetByName(name string, searchType string) ([]entity.Organization, error) { - finalQuery := c.getQuery() + " WHERE a.organization_name LIKE ?" +func (c *organizationRepo) GetByName(name string, searchType string, user entity.User) ([]entity.Organization, error) { + query, where, err := c.getProfileQuery(user) + if err != nil { + return nil, err + } + + finalQuery := c.getQuery() + query + " WHERE a.organization_name LIKE ? " switch searchType { case "parent": - finalQuery += " AND a.organization_parent_id > 0; " + finalQuery += " AND a.organization_parent_id > 0 " case "child": - finalQuery += " AND a.organization_parent_id = 0; " + finalQuery += " AND a.organization_parent_id = 0 " } - name = "%" + name + "%" - fmt.Println(finalQuery) + finalQuery += where + name = "%" + name + "%" return c.parseSet(c.conn.Query(finalQuery, name)) } -func (c *organizationRepo) GetByUUID(organizationUUID string) (entity.Organization, error) { - return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.organization_uuid = ? ", organizationUUID)) +func (c *organizationRepo) GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) { + query, where, err := c.getProfileQuery(user) + if err != nil { + return entity.Organization{}, err + } + + query = c.getQuery() + query + " WHERE a.organization_uuid = ? " + where + + return c.parseEntity(c.conn.QueryRow(query, organizationUUID)) } -func (c *organizationRepo) GetByID(organizationID int64) (entity.Organization, error) { - return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.organization_id = ? ", organizationID)) +func (c *organizationRepo) GetByID(organizationID int64, user entity.User) (entity.Organization, error) { + query, where, err := c.getProfileQuery(user) + if err != nil { + return entity.Organization{}, err + } + + query = c.getQuery() + query + " WHERE a.organization_id = ? " + where + + return c.parseEntity(c.conn.QueryRow(query, organizationID)) } -func (c *organizationRepo) GetChildsByID(organizationID int64) ([]entity.Organization, error) { - return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.organization_parent_id = ? ", organizationID)) +func (c *organizationRepo) GetChildsByID(organizationID int64, user entity.User) ([]entity.Organization, error) { + query, where, err := c.getProfileQuery(user) + if err != nil { + return nil, err + } + + query = c.getQuery() + query + " WHERE a.organization_parent_id = ? " + where + + return c.parseSet(c.conn.Query(query, organizationID)) } func (c *organizationRepo) GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error) { @@ -312,7 +400,7 @@ func (c *organizationRepo) SetParentOrganization(organizationID int64, parentOrg } } -func (c *organizationRepo) InactivateOrganizationAddress(address entity.OrganizationAddress) error { +func (c *organizationRepo) InactivateOrganizationAddress(address entity.OrganizationAddress, user entity.User) error { const ( query = "UPDATE tab_organization_address SET active = 0, updated = CURRENT_TIMESTAMP, updated_user_id = ? WHERE organization_id = ? and organization_address_uuid = ?" ) @@ -321,7 +409,7 @@ func (c *organizationRepo) InactivateOrganizationAddress(address entity.Organiza return errors.NewNotFoundError() } - organization, err := c.GetByUUID(address.Organization.UUID) + organization, err := c.GetByUUID(address.Organization.UUID, user) if err != nil { return err } @@ -334,7 +422,7 @@ func (c *organizationRepo) InactivateOrganizationAddress(address entity.Organiza } } -func (c *organizationRepo) SetOrganizationAddress(address entity.OrganizationAddress) (entity.OrganizationAddress, error) { +func (c *organizationRepo) SetOrganizationAddress(address entity.OrganizationAddress, user entity.User) (entity.OrganizationAddress, error) { const ( query = "INSERT INTO tab_organization_address(organization_address_uuid, organization_id, internal_id, `name`, address, `desc`, lat, `long`, created_user_id, updated_user_id) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" ) @@ -343,7 +431,7 @@ func (c *organizationRepo) SetOrganizationAddress(address entity.OrganizationAdd return entity.OrganizationAddress{}, errors.NewNotFoundError() } - organization, err := c.GetByUUID(address.Organization.UUID) + organization, err := c.GetByUUID(address.Organization.UUID, user) if err != nil { return entity.OrganizationAddress{}, err } @@ -362,7 +450,7 @@ func (c *organizationRepo) SetOrganizationAddress(address entity.OrganizationAdd return address, nil } -func (c *organizationRepo) InactivateOrganizationContact(contact entity.OrganizationContact) error { +func (c *organizationRepo) InactivateOrganizationContact(contact entity.OrganizationContact, user entity.User) error { const ( query = "UPDATE tab_organization_contact SET active = 0, updated = CURRENT_TIMESTAMP, updated_user_id = ? WHERE organization_id = ? and organization_contact_uuid = ?" ) @@ -371,7 +459,7 @@ func (c *organizationRepo) InactivateOrganizationContact(contact entity.Organiza return errors.NewNotFoundError() } - organization, err := c.GetByUUID(contact.Organization.UUID) + organization, err := c.GetByUUID(contact.Organization.UUID, user) if err != nil { return err } @@ -384,7 +472,7 @@ func (c *organizationRepo) InactivateOrganizationContact(contact entity.Organiza } } -func (c *organizationRepo) SetOrganizationContact(contact entity.OrganizationContact) (entity.OrganizationContact, error) { +func (c *organizationRepo) SetOrganizationContact(contact entity.OrganizationContact, user entity.User) (entity.OrganizationContact, error) { const ( selectQuery = "SELECT a.contact_type_id, a.name, a.key FROM tab_contact_type a WHERE a.key = ?" query = "INSERT INTO tab_organization_contact(organization_contact_uuid, organization_id, contact_type_id, contact, contact_name, contact_desc, created_user_id, updated_user_id) VALUES(?, ?, ?, ?, ?, ?, ?, ?);" @@ -394,7 +482,7 @@ func (c *organizationRepo) SetOrganizationContact(contact entity.OrganizationCon return entity.OrganizationContact{}, errors.NewNotFoundError() } - organization, err := c.GetByUUID(contact.Organization.UUID) + organization, err := c.GetByUUID(contact.Organization.UUID, user) if err != nil { return entity.OrganizationContact{}, err } @@ -419,7 +507,7 @@ func (c *organizationRepo) SetOrganizationContact(contact entity.OrganizationCon return contact, nil } -func (c *organizationRepo) AddOrganization(organization entity.Organization) (entity.Organization, error) { +func (c *organizationRepo) AddOrganization(organization entity.Organization, user entity.User) (entity.Organization, error) { const ( queryOrgType = "SELECT a.organization_type_id FROM tab_organization_type a WHERE a.organization_type_key = ?;" queryParentOrg = "SELECT a.organization_id FROM tab_organization a WHERE a.organization_uuid = ?;" @@ -457,7 +545,7 @@ func (c *organizationRepo) AddOrganization(organization entity.Organization) (en if len(organization.Addresses) > 0 { for i, a := range organization.Addresses { a.Organization = &organization - address, err := c.SetOrganizationAddress(a) + address, err := c.SetOrganizationAddress(a, user) if err != nil { fmt.Println("Error to save addresses") return entity.Organization{}, err @@ -469,7 +557,7 @@ func (c *organizationRepo) AddOrganization(organization entity.Organization) (en if len(organization.Contacts) > 0 { for i, ct := range organization.Contacts { ct.Organization = &organization - contact, err := c.SetOrganizationContact(ct) + contact, err := c.SetOrganizationContact(ct, user) if err != nil { fmt.Println("Error to save contacts") return entity.Organization{}, err diff --git a/domain/contract/repo.go b/domain/contract/repo.go index d2196e8..d1775b8 100644 --- a/domain/contract/repo.go +++ b/domain/contract/repo.go @@ -68,23 +68,23 @@ type NotificationRepo interface { // ProviderRepo defines the data set for Rides type OrganizationRepo interface { GetAllTypes() ([]entity.OrganizationType, error) - GetByType(organizationTypeKey string) ([]entity.Organization, error) - GetByUUID(organizationUUID string) (entity.Organization, error) + GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error) + GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error) GetContactsByOrganizationID(organizationID int64) ([]entity.OrganizationContact, error) GetContactsByUUID(contactUUID string) (entity.OrganizationContact, error) GetAddressByOrganizationUUID(organizationUUID string) ([]entity.OrganizationAddress, error) GetAddressByOrganizationID(organizationID int64) ([]entity.OrganizationAddress, error) GetAddressByUUID(contactUUID string) (entity.OrganizationAddress, error) - GetByID(organizationID int64) (entity.Organization, error) - GetChildsByID(organizationID int64) ([]entity.Organization, error) - GetByName(name string, searchType string) ([]entity.Organization, error) + GetByID(organizationID int64, user entity.User) (entity.Organization, error) + GetChildsByID(organizationID int64, user entity.User) ([]entity.Organization, error) + GetByName(name string, searchType string, user entity.User) ([]entity.Organization, error) SetParentOrganization(organizationID int64, parentOrganizationID int64) error - InactivateOrganizationAddress(address entity.OrganizationAddress) error - SetOrganizationAddress(address entity.OrganizationAddress) (entity.OrganizationAddress, error) - InactivateOrganizationContact(contact entity.OrganizationContact) error - SetOrganizationContact(contact entity.OrganizationContact) (entity.OrganizationContact, error) - AddOrganization(organization entity.Organization) (entity.Organization, error) + InactivateOrganizationAddress(address entity.OrganizationAddress, user entity.User) error + SetOrganizationAddress(address entity.OrganizationAddress, user entity.User) (entity.OrganizationAddress, error) + InactivateOrganizationContact(contact entity.OrganizationContact, user entity.User) error + SetOrganizationContact(contact entity.OrganizationContact, user entity.User) (entity.OrganizationContact, error) + AddOrganization(organization entity.Organization, user entity.User) (entity.Organization, error) GetTypeByKey(key string) (entity.OrganizationType, error) } diff --git a/domain/service/organization.go b/domain/service/organization.go index 79e72d2..f26c76b 100644 --- a/domain/service/organization.go +++ b/domain/service/organization.go @@ -20,16 +20,16 @@ func (s *organizationService) GetAllTypes() ([]entity.OrganizationType, error) { return s.svc.db.Organization().GetAllTypes() } -func (s *organizationService) GetByType(organizationTypeKey string) ([]entity.Organization, error) { - return s.svc.db.Organization().GetByType(organizationTypeKey) +func (s *organizationService) GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error) { + return s.svc.db.Organization().GetByType(organizationTypeKey, user) } -func (s *organizationService) GetByName(name string, searchType string) ([]entity.Organization, error) { - return s.svc.db.Organization().GetByName(name, searchType) +func (s *organizationService) GetByName(name string, searchType string, user entity.User) ([]entity.Organization, error) { + return s.svc.db.Organization().GetByName(name, searchType, user) } -func (s *organizationService) GetByUUID(organizationUUID string) (entity.Organization, error) { - organization, err := s.svc.db.Organization().GetByUUID(organizationUUID) +func (s *organizationService) GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) { + organization, err := s.svc.db.Organization().GetByUUID(organizationUUID, user) if err != nil { return organization, err } @@ -44,13 +44,13 @@ func (s *organizationService) GetByUUID(organizationUUID string) (entity.Organiz return organization, err } - organization.ChildOrgs, err = s.svc.db.Organization().GetChildsByID(organization.ID) + organization.ChildOrgs, err = s.svc.db.Organization().GetChildsByID(organization.ID, user) if err != nil { return organization, err } if organization.ParentID > 0 { - parent, err := s.svc.db.Organization().GetByID(organization.ParentID) + parent, err := s.svc.db.Organization().GetByID(organization.ParentID, user) if err != nil { return organization, err } @@ -88,24 +88,24 @@ func (s *organizationService) GetAddressByUUID(contactUUID string) (entity.Organ return s.svc.db.Organization().GetAddressByUUID(contactUUID) } -func (s *organizationService) InactivateOrganizationAddress(address entity.OrganizationAddress) error { - return s.svc.db.Organization().InactivateOrganizationAddress(address) +func (s *organizationService) InactivateOrganizationAddress(address entity.OrganizationAddress, user entity.User) error { + return s.svc.db.Organization().InactivateOrganizationAddress(address, user) } -func (s *organizationService) SetOrganizationAddress(address entity.OrganizationAddress) (entity.OrganizationAddress, error) { - return s.svc.db.Organization().SetOrganizationAddress(address) +func (s *organizationService) SetOrganizationAddress(address entity.OrganizationAddress, user entity.User) (entity.OrganizationAddress, error) { + return s.svc.db.Organization().SetOrganizationAddress(address, user) } -func (s *organizationService) InactivateOrganizationContact(contact entity.OrganizationContact) error { - return s.svc.db.Organization().InactivateOrganizationContact(contact) +func (s *organizationService) InactivateOrganizationContact(contact entity.OrganizationContact, user entity.User) error { + return s.svc.db.Organization().InactivateOrganizationContact(contact, user) } -func (s *organizationService) SetOrganizationContact(contact entity.OrganizationContact) (entity.OrganizationContact, error) { - return s.svc.db.Organization().SetOrganizationContact(contact) +func (s *organizationService) SetOrganizationContact(contact entity.OrganizationContact, user entity.User) (entity.OrganizationContact, error) { + return s.svc.db.Organization().SetOrganizationContact(contact, user) } -func (s *organizationService) AddOrganization(organization entity.Organization) (entity.Organization, error) { - return s.svc.db.Organization().AddOrganization(organization) +func (s *organizationService) AddOrganization(organization entity.Organization, user entity.User) (entity.Organization, error) { + return s.svc.db.Organization().AddOrganization(organization, user) } func (s *organizationService) GetTypeByKey(key string) (entity.OrganizationType, error) { diff --git a/ecs.prd.json b/ecs.prd.json index 076f043..a2e2bfd 100644 --- a/ecs.prd.json +++ b/ecs.prd.json @@ -16,17 +16,8 @@ }, "portMappings": [ { - "containerPort": 5100 - } - ], - "environment": [ - { - "name": "SERVICE_5100_NAME", - "value": "portal-api" - }, - { - "name": "SERVICE_5100_TAGS", - "value": "api" + "containerPort": 5100, + "hostPort": 5100 } ] } diff --git a/ecs.stg.json b/ecs.stg.json index 1ea720d..9ff6ace 100644 --- a/ecs.stg.json +++ b/ecs.stg.json @@ -1,7 +1,7 @@ { "containerDefinitions": [ { - "name": "portal-api-dev", + "name": "portal-api", "image": "105690980714.dkr.ecr.us-east-2.amazonaws.com/nemt-portal-api:dev", "cpu": 128, "memory": 128, @@ -16,17 +16,8 @@ }, "portMappings": [ { - "containerPort": 5100 - } - ], - "environment": [ - { - "name": "SERVICE_5100_NAME", - "value": "portal-api" - }, - { - "name": "SERVICE_5100_TAGS", - "value": "api" + "containerPort": 5100, + "hostPort": 5100 } ] } diff --git a/server/router/organizationroute/controller.go b/server/router/organizationroute/controller.go index 527ec09..682a896 100644 --- a/server/router/organizationroute/controller.go +++ b/server/router/organizationroute/controller.go @@ -78,7 +78,12 @@ func (c *controller) handleAddOrganization(ctx echo.Context) error { func (c *controller) handle(ctx echo.Context) error { orgType, _ := routeutils.GetAndValidateStringQueryParam(ctx, "type", "Type is mandatory") - resp, err := c.svc.Organization.GetByType(orgType) + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + resp, err := c.svc.Organization.GetByType(orgType, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -92,7 +97,12 @@ func (c *controller) handleDetail(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.GetByUUID(orgUUID) + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -112,7 +122,12 @@ func (c *controller) handleParent(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.SetParentOrganization(orgUUID, parent.UUID) + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + resp, err := c.svc.Organization.SetParentOrganization(orgUUID, parent.UUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -132,12 +147,17 @@ func (c *controller) handleChild(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - _, err = c.svc.Organization.SetParentOrganization(child.UUID, orgUUID) + authUser, err := auth.GetUserDetail(ctx, c.cfg) if err != nil { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.GetByUUID(orgUUID) + _, err = c.svc.Organization.SetParentOrganization(child.UUID, orgUUID, authUser) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + + resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -151,11 +171,16 @@ func (c *controller) handleNameSearch(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + searchType := "" searchType, _ = routeutils.GetAndValidateStringQueryParam(ctx, "type", "Type is mandatory") cache := cache.Instance(c.cfg) - cacheKey := ctx.Request().Method + ctx.Request().URL.RawPath + ctx.Request().URL.RawQuery + cacheKey := ctx.Request().Method + ctx.Request().URL.RawPath + ctx.Request().URL.RawQuery + authUser.ID resp := []viewmodel.Organization{} err = cache.GetStruct(cacheKey, &resp) @@ -163,7 +188,7 @@ func (c *controller) handleNameSearch(ctx echo.Context) error { if err != domain.ErrCacheMiss { ctx.Logger().Errorf(domain.LogProblemGettingFromCache, err) } - resp, err = c.svc.Organization.GetByName(name, searchType) + resp, err = c.svc.Organization.GetByName(name, searchType, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -180,24 +205,24 @@ func (c *controller) handleRemoveAddress(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + orgUUID, err := routeutils.GetAndValidateStringParam(ctx, "org_uuid", "Org ID is mandatory") if err != nil { return routeutils.HandleAPIError(ctx, err) } - uInt, err := auth.GetTokenDetail(ctx, c.cfg) - if err != nil { - return routeutils.HandleAPIError(ctx, err) - } - createdUser := uInt.(map[string]interface{}) - address.UpdatedUser.ID = createdUser["useruuid"].(string) + address.UpdatedUser.ID = authUser.ID - err = c.svc.Organization.InactivateOrganizationAddress(orgUUID, address) + err = c.svc.Organization.InactivateOrganizationAddress(orgUUID, address, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.GetByUUID(orgUUID) + resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -217,20 +242,19 @@ func (c *controller) handleAddAddress(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - uInt, err := auth.GetTokenDetail(ctx, c.cfg) + authUser, err := auth.GetUserDetail(ctx, c.cfg) if err != nil { return routeutils.HandleAPIError(ctx, err) } - createdUser := uInt.(map[string]interface{}) - address.CreatedUser.ID = createdUser["useruuid"].(string) - address.UpdatedUser.ID = address.CreatedUser.ID + address.CreatedUser.ID = authUser.ID + address.UpdatedUser.ID = authUser.ID - _, err = c.svc.Organization.SetOrganizationAddress(orgUUID, address) + _, err = c.svc.Organization.SetOrganizationAddress(orgUUID, address, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.GetByUUID(orgUUID) + resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -250,19 +274,18 @@ func (c *controller) handleRemoveContact(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - uInt, err := auth.GetTokenDetail(ctx, c.cfg) + authUser, err := auth.GetUserDetail(ctx, c.cfg) if err != nil { return routeutils.HandleAPIError(ctx, err) } - createdUser := uInt.(map[string]interface{}) - contact.UpdatedUser.ID = createdUser["useruuid"].(string) + contact.UpdatedUser.ID = authUser.ID - err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact) + err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.GetByUUID(orgUUID) + resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -282,20 +305,19 @@ func (c *controller) handleAddContact(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } - uInt, err := auth.GetTokenDetail(ctx, c.cfg) + authUser, err := auth.GetUserDetail(ctx, c.cfg) if err != nil { return routeutils.HandleAPIError(ctx, err) } - createdUser := uInt.(map[string]interface{}) - contact.CreatedUser.ID = createdUser["useruuid"].(string) - contact.UpdatedUser.ID = contact.CreatedUser.ID + contact.CreatedUser.ID = authUser.ID + contact.UpdatedUser.ID = authUser.ID - _, err = c.svc.Organization.SetOrganizationContact(orgUUID, contact) + _, err = c.svc.Organization.SetOrganizationContact(orgUUID, contact, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } - resp, err := c.svc.Organization.GetByUUID(orgUUID) + resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } diff --git a/server/router/usersroute/controller.go b/server/router/usersroute/controller.go index 833bd5e..34ff679 100644 --- a/server/router/usersroute/controller.go +++ b/server/router/usersroute/controller.go @@ -274,6 +274,11 @@ func (c *controller) handleMember(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + if user.PhoneNumber == nil && user.Email == nil || len(*user.PhoneNumber) == 0 && len(*user.Email) == 0 { return routeutils.ResponseAPIAuthError(ctx, "phonenumber or email is required", false) } @@ -314,7 +319,7 @@ func (c *controller) handleMember(ctx echo.Context) error { } user.Profiles = append(user.Profiles, profile) - user, err = c.svc.Users.Create(user) + user, err = c.svc.Users.Create(user, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -328,6 +333,11 @@ func (c *controller) handleBulkPortal(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + for i, _ := range users { if len(users[i].Profiles) == 0 { return routeutils.ResponseAPIAuthError(ctx, "profile is required", false) @@ -360,7 +370,7 @@ func (c *controller) handleBulkPortal(ctx echo.Context) error { } } - returnUser, err := c.svc.Users.CreateBulk(users) + returnUser, err := c.svc.Users.CreateBulk(users, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } @@ -374,6 +384,11 @@ func (c *controller) handlePortal(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + if len(user.Profiles) == 0 { return routeutils.ResponseAPIAuthError(ctx, "profile is required", false) } @@ -404,7 +419,7 @@ func (c *controller) handlePortal(ctx echo.Context) error { user.Name = fmt.Sprintf("%s %s", user.First, user.Last) } - user, err = c.svc.Users.Create(user) + user, err = c.svc.Users.Create(user, authUser) if err != nil { return routeutils.HandleAPIError(ctx, err) } diff --git a/server/serverconfig/authorization.go b/server/serverconfig/authorization.go index 96e9e68..c3a8c4f 100644 --- a/server/serverconfig/authorization.go +++ b/server/serverconfig/authorization.go @@ -1,8 +1,6 @@ package serverconfig import ( - "fmt" - "bitbucket.org/nemt/nemt-portal-api/application/applicationservice" "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" "bitbucket.org/nemt/nemt-portal-api/infra/auth" @@ -77,8 +75,8 @@ func (a *Config) CheckPermission(c echo.Context) bool { } method := c.Request().Method path := c.Request().URL.Path - objectOrganization := a.organizationGoverningObject(c, user) - objectRole := a.roleGoverningObject(c, user) + + objectsRole, objectsOrganization, objectsOrganizationType, object := a.policyObjectAttributes(c, user) currentUsersOrganization := viewmodel.Organization{} if len(user.Organizations) > 0 { @@ -89,49 +87,74 @@ func (a *Config) CheckPermission(c echo.Context) bool { if len(user.Profiles) > 0 { currentUsersRole = user.Profiles[0] } - orgRelation := organizationsRelation(currentUsersOrganization, objectOrganization) - objRelation := a.objectRelation(c, user) - // parameters to Enforce must match the request section of the authorization model - return a.Enforcer.Enforce(currentUsersRole.Key, objectRole.Key, orgRelation, objRelation, path, method) + currentUsersOrganizationType := "" + if len(user.Profiles) > 0 { + currentUsersOrganizationType = user.Profiles[0].Organization.Type.Key + } + + orgRelation := organizationsRelation(currentUsersOrganization, objectsOrganization) + objRelation := a.objectRelation(object, user) + + // parameters to Enforce must match the request section of the authorization_model.conf + return a.Enforcer.Enforce(currentUsersRole.Key, + objectsRole.Key, + objectsOrganizationType, + currentUsersOrganizationType, + orgRelation, + objRelation, + path, + method) } -// organizationGoverningObject returns the organization that is the owner of the object that is being accessed -// in case object exists and returns users role if it is a new object -func (a *Config) organizationGoverningObject(c echo.Context, userDetails viewmodel.User) (result viewmodel.Organization) { +// policyObjectAttributes returns all information about the object being accessed for the policy +// in case object exists and returns users information if it is a new object +func (a *Config) policyObjectAttributes(c echo.Context, userDetails viewmodel.User) (viewmodel.Profile, viewmodel.Organization, string, interface{}) { - fmt.Println("***************") - fmt.Println(c.ParamValues()) - fmt.Println("***************") - existingUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) > 1 - newUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) <= 1 + var object interface{} + + objectIsNew := len(c.ParamValues()) <= 1 + objectIsExisting := len(c.ParamValues()) > 1 + + existingUser := strings.Contains(c.Request().URL.Path, "/users") && objectIsNew + newUser := strings.Contains(c.Request().URL.Path, "/users") && objectIsExisting + + existingOrganization := strings.Contains(c.Request().URL.Path, "/organization") && objectIsExisting + newOrganization := strings.Contains(c.Request().URL.Path, "/organization") && objectIsNew switch { case existingUser: - user, _ := a.Svc.Users.GetByUUID(c.ParamValues()[1], "") - result = user.Organizations[0] + object, _ = a.Svc.Users.GetByUUID(c.ParamValues()[1], "") case newUser && len(userDetails.Organizations) > 0: - result = userDetails.Organizations[0] + object = userDetails + case existingOrganization: + object, _ = a.Svc.Organization.GetByUUID(c.ParamValues()[1], userDetails) + case newOrganization: + object = viewmodel.Organization{} } - return -} -// organizationGoverningObject returns the role that is the owner of the object that is being accessed -// in case object exists and returns users role if it is a new object -func (a *Config) roleGoverningObject(c echo.Context, userDetails viewmodel.User) (result viewmodel.Profile) { - - existingUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) > 1 - newUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) <= 1 - - switch { - case existingUser: - user, _ := a.Svc.Users.GetByUUID(c.ParamValues()[1], "") - result = user.Profiles[0] - case newUser && len(userDetails.Organizations) > 0: - result = userDetails.Profiles[0] + objectsRole := viewmodel.Profile{} + switch obj := object.(type) { + case viewmodel.User: + if len(obj.Profiles) > 0 { + objectsRole = obj.Profiles[0] + } } - return + + objectsOrganization := viewmodel.Organization{} + switch obj := object.(type) { + case viewmodel.User: + if len(obj.Profiles) > 0 { + objectsOrganization = obj.Profiles[0].Organization + } + case viewmodel.Organization: + objectsOrganization = obj + } + + objectsOrganizationType := objectsOrganization.Type.Key + + return objectsRole, objectsOrganization, objectsOrganizationType, object } func organizationsRelation(requestOrganization, currentUsersOrganization viewmodel.Organization) string { @@ -156,15 +179,14 @@ func organizationsRelation(requestOrganization, currentUsersOrganization viewmod // organizationGoverningObject returns the role that is the owner of the object that is being accessed // in case object exists and returns users role if it is a new object -func (a *Config) objectRelation(c echo.Context, userDetails viewmodel.User) string { +func (a *Config) objectRelation(object interface{}, currentUser viewmodel.User) string { - existingUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) > 1 - - switch { - case existingUser: - user, _ := a.Svc.Users.GetByUUID(c.ParamValues()[1], "") - if user.ID == userDetails.ID { + switch obj := object.(type) { + case viewmodel.User: + if obj.ID == currentUser.ID { return "[self]" + } else { + return "[other]" } } return "[other]"