Compare commits

5 Commits

Author SHA1 Message Date
GotPPay
52656e0420 remove debugging response 2018-05-18 17:45:47 +02:00
GotPPay
c6606a98dd custom elig. api error msg ; first check elig. then create user 2018-05-18 10:46:47 +02:00
Senad Uka
2e5444bed8 Upstream sync 2018-05-16 18:30:59 +02:00
Senad Uka
4852a5586c upstream sync 2018-05-11 09:07:54 +02:00
Senad Uka
50a6362b67 upstream sync 2018-05-03 07:55:09 +02:00
48 changed files with 3584 additions and 232 deletions

View File

@@ -15,6 +15,8 @@ COPY ./dist/${BIN_NAME} /opt/app/${BIN_NAME}
ADD ./dist/docs/ /opt/app/docs/
ADD ./dist/static/ /opt/app/static/
ADD ./dist/config.toml /opt/app/config.toml
ADD ./dist/authorization_model.conf /opt/app/authorization_model.conf
ADD ./dist/authorization_policy.csv /opt/app/authorization_policy.csv
# Sets and executes the app.
WORKDIR /opt/app

View File

@@ -67,6 +67,8 @@ build: clean create-build-container
cp -R static/* ./dist/static/
cp -R docs/swagger/ ./dist/docs/
cp config.${DEPLOY_ENV}.toml ./dist/config.toml
cp authorization_model.conf ./dist/authorization_model.conf
cp authorization_policy.csv ./dist/authorization_policy.csv
#################################################
## Building, based on the current environment. ##

View File

@@ -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)
}

View File

@@ -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
}
@@ -147,3 +149,23 @@ func (s *userService) GetContactType() (retVal []viewmodel.ContactType, err erro
return s.mapEntity.User.ToContactTypeModelSlice(entity), nil
}
func (s *userService) SaveContact(contact viewmodel.Contact) (retVal viewmodel.Contact, err error) {
entity := s.mapEntity.User.ToContactEntity(contact)
entity, err = s.svc.Users.SaveContact(entity)
if err != nil {
return retVal, errors.Wrap(err)
}
return s.mapEntity.User.ToContactModel(entity), err
}
func (s *userService) RemoveContact(contact viewmodel.Contact) (retVal viewmodel.Contact, err error) {
entity := s.mapEntity.User.ToContactEntity(contact)
entity, err = s.svc.Users.RemoveContact(entity)
if err != nil {
return retVal, errors.Wrap(err)
}
return s.mapEntity.User.ToContactModel(entity), err
}

View File

@@ -158,8 +158,11 @@ func (mapping *userMapping) ToContactTypeModelSlice(list []entity.ContactType) (
// ToContactModel maps a Contact entity to Contact view model
func (mapping *userMapping) ToContactModel(item entity.ContactInfo) viewmodel.Contact {
return viewmodel.Contact{
Type: mapping.ToContactTypeModel(item.Type),
Value: item.Value,
ID: item.UUID,
User: mapping.ToUserModel(item.User),
Author: mapping.ToUserModel(item.Author),
Type: mapping.ToContactTypeModel(item.Type),
Value: item.Value,
}
}
@@ -177,8 +180,11 @@ func (mapping *userMapping) ToContactModelSlice(list []entity.ContactInfo) (retV
// ToContactEntity maps a Contact entity to Contact view model
func (mapping *userMapping) ToContactEntity(item viewmodel.Contact) entity.ContactInfo {
return entity.ContactInfo{
Type: mapping.ToContactTypeEntity(item.Type),
Value: item.Value,
UUID: item.ID,
User: mapping.ToUserEntity(item.User),
Author: mapping.ToUserEntity(item.Author),
Type: mapping.ToContactTypeEntity(item.Type),
Value: item.Value,
}
}

View File

@@ -42,3 +42,287 @@ type EntityResponse struct {
Name string `json:"name"`
Status bool `json:"status"`
}
type Interchange271 struct {
XMLName xml.Name `json:"-" xml:"Interchange"`
Isa ISA271 `json:"isa,omitempty" xml:"ISA"`
Division Division271 `json:"division,omitempty" xml:"Division"`
IEA IEA271 `json:"iea,omitempty" xml:"IEA"`
}
type IEA271 struct {
IEA01 string `json:"iea01,omitempty" xml:"IEA01"`
IEA02 string `json:"iea02,omitempty" xml:"IEA02"`
}
type ISA271 struct {
Isa01 string `json:"isa01,omitempty" xml:"ISA01"`
Isa02 string `json:"isa02,omitempty" xml:"ISA02"`
Isa03 string `json:"isa03,omitempty" xml:"ISA03"`
Isa04 string `json:"isa04,omitempty" xml:"ISA04"`
Isa05 string `json:"isa05,omitempty" xml:"ISA05"`
Isa06 string `json:"isa06,omitempty" xml:"ISA06"`
Isa07 string `json:"isa07,omitempty" xml:"ISA07"`
Isa08 string `json:"isa08,omitempty" xml:"ISA08"`
Isa09 string `json:"isa09,omitempty" xml:"ISA09"`
Isa10 string `json:"isa10,omitempty" xml:"ISA10"`
Isa11 string `json:"isa11,omitempty" xml:"ISA11"`
Isa12 string `json:"isa12,omitempty" xml:"ISA12"`
Isa13 string `json:"isa13,omitempty" xml:"ISA13"`
Isa14 string `json:"isa14,omitempty" xml:"ISA14"`
Isa15 string `json:"isa15,omitempty" xml:"ISA15"`
Isa16 string `json:"isa16,omitempty" xml:"ISA16"`
}
type Division271 struct {
GS GS271 `json:"gs,omitempty" xml:"GS"`
HealthCareEligibilityResponse HealthCareEligibilityBenefitResponse271 `json:"eligibility_response,omitempty" xml:"Health_Care_Eligibility_Benefit_Response"`
GE GE271 `json:"ge,omitempty" xml:"GE"`
}
type GS271 struct {
GS01 string `json:"gs01,omitempty" xml:"GS01"`
GS02 string `json:"gs02,omitempty" xml:"GS02"`
GS03 string `json:"gs03,omitempty" xml:"GS03"`
GS04 string `json:"gs04,omitempty" xml:"GS04"`
GS05 string `json:"gs05,omitempty" xml:"GS05"`
GS06 string `json:"gs06,omitempty" xml:"GS06"`
GS07 string `json:"gs07,omitempty" xml:"GS07"`
GS08 string `json:"gs08,omitempty" xml:"GS08"`
}
type GE271 struct {
GE01 string `json:"ge01,omitempty" xml:"GE01"`
GE02 string `json:"ge02,omitempty" xml:"GE02"`
}
type HealthCareEligibilityBenefitResponse271 struct {
ST0010 ST `json:"st0010,omitempty" xml:"ST_0010"`
BHT0020 BHT `json:"bht0020,omitempty" xml:"BHT_0020"`
LoopHL0030 []LoopHL0030271 `json:"hl0030,omitempty" xml:"Loop_HL_0030"`
}
type ST struct {
ST01 string `json:"st01,omitempty" xml:"ST01"`
ST02 string `json:"st02,omitempty" xml:"ST02"`
ST03 string `json:"st03,omitempty" xml:"ST03"`
ST04 string `json:"st04,omitempty" xml:"ST04"`
ST05 string `json:"st05,omitempty" xml:"ST05"`
ST06 string `json:"st06,omitempty" xml:"ST06"`
ST07 string `json:"st07,omitempty" xml:"ST07"`
ST08 string `json:"st08,omitempty" xml:"ST08"`
ST09 string `json:"st09,omitempty" xml:"ST09"`
ST10 string `json:"st10,omitempty" xml:"ST10"`
ST11 string `json:"st11,omitempty" xml:"ST11"`
ST12 string `json:"st12,omitempty" xml:"ST12"`
ST13 string `json:"st13,omitempty" xml:"ST13"`
ST14 string `json:"st14,omitempty" xml:"ST14"`
ST15 string `json:"st15,omitempty" xml:"ST15"`
ST16 string `json:"st16,omitempty" xml:"ST16"`
}
type BHT struct {
BHT01 string `json:"bht01,omitempty" xml:"BHT01"`
BHT02 string `json:"bht02,omitempty" xml:"BHT02"`
BHT03 string `json:"bht03,omitempty" xml:"BHT03"`
BHT04 string `json:"bht04,omitempty" xml:"BHT04"`
BHT05 string `json:"bht05,omitempty" xml:"BHT05"`
BHT06 string `json:"bht06,omitempty" xml:"BHT06"`
BHT07 string `json:"bht07,omitempty" xml:"BHT07"`
BHT08 string `json:"bht08,omitempty" xml:"BHT08"`
BHT09 string `json:"bht09,omitempty" xml:"BHT09"`
BHT10 string `json:"bht10,omitempty" xml:"BHT10"`
BHT11 string `json:"bht11,omitempty" xml:"BHT11"`
BHT12 string `json:"bht12,omitempty" xml:"BHT12"`
BHT13 string `json:"bht13,omitempty" xml:"BHT13"`
BHT14 string `json:"bht14,omitempty" xml:"BHT14"`
BHT15 string `json:"bht15,omitempty" xml:"BHT15"`
BHT16 string `json:"bht16,omitempty" xml:"BHT16"`
}
type LoopHL0030271 struct {
HL_0030 HL `json:"hl_0030,omitempty" xml:"HL_0030"`
NM1_0060 []LoopNM10060 `json:"nm1_0060,omitempty" xml:"Loop_NM1_0060"`
HL_0460 []LoopHL0460 `json:"hl_0460,omitempty" xml:"Loop_HL_0460"`
}
type LoopHL0460 struct {
HL_0460 HL `json:"hl_0460,omitempty" xml:"HL_0460"`
NM1_0490 []LoopNM10490 `json:"nm1_0490,omitempty" xml:"Loop_NM1_0490"`
HL_0890 []LoopHL0890 `json:"hl_0890,omitempty" xml:"Loop_HL_0890"`
}
type LoopNM10490 struct {
NM1_0490 NM1 `json:"nm1_0490,omitempty" xml:"NM1_0490"`
}
type LoopHL0890 struct {
HL_0890 HL `json:"hl_0890,omitempty" xml:"HL_0890"`
TRN_0900 TRN `json:"trn_0900,omitempty" xml:"TRN_0900"`
NM1_0920 []LoopNM10920 `json:"nm1_0920,omitempty" xml:"Loop_NM1_0920"`
}
type REF struct {
REF01 string `json:"ref01,omitempty" xml:"REF01"`
REF02 string `json:"ref02,omitempty" xml:"REF02"`
REF03 string `json:"ref03,omitempty" xml:"REF03"`
REF04 string `json:"ref04,omitempty" xml:"REF04"`
REF05 string `json:"ref05,omitempty" xml:"REF05"`
REF06 string `json:"ref06,omitempty" xml:"REF06"`
REF07 string `json:"ref07,omitempty" xml:"REF07"`
REF08 string `json:"ref08,omitempty" xml:"REF08"`
REF09 string `json:"ref09,omitempty" xml:"REF09"`
REF10 string `json:"ref10,omitempty" xml:"REF10"`
REF11 string `json:"ref11,omitempty" xml:"REF11"`
REF12 string `json:"ref12,omitempty" xml:"REF12"`
REF13 string `json:"ref13,omitempty" xml:"REF13"`
REF14 string `json:"ref14,omitempty" xml:"REF14"`
REF15 string `json:"ref15,omitempty" xml:"REF15"`
REF16 string `json:"ref16,omitempty" xml:"REF16"`
}
type N3 struct {
N301 string `json:"n301,omitempty" xml:"N301"`
N302 string `json:"n302,omitempty" xml:"N302"`
N303 string `json:"n303,omitempty" xml:"N303"`
N304 string `json:"n304,omitempty" xml:"N304"`
N305 string `json:"n305,omitempty" xml:"N305"`
N306 string `json:"n306,omitempty" xml:"N306"`
N307 string `json:"n307,omitempty" xml:"N307"`
N308 string `json:"n308,omitempty" xml:"N308"`
N309 string `json:"n309,omitempty" xml:"N309"`
N310 string `json:"n310,omitempty" xml:"N310"`
N311 string `json:"n311,omitempty" xml:"N311"`
N312 string `json:"n312,omitempty" xml:"N312"`
N313 string `json:"n313,omitempty" xml:"N313"`
N314 string `json:"n314,omitempty" xml:"N314"`
N315 string `json:"n315,omitempty" xml:"N315"`
N316 string `json:"n316,omitempty" xml:"N316"`
}
type N4 struct {
N401 string `json:"n401,omitempty" xml:"N401"`
N402 string `json:"n402,omitempty" xml:"N402"`
N403 string `json:"n403,omitempty" xml:"N403"`
N404 string `json:"n404,omitempty" xml:"N404"`
N405 string `json:"n405,omitempty" xml:"N405"`
N406 string `json:"n406,omitempty" xml:"N406"`
N407 string `json:"n407,omitempty" xml:"N407"`
N408 string `json:"n408,omitempty" xml:"N408"`
N409 string `json:"n409,omitempty" xml:"N409"`
N410 string `json:"n410,omitempty" xml:"N410"`
N411 string `json:"n411,omitempty" xml:"N411"`
N412 string `json:"n412,omitempty" xml:"N412"`
N413 string `json:"n413,omitempty" xml:"N413"`
N414 string `json:"n414,omitempty" xml:"N414"`
N415 string `json:"n415,omitempty" xml:"N415"`
N416 string `json:"n416,omitempty" xml:"N416"`
}
type LoopNM10920 struct {
NM1_0920 NM1 `json:"nm1_0920,omitempty" xml:"NM1_0920"`
REF_0930 []REF `json:"ref_0930,omitempty" xml:"REF_0930"`
N3_0950 N3 `json:"n3_0950,omitempty" xml:"N3_0950"`
N4_0960 N4 `json:"n4_0960,omitempty" xml:"N4_0960"`
DMG_1000 DMG `json:"dmg_1000,omitempty" xml:"DMG_1000"`
INS_1010 INS `json:"ins_1010,omitempty" xml:"INS_1010"`
}
type DMG struct {
DMG01 string `json:"dmg01,omitempty" xml:"DMG01"`
DMG02 string `json:"dmg02,omitempty" xml:"DMG02"`
DMG03 string `json:"dmg03,omitempty" xml:"DMG03"`
DMG04 string `json:"dmg04,omitempty" xml:"DMG04"`
DMG05 string `json:"dmg05,omitempty" xml:"DMG05"`
DMG06 string `json:"dmg06,omitempty" xml:"DMG06"`
DMG07 string `json:"dmg07,omitempty" xml:"DMG07"`
DMG08 string `json:"dmg08,omitempty" xml:"DMG08"`
DMG09 string `json:"dmg09,omitempty" xml:"DMG09"`
DMG10 string `json:"dmg10,omitempty" xml:"DMG10"`
DMG11 string `json:"dmg11,omitempty" xml:"DMG11"`
DMG12 string `json:"dmg12,omitempty" xml:"DMG12"`
DMG13 string `json:"dmg13,omitempty" xml:"DMG13"`
DMG14 string `json:"dmg14,omitempty" xml:"DMG14"`
DMG15 string `json:"dmg15,omitempty" xml:"DMG15"`
DMG16 string `json:"dmg16,omitempty" xml:"DMG16"`
}
type INS struct {
INS01 string `json:"ins01,omitempty" xml:"INS01"`
INS02 string `json:"ins02,omitempty" xml:"INS02"`
INS03 string `json:"ins03,omitempty" xml:"INS03"`
INS04 string `json:"ins04,omitempty" xml:"INS04"`
INS05 string `json:"ins05,omitempty" xml:"INS05"`
INS06 string `json:"ins06,omitempty" xml:"INS06"`
INS07 string `json:"ins07,omitempty" xml:"INS07"`
INS08 string `json:"ins08,omitempty" xml:"INS08"`
INS09 string `json:"ins09,omitempty" xml:"INS09"`
INS10 string `json:"ins10,omitempty" xml:"INS10"`
INS11 string `json:"ins11,omitempty" xml:"INS11"`
INS12 string `json:"ins12,omitempty" xml:"INS12"`
INS13 string `json:"ins13,omitempty" xml:"INS13"`
INS14 string `json:"ins14,omitempty" xml:"INS14"`
INS15 string `json:"ins15,omitempty" xml:"INS15"`
INS16 string `json:"ins16,omitempty" xml:"INS16"`
}
type TRN struct {
TRN01 string `json:"trn01,omitempty" xml:"TRN01"`
TRN02 string `json:"trn02,omitempty" xml:"TRN02"`
TRN03 string `json:"trn03,omitempty" xml:"TRN03"`
TRN04 string `json:"trn04,omitempty" xml:"TRN04"`
TRN05 string `json:"trn05,omitempty" xml:"TRN05"`
TRN06 string `json:"trn06,omitempty" xml:"TRN06"`
TRN07 string `json:"trn07,omitempty" xml:"TRN07"`
TRN08 string `json:"trn08,omitempty" xml:"TRN08"`
TRN09 string `json:"trn09,omitempty" xml:"TRN09"`
TRN10 string `json:"trn10,omitempty" xml:"TRN10"`
TRN11 string `json:"trn11,omitempty" xml:"TRN11"`
TRN12 string `json:"trn12,omitempty" xml:"TRN12"`
TRN13 string `json:"trn13,omitempty" xml:"TRN13"`
TRN14 string `json:"trn14,omitempty" xml:"TRN14"`
TRN15 string `json:"trn15,omitempty" xml:"TRN15"`
TRN16 string `json:"trn16,omitempty" xml:"TRN16"`
}
type HL struct {
HL01 string `json:"hl01,omitempty" xml:"HL01"`
HL02 string `json:"hl02,omitempty" xml:"HL02"`
HL03 string `json:"hl03,omitempty" xml:"HL03"`
HL04 string `json:"hl04,omitempty" xml:"HL04"`
HL05 string `json:"hl05,omitempty" xml:"HL05"`
HL06 string `json:"hl06,omitempty" xml:"HL06"`
HL07 string `json:"hl07,omitempty" xml:"HL07"`
HL08 string `json:"hl08,omitempty" xml:"HL08"`
HL09 string `json:"hl09,omitempty" xml:"HL09"`
HL10 string `json:"hl10,omitempty" xml:"HL10"`
HL11 string `json:"hl11,omitempty" xml:"HL11"`
HL12 string `json:"hl12,omitempty" xml:"HL12"`
HL13 string `json:"hl13,omitempty" xml:"HL13"`
HL14 string `json:"hl14,omitempty" xml:"HL14"`
HL15 string `json:"hl15,omitempty" xml:"HL15"`
HL16 string `json:"hl16,omitempty" xml:"HL16"`
}
type LoopNM10060 struct {
NM10060 NM1 `json:"nm1_0060,omitempty" xml:"NM1_0060"`
}
type NM1 struct {
NM101 string `json:"nm101,omitempty" xml:"NM101"`
NM102 string `json:"nm102,omitempty" xml:"NM102"`
NM103 string `json:"nm103,omitempty" xml:"NM103"`
NM104 string `json:"nm104,omitempty" xml:"NM104"`
NM105 string `json:"nm105,omitempty" xml:"NM105"`
NM106 string `json:"nm106,omitempty" xml:"NM106"`
NM107 string `json:"nm107,omitempty" xml:"NM107"`
NM108 string `json:"nm108,omitempty" xml:"NM108"`
NM109 string `json:"nm109,omitempty" xml:"NM109"`
NM110 string `json:"nm110,omitempty" xml:"NM110"`
NM111 string `json:"nm111,omitempty" xml:"NM111"`
NM112 string `json:"nm112,omitempty" xml:"NM112"`
NM113 string `json:"nm113,omitempty" xml:"NM113"`
NM114 string `json:"nm114,omitempty" xml:"NM114"`
NM115 string `json:"nm115,omitempty" xml:"NM115"`
NM116 string `json:"nm116,omitempty" xml:"NM116"`
}

View File

@@ -5,7 +5,9 @@ import (
"crypto/md5"
"encoding/hex"
"encoding/xml"
"errors"
"fmt"
"html"
"io/ioutil"
"net/http"
"strings"
@@ -72,14 +74,37 @@ func (s bxeService) GetPayerDetails(subscriberID string) ([]bcbsimodel.EntityRes
return response, nil
}
func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimodel.MemberEligibilityResponse, error) {
payer, err := s.GetPayerDetails(eligibility.Subscriber.SubscriberID)
func (s bxeService) Get271(eligibility viewmodel.Eligibility) (bcbsimodel.Interchange271, error) {
resp, err := s.CheckEligibility(eligibility)
if err != nil {
return bcbsimodel.MemberEligibilityResponse{}, err
return bcbsimodel.Interchange271{}, err
}
eligibility.Payer.PayerID = payer[0].ID
eligibility.Payer.PayerName = payer[0].Name
if resp.QueryResult.HIPPA271.T271 != "" {
xmlString := html.UnescapeString(resp.QueryResult.HIPPA271.T271)
xmlReader := strings.NewReader(xmlString)
var f bcbsimodel.Interchange271
err = xml.NewDecoder(xmlReader).Decode(&f)
if err != nil {
fmt.Println("Error to unmarshal: ", err.Error())
return bcbsimodel.Interchange271{}, err
}
return f, nil
} else {
return bcbsimodel.Interchange271{}, errors.New("No 271 response")
}
}
func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimodel.MemberEligibilityResponse, error) {
// payer, err := s.GetPayerDetails(eligibility.Subscriber.SubscriberID)
// if err != nil {
// return bcbsimodel.MemberEligibilityResponse{}, err
// }
eligibility.Payer.PayerID = "621"
eligibility.Payer.PayerName = "blue_cross_blue_shield_il"
envelope := bcbsimodel.GetEnvelope(eligibility)
apiKey := s.cfg.BXE.APIKey
@@ -99,14 +124,14 @@ func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimo
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error WebService: ", err)
fmt.Println("Error WebService Request: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
defer resp.Body.Close()
bReturn, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error WebService: ", err)
fmt.Println("Error WebService getting byte: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
@@ -118,7 +143,7 @@ func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimo
var result bcbsimodel.EnvelopeResponse
err = xml.Unmarshal([]byte(sResponse), &result)
if err != nil {
fmt.Println("Error WebService: ", err)
fmt.Println("Error WebService getting object: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}

View File

@@ -1,6 +1,7 @@
package viewmodel
import (
"encoding/xml"
"time"
)
@@ -53,3 +54,287 @@ type ServiceInfo struct {
DateOfService time.Time `json:"date_of_service,omitempty"`
ServiceTypeCodes []string `json:"service_type_codes,omitempty"`
}
type Interchange271 struct {
XMLName xml.Name `json:"-" xml:"Interchange"`
Isa ISA271 `json:"isa,omitempty" xml:"ISA"`
Division Division271 `json:"division,omitempty" xml:"Division"`
IEA IEA271 `json:"iea,omitempty" xml:"IEA"`
}
type IEA271 struct {
IEA01 string `json:"iea01,omitempty" xml:"IEA01"`
IEA02 string `json:"iea02,omitempty" xml:"IEA02"`
}
type ISA271 struct {
Isa01 string `json:"isa01,omitempty" xml:"ISA01"`
Isa02 string `json:"isa02,omitempty" xml:"ISA02"`
Isa03 string `json:"isa03,omitempty" xml:"ISA03"`
Isa04 string `json:"isa04,omitempty" xml:"ISA04"`
Isa05 string `json:"isa05,omitempty" xml:"ISA05"`
Isa06 string `json:"isa06,omitempty" xml:"ISA06"`
Isa07 string `json:"isa07,omitempty" xml:"ISA07"`
Isa08 string `json:"isa08,omitempty" xml:"ISA08"`
Isa09 string `json:"isa09,omitempty" xml:"ISA09"`
Isa10 string `json:"isa10,omitempty" xml:"ISA10"`
Isa11 string `json:"isa11,omitempty" xml:"ISA11"`
Isa12 string `json:"isa12,omitempty" xml:"ISA12"`
Isa13 string `json:"isa13,omitempty" xml:"ISA13"`
Isa14 string `json:"isa14,omitempty" xml:"ISA14"`
Isa15 string `json:"isa15,omitempty" xml:"ISA15"`
Isa16 string `json:"isa16,omitempty" xml:"ISA16"`
}
type Division271 struct {
GS GS271 `json:"gs,omitempty" xml:"GS"`
HealthCareEligibilityResponse HealthCareEligibilityBenefitResponse271 `json:"eligibility_response,omitempty" xml:"Health_Care_Eligibility_Benefit_Response"`
GE GE271 `json:"ge,omitempty" xml:"GE"`
}
type GS271 struct {
GS01 string `json:"gs01,omitempty" xml:"GS01"`
GS02 string `json:"gs02,omitempty" xml:"GS02"`
GS03 string `json:"gs03,omitempty" xml:"GS03"`
GS04 string `json:"gs04,omitempty" xml:"GS04"`
GS05 string `json:"gs05,omitempty" xml:"GS05"`
GS06 string `json:"gs06,omitempty" xml:"GS06"`
GS07 string `json:"gs07,omitempty" xml:"GS07"`
GS08 string `json:"gs08,omitempty" xml:"GS08"`
}
type GE271 struct {
GE01 string `json:"ge01,omitempty" xml:"GE01"`
GE02 string `json:"ge02,omitempty" xml:"GE02"`
}
type HealthCareEligibilityBenefitResponse271 struct {
ST0010 ST `json:"st0010,omitempty" xml:"ST_0010"`
BHT0020 BHT `json:"bht0020,omitempty" xml:"BHT_0020"`
LoopHL0030 []LoopHL0030271 `json:"hl0030,omitempty" xml:"Loop_HL_0030"`
}
type ST struct {
ST01 string `json:"st01,omitempty" xml:"ST01"`
ST02 string `json:"st02,omitempty" xml:"ST02"`
ST03 string `json:"st03,omitempty" xml:"ST03"`
ST04 string `json:"st04,omitempty" xml:"ST04"`
ST05 string `json:"st05,omitempty" xml:"ST05"`
ST06 string `json:"st06,omitempty" xml:"ST06"`
ST07 string `json:"st07,omitempty" xml:"ST07"`
ST08 string `json:"st08,omitempty" xml:"ST08"`
ST09 string `json:"st09,omitempty" xml:"ST09"`
ST10 string `json:"st10,omitempty" xml:"ST10"`
ST11 string `json:"st11,omitempty" xml:"ST11"`
ST12 string `json:"st12,omitempty" xml:"ST12"`
ST13 string `json:"st13,omitempty" xml:"ST13"`
ST14 string `json:"st14,omitempty" xml:"ST14"`
ST15 string `json:"st15,omitempty" xml:"ST15"`
ST16 string `json:"st16,omitempty" xml:"ST16"`
}
type BHT struct {
BHT01 string `json:"bht01,omitempty" xml:"BHT01"`
BHT02 string `json:"bht02,omitempty" xml:"BHT02"`
BHT03 string `json:"bht03,omitempty" xml:"BHT03"`
BHT04 string `json:"bht04,omitempty" xml:"BHT04"`
BHT05 string `json:"bht05,omitempty" xml:"BHT05"`
BHT06 string `json:"bht06,omitempty" xml:"BHT06"`
BHT07 string `json:"bht07,omitempty" xml:"BHT07"`
BHT08 string `json:"bht08,omitempty" xml:"BHT08"`
BHT09 string `json:"bht09,omitempty" xml:"BHT09"`
BHT10 string `json:"bht10,omitempty" xml:"BHT10"`
BHT11 string `json:"bht11,omitempty" xml:"BHT11"`
BHT12 string `json:"bht12,omitempty" xml:"BHT12"`
BHT13 string `json:"bht13,omitempty" xml:"BHT13"`
BHT14 string `json:"bht14,omitempty" xml:"BHT14"`
BHT15 string `json:"bht15,omitempty" xml:"BHT15"`
BHT16 string `json:"bht16,omitempty" xml:"BHT16"`
}
type LoopHL0030271 struct {
HL_0030 HL `json:"hl_0030,omitempty" xml:"HL_0030"`
NM1_0060 []LoopNM10060 `json:"nm1_0060,omitempty" xml:"Loop_NM1_0060"`
HL_0460 []LoopHL0460 `json:"hl_0460,omitempty" xml:"Loop_HL_0460"`
}
type LoopHL0460 struct {
HL_0460 HL `json:"hl_0460,omitempty" xml:"HL_0460"`
NM1_0490 []LoopNM10490 `json:"nm1_0490,omitempty" xml:"Loop_NM1_0490"`
HL_0890 []LoopHL0890 `json:"hl_0890,omitempty" xml:"Loop_HL_0890"`
}
type LoopNM10490 struct {
NM1_0490 NM1 `json:"nm1_0490,omitempty" xml:"NM1_0490"`
}
type LoopHL0890 struct {
HL_0890 HL `json:"hl_0890,omitempty" xml:"HL_0890"`
TRN_0900 TRN `json:"trn_0900,omitempty" xml:"TRN_0900"`
NM1_0920 []LoopNM10920 `json:"nm1_0920,omitempty" xml:"Loop_NM1_0920"`
}
type REF struct {
REF01 string `json:"ref01,omitempty" xml:"REF01"`
REF02 string `json:"ref02,omitempty" xml:"REF02"`
REF03 string `json:"ref03,omitempty" xml:"REF03"`
REF04 string `json:"ref04,omitempty" xml:"REF04"`
REF05 string `json:"ref05,omitempty" xml:"REF05"`
REF06 string `json:"ref06,omitempty" xml:"REF06"`
REF07 string `json:"ref07,omitempty" xml:"REF07"`
REF08 string `json:"ref08,omitempty" xml:"REF08"`
REF09 string `json:"ref09,omitempty" xml:"REF09"`
REF10 string `json:"ref10,omitempty" xml:"REF10"`
REF11 string `json:"ref11,omitempty" xml:"REF11"`
REF12 string `json:"ref12,omitempty" xml:"REF12"`
REF13 string `json:"ref13,omitempty" xml:"REF13"`
REF14 string `json:"ref14,omitempty" xml:"REF14"`
REF15 string `json:"ref15,omitempty" xml:"REF15"`
REF16 string `json:"ref16,omitempty" xml:"REF16"`
}
type N3 struct {
N301 string `json:"n301,omitempty" xml:"N301"`
N302 string `json:"n302,omitempty" xml:"N302"`
N303 string `json:"n303,omitempty" xml:"N303"`
N304 string `json:"n304,omitempty" xml:"N304"`
N305 string `json:"n305,omitempty" xml:"N305"`
N306 string `json:"n306,omitempty" xml:"N306"`
N307 string `json:"n307,omitempty" xml:"N307"`
N308 string `json:"n308,omitempty" xml:"N308"`
N309 string `json:"n309,omitempty" xml:"N309"`
N310 string `json:"n310,omitempty" xml:"N310"`
N311 string `json:"n311,omitempty" xml:"N311"`
N312 string `json:"n312,omitempty" xml:"N312"`
N313 string `json:"n313,omitempty" xml:"N313"`
N314 string `json:"n314,omitempty" xml:"N314"`
N315 string `json:"n315,omitempty" xml:"N315"`
N316 string `json:"n316,omitempty" xml:"N316"`
}
type N4 struct {
N401 string `json:"n401,omitempty" xml:"N401"`
N402 string `json:"n402,omitempty" xml:"N402"`
N403 string `json:"n403,omitempty" xml:"N403"`
N404 string `json:"n404,omitempty" xml:"N404"`
N405 string `json:"n405,omitempty" xml:"N405"`
N406 string `json:"n406,omitempty" xml:"N406"`
N407 string `json:"n407,omitempty" xml:"N407"`
N408 string `json:"n408,omitempty" xml:"N408"`
N409 string `json:"n409,omitempty" xml:"N409"`
N410 string `json:"n410,omitempty" xml:"N410"`
N411 string `json:"n411,omitempty" xml:"N411"`
N412 string `json:"n412,omitempty" xml:"N412"`
N413 string `json:"n413,omitempty" xml:"N413"`
N414 string `json:"n414,omitempty" xml:"N414"`
N415 string `json:"n415,omitempty" xml:"N415"`
N416 string `json:"n416,omitempty" xml:"N416"`
}
type LoopNM10920 struct {
NM1_0920 NM1 `json:"nm1_0920,omitempty" xml:"NM1_0920"`
REF_0930 []REF `json:"ref_0930,omitempty" xml:"REF_0930"`
N3_0950 N3 `json:"n3_0950,omitempty" xml:"N3_0950"`
N4_0960 N4 `json:"n4_0960,omitempty" xml:"N4_0960"`
DMG_1000 DMG `json:"dmg_1000,omitempty" xml:"DMG_1000"`
INS_1010 INS `json:"ins_1010,omitempty" xml:"INS_1010"`
}
type DMG struct {
DMG01 string `json:"dmg01,omitempty" xml:"DMG01"`
DMG02 string `json:"dmg02,omitempty" xml:"DMG02"`
DMG03 string `json:"dmg03,omitempty" xml:"DMG03"`
DMG04 string `json:"dmg04,omitempty" xml:"DMG04"`
DMG05 string `json:"dmg05,omitempty" xml:"DMG05"`
DMG06 string `json:"dmg06,omitempty" xml:"DMG06"`
DMG07 string `json:"dmg07,omitempty" xml:"DMG07"`
DMG08 string `json:"dmg08,omitempty" xml:"DMG08"`
DMG09 string `json:"dmg09,omitempty" xml:"DMG09"`
DMG10 string `json:"dmg10,omitempty" xml:"DMG10"`
DMG11 string `json:"dmg11,omitempty" xml:"DMG11"`
DMG12 string `json:"dmg12,omitempty" xml:"DMG12"`
DMG13 string `json:"dmg13,omitempty" xml:"DMG13"`
DMG14 string `json:"dmg14,omitempty" xml:"DMG14"`
DMG15 string `json:"dmg15,omitempty" xml:"DMG15"`
DMG16 string `json:"dmg16,omitempty" xml:"DMG16"`
}
type INS struct {
INS01 string `json:"ins01,omitempty" xml:"INS01"`
INS02 string `json:"ins02,omitempty" xml:"INS02"`
INS03 string `json:"ins03,omitempty" xml:"INS03"`
INS04 string `json:"ins04,omitempty" xml:"INS04"`
INS05 string `json:"ins05,omitempty" xml:"INS05"`
INS06 string `json:"ins06,omitempty" xml:"INS06"`
INS07 string `json:"ins07,omitempty" xml:"INS07"`
INS08 string `json:"ins08,omitempty" xml:"INS08"`
INS09 string `json:"ins09,omitempty" xml:"INS09"`
INS10 string `json:"ins10,omitempty" xml:"INS10"`
INS11 string `json:"ins11,omitempty" xml:"INS11"`
INS12 string `json:"ins12,omitempty" xml:"INS12"`
INS13 string `json:"ins13,omitempty" xml:"INS13"`
INS14 string `json:"ins14,omitempty" xml:"INS14"`
INS15 string `json:"ins15,omitempty" xml:"INS15"`
INS16 string `json:"ins16,omitempty" xml:"INS16"`
}
type TRN struct {
TRN01 string `json:"trn01,omitempty" xml:"TRN01"`
TRN02 string `json:"trn02,omitempty" xml:"TRN02"`
TRN03 string `json:"trn03,omitempty" xml:"TRN03"`
TRN04 string `json:"trn04,omitempty" xml:"TRN04"`
TRN05 string `json:"trn05,omitempty" xml:"TRN05"`
TRN06 string `json:"trn06,omitempty" xml:"TRN06"`
TRN07 string `json:"trn07,omitempty" xml:"TRN07"`
TRN08 string `json:"trn08,omitempty" xml:"TRN08"`
TRN09 string `json:"trn09,omitempty" xml:"TRN09"`
TRN10 string `json:"trn10,omitempty" xml:"TRN10"`
TRN11 string `json:"trn11,omitempty" xml:"TRN11"`
TRN12 string `json:"trn12,omitempty" xml:"TRN12"`
TRN13 string `json:"trn13,omitempty" xml:"TRN13"`
TRN14 string `json:"trn14,omitempty" xml:"TRN14"`
TRN15 string `json:"trn15,omitempty" xml:"TRN15"`
TRN16 string `json:"trn16,omitempty" xml:"TRN16"`
}
type HL struct {
HL01 string `json:"hl01,omitempty" xml:"HL01"`
HL02 string `json:"hl02,omitempty" xml:"HL02"`
HL03 string `json:"hl03,omitempty" xml:"HL03"`
HL04 string `json:"hl04,omitempty" xml:"HL04"`
HL05 string `json:"hl05,omitempty" xml:"HL05"`
HL06 string `json:"hl06,omitempty" xml:"HL06"`
HL07 string `json:"hl07,omitempty" xml:"HL07"`
HL08 string `json:"hl08,omitempty" xml:"HL08"`
HL09 string `json:"hl09,omitempty" xml:"HL09"`
HL10 string `json:"hl10,omitempty" xml:"HL10"`
HL11 string `json:"hl11,omitempty" xml:"HL11"`
HL12 string `json:"hl12,omitempty" xml:"HL12"`
HL13 string `json:"hl13,omitempty" xml:"HL13"`
HL14 string `json:"hl14,omitempty" xml:"HL14"`
HL15 string `json:"hl15,omitempty" xml:"HL15"`
HL16 string `json:"hl16,omitempty" xml:"HL16"`
}
type LoopNM10060 struct {
NM10060 NM1 `json:"nm1_0060,omitempty" xml:"NM1_0060"`
}
type NM1 struct {
NM101 string `json:"nm101,omitempty" xml:"NM101"`
NM102 string `json:"nm102,omitempty" xml:"NM102"`
NM103 string `json:"nm103,omitempty" xml:"NM103"`
NM104 string `json:"nm104,omitempty" xml:"NM104"`
NM105 string `json:"nm105,omitempty" xml:"NM105"`
NM106 string `json:"nm106,omitempty" xml:"NM106"`
NM107 string `json:"nm107,omitempty" xml:"NM107"`
NM108 string `json:"nm108,omitempty" xml:"NM108"`
NM109 string `json:"nm109,omitempty" xml:"NM109"`
NM110 string `json:"nm110,omitempty" xml:"NM110"`
NM111 string `json:"nm111,omitempty" xml:"NM111"`
NM112 string `json:"nm112,omitempty" xml:"NM112"`
NM113 string `json:"nm113,omitempty" xml:"NM113"`
NM114 string `json:"nm114,omitempty" xml:"NM114"`
NM115 string `json:"nm115,omitempty" xml:"NM115"`
NM116 string `json:"nm116,omitempty" xml:"NM116"`
}

View File

@@ -15,6 +15,7 @@ type WebhookResponse struct {
//RideRequest has the data to dispatch a ride
type RideRequest struct {
UserUUID string `json:"user_uuid,omitempty"`
UserConsent bool `json:"user_consent,omitempty"`
Status string `json:"status,omitempty"`
RideID string `json:"ride_id,omitempty"`
RideType string `json:"ride_type,omitempty"`
@@ -158,4 +159,4 @@ type RideRoute struct {
Duration int64 `json:"duration,omitempty"`
ETA int64 `json:"eta,omitempty"`
Bearing int64 `json:"bearing,omitempty"`
}
}

View File

@@ -26,8 +26,11 @@ type User struct {
}
type Contact struct {
Type ContactType `json:"type,omitempty"`
Value string `json:"contact,omitempty"`
ID string `json:"id,omitempty"`
User User `json:"-"`
Type ContactType `json:"type,omitempty"`
Value string `json:"contact,omitempty"`
Author User `json:"-"`
}
type ContactType struct {

11
authorization_model.conf Normal file
View File

@@ -0,0 +1,11 @@
[request_definition]
r = role, objectsRole, orgType, objectsOrgType, orgRelation, objectsRelation, obj, act
[policy_definition]
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.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 == "*")

115
authorization_policy.csv Normal file
View File

@@ -0,0 +1,115 @@
p, AD, *, *, *, *, *, *, *
p, *, *, *, *, *, *, /v1/authenticate/portal, POST
p, *, *, *, *, *, *, /v1/notification/ws, GET
p, *, *, *, *, *, *, /health/, GET
p, *, *, *, *, *, *, /v1/nemt/users/contacttype, GET
p, *, *, *, *, *, [self], /v1/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, *, *, *, *, *, *, /v1/nemt/organization/name, GET
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
p, SPT, *, programsupport, *, *, *, /v1/nemt/organization, GET
p, SCHDAD, *, provider, *, *, *, /v1/nemt/organization, GET
p, BCBSIAD, *, bcbsi, *, *, *, /v1/nemt/organization, GET
p, BDCAD, *, techsupport, *, *, *, /v1/nemt/organization, GET
p, PLANAD, *, plan, *, *, *, /v1/nemt/organization, GET
p, AD, *, *, *, *, *, /v1/nemt/organization, GET
p, SP, *, provider, *, *, *, /v1/nemt/eligibility, POST
p, SP, *, plan, *, *, *, /v1/nemt/eligibility, POST
p, SPT, *, programsupport, *, *, *, /v1/nemt/eligibility, POST
p, SCHDAD, *, provider, *, *, *, /v1/nemt/eligibility, POST
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
1 p AD * * * * * * *
2 p * * * * * * /v1/authenticate/portal POST
3 p * * * * * * /v1/notification/ws GET
4 p * * * * * * /health/ GET
5 p * * * * * * /v1/nemt/users/contacttype GET
6 p * * * * * [self] /v1/nemt/users/* GET
7 p * * * * * [self] /v1/nemt/users/portal/* DELETE
8 p * * * * * [self] /v1/nemt/users/portal/* POST
9 p * * * * * [self] /v1/nemt/users/portal/* GET
10 p *AD * * * * * /v1/nemt/users/ GET
11 p BDCAD SP * * * [other] /v1/nemt/users/*/ GET
12 p BDCAD SP * * * [other] /v1/nemt/users/portal/* DELETE
13 p BDCAD SP * * * [other] /v1/nemt/users/portal/* POST
14 p BDCAD SP * * * [other] /v1/nemt/users/portal/* GET
15 p BDCAD SPT * * * [other] /v1/nemt/users/*/ GET
16 p BDCAD SPT * * * [other] /v1/nemt/users/portal/* DELETE
17 p BDCAD SPT * * * [other] /v1/nemt/users/portal/* POST
18 p BDCAD SPT * * * [other] /v1/nemt/users/portal/* GET
19 p BDCAD US * * * [other] /v1/nemt/users/*/ GET
20 p BDCAD US * * * [other] /v1/nemt/users/portal/* DELETE
21 p BDCAD US * * * [other] /v1/nemt/users/portal/* POST
22 p BDCAD US * * * [other] /v1/nemt/users/portal/* GET
23 p BCBSIAD SP * * * [other] /v1/nemt/users/*/ GET
24 p BCBSIAD SP * * * [other] /v1/nemt/users/portal/* DELETE
25 p BCBSIAD SP * * * [other] /v1/nemt/users/portal/* POST
26 p BCBSIAD SP * * * [other] /v1/nemt/users/portal/* GET
27 p BCBSIAD US * * * [other] /v1/nemt/users/*/ GET
28 p BCBSIAD US * * * [other] /v1/nemt/users/portal/* DELETE
29 p BCBSIAD US * * * [other] /v1/nemt/users/portal/* POST
30 p BCBSIAD US * * * [other] /v1/nemt/users/portal/* GET
31 p BCBSIAD SPT * * * [other] /v1/nemt/users/*/ GET
32 p BCBSIAD SPT * * * [other] /v1/nemt/users/portal/* DELETE
33 p BCBSIAD SPT * * * [other] /v1/nemt/users/portal/* POST
34 p BCBSIAD SPT * * * [other] /v1/nemt/users/portal/* GET
35 p PLANAD SPT * * [equal] [other] /v1/nemt/users/*/ GET
36 p PLANAD SPT * * [equal] [other] /v1/nemt/users/portal/* DELETE
37 p PLANAD SPT * * [equal] [other] /v1/nemt/users/portal/* POST
38 p PLANAD SPT * * [equal] [other] /v1/nemt/users/portal/* GET
39 p PLANAD US * * [equal] [other] /v1/nemt/users/*/ GET
40 p PLANAD US * * [equal] [other] /v1/nemt/users/portal/* DELETE
41 p PLANAD US * * [equal] [other] /v1/nemt/users/portal/* POST
42 p PLANAD US * * [equal] [other] /v1/nemt/users/portal/* GET
43 p PLANAD SP * * [equal] [other] /v1/nemt/users/*/ GET
44 p PLANAD SP * * [equal] [other] /v1/nemt/users/portal/* DELETE
45 p PLANAD SP * * [equal] [other] /v1/nemt/users/portal/* POST
46 p PLANAD SP * * [equal] [other] /v1/nemt/users/portal/* GET
47 p SCHDAD US * * [parent] [other] /v1/nemt/users/*/ GET
48 p SCHDAD US * * [parent] [other] /v1/nemt/users/portal/* DELETE
49 p SCHDAD US * * [parent] [other] /v1/nemt/users/portal/* POST
50 p SCHDAD US * * [parent] [other] /v1/nemt/users/portal/* GET
51 p SCHDAD SP * * [parent] [other] /v1/nemt/users/*/ GET
52 p SCHDAD SP * * [parent] [other] /v1/nemt/users/portal/* DELETE
53 p SCHDAD SP * * [parent] [other] /v1/nemt/users/portal/* POST
54 p SCHDAD SP * * [parent] [other] /v1/nemt/users/portal/* GET
55 p SCHDAD SPT * * [parent] [other] /v1/nemt/users/*/ GET
56 p SCHDAD SPT * * [parent] [other] /v1/nemt/users/portal/* DELETE
57 p SCHDAD SPT * * [parent] [other] /v1/nemt/users/portal/* POST
58 p SCHDAD SPT * * [parent] [other] /v1/nemt/users/portal/* GET
59 p SCHDAD SP * * [equal*] [other] /v1/nemt/users/*/ GET
60 p SCHDAD SP * * [equal*] [other] /v1/nemt/users/portal/* DELETE
61 p SCHDAD SP * * [equal*] [other] /v1/nemt/users/portal/* POST
62 p SCHDAD SP * * [equal*] [other] /v1/nemt/users/portal/* GET
63 p SCHDAD US * * [equal*] [other] /v1/nemt/users/*/ GET
64 p SCHDAD US * * [equal*] [other] /v1/nemt/users/portal/* DELETE
65 p SCHDAD US * * [equal*] [other] /v1/nemt/users/portal/* POST
66 p SCHDAD US * * [equal*] [other] /v1/nemt/users/portal/* GET
67 p SCHDAD SPT * * [equal*] [other] /v1/nemt/users/*/ GET
68 p SCHDAD SPT * * [equal*] [other] /v1/nemt/users/portal/* DELETE
69 p SCHDAD SPT * * [equal*] [other] /v1/nemt/users/portal/* POST
70 p SCHDAD SPT * * [equal*] [other] /v1/nemt/users/portal/* GET
71 p SCHDAD SCHDAD * * [equal*] [other] /v1/nemt/users/*/ GET
72 p SCHDAD SCHDAD * * [equal*] [other] /v1/nemt/users/portal/* DELETE
73 p SCHDAD SCHDAD * * [equal*] [other] /v1/nemt/users/portal/* POST
74 p SCHDAD SCHDAD * * [equal*] [other] /v1/nemt/users/portal/* GET
75 p SPT * programsupport * * [other] /v1/nemt/users/ GET
76 p SPT * programsupport * * [other] /v1/nemt/users/* GET
77 p * * * * * * /v1/nemt/organization/name GET
78 p * * * * * * /v1/nemt/organization/type GET
79 p AD * * * * * /v1/nemt/organization/* GET
80 p AD * * * * * /v1/nemt/organization/* POST
81 p AD * * * * * /v1/nemt/organization/* PUT
82 p AD * * * * * /v1/nemt/organization/* DELETE
83 p SCHDAD * * * [equal*] * /v1/nemt/organization/* GET
84 p SCHDAD * * * [equal*] * /v1/nemt/organization/* POST
85 p SCHDAD * * * [equal*] * /v1/nemt/organization/* PUT
86 p SCHDAD * * * [equal*] * /v1/nemt/organization/* DELETE
87 p PLANAD * * * [equal*] * /v1/nemt/organization/* GET
88 p PLANAD * * * [equal*] * /v1/nemt/organization/* POST
89 p PLANAD * * * [equal*] * /v1/nemt/organization/* PUT
90 p PLANAD * * * [equal*] * /v1/nemt/organization/* DELETE
91 p BDCAD * * * * * /v1/nemt/organization/* GET
92 p BDCAD * * * * * /v1/nemt/organization/* POST
93 p BDCAD * * * * * /v1/nemt/organization/* PUT
94 p BDCAD * * * * * /v1/nemt/organization/* DELETE
95 p BCBSIAD * * * * * /v1/nemt/organization/* GET
96 p BCBSIAD * * * * * /v1/nemt/organization/* POST
97 p BCBSIAD * * * * * /v1/nemt/organization/* PUT
98 p BCBSIAD * * * * * /v1/nemt/organization/* DELETE
99 p SPT * programsupport * * * /v1/nemt/organization/* GET
100 p SP * provider * * * /v1/nemt/organization GET
101 p SP * plan * * * /v1/nemt/organization GET
102 p SPT * programsupport * * * /v1/nemt/organization GET
103 p SCHDAD * provider * * * /v1/nemt/organization GET
104 p BCBSIAD * bcbsi * * * /v1/nemt/organization GET
105 p BDCAD * techsupport * * * /v1/nemt/organization GET
106 p PLANAD * plan * * * /v1/nemt/organization GET
107 p AD * * * * * /v1/nemt/organization GET
108 p SP * provider * * * /v1/nemt/eligibility POST
109 p SP * plan * * * /v1/nemt/eligibility POST
110 p SPT * programsupport * * * /v1/nemt/eligibility POST
111 p SCHDAD * provider * * * /v1/nemt/eligibility POST
112 p BCBSIAD * bcbsi * * * /v1/nemt/eligibility POST
113 p BDCAD * techsupport * * * /v1/nemt/eligibility POST
114 p PLANAD * plan * * * /v1/nemt/eligibility POST
115 p AD * * * * * /v1/nemt/eligibility POST

View File

@@ -19,6 +19,8 @@ pipelines:
- cp -R static/* ./dist/static/
- cp -R docs/swagger/ ./dist/docs/
- cp config.prd.toml ./dist/config.toml
- cp authorization_model.conf ./dist/authorization_model.conf
- cp authorization_policy.csv ./dist/authorization_policy.csv
- docker build -f Dockerfile.run -t nemt-portal-api-run:prod --force-rm --build-arg BIN_NAME=nemt-portal-api --build-arg APP_NAME=nemt-portal-api .
- apt-get update -y && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get -y autoremove && apt-get clean
- apt-get install python3-pip -y
@@ -46,6 +48,8 @@ pipelines:
- cp -R static/* ./dist/static/
- cp -R docs/swagger/ ./dist/docs/
- cp config.stg.toml ./dist/config.toml
- cp authorization_model.conf ./dist/authorization_model.conf
- cp authorization_policy.csv ./dist/authorization_policy.csv
- docker build -f Dockerfile.run -t nemt-portal-api-run:dev --force-rm --build-arg BIN_NAME=nemt-portal-api --build-arg APP_NAME=nemt-portal-api .
- apt-get update -y && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get -y autoremove && apt-get clean
- apt-get install python3-pip -y

View File

@@ -37,6 +37,7 @@ db = 0
pass = "3rdaP3KL2x%V"
prefix = "nemt-portal-api-dev"
default-expiration = "5m"
master-name = "devmaster01"
[log]
log-to-file = false
@@ -73,8 +74,8 @@ user-uuid = "11a49fa4-fbc7-4fe9-87fe-52a5bc3b71f8"
[bxe]
url = "https://api-pve.bcbs.com/BXDirectConnect/V30"
key = "dacg7jtsmb6ajr3z553jbczg"
secret = "vFhNeWE8JdJpbDZQtcm6AHjX"
key = "c63z7gv9a5qz2zgx7zcm3253"
secret = "hK4Yc9jtBrxaZTr4UU2VsfX9"
[blue365]
url = "https://api-cloud.bcbs.com/blue365deals-stg/v1/validatePrefix/"

View File

@@ -37,6 +37,7 @@ db = 0
pass = "3rdaP3KL2x%V"
prefix = "portal-api-prod"
default-expiration = "5m"
master-name = "master01"
[log]
log-to-file = false

View File

@@ -37,6 +37,7 @@ db = 0
pass = "3rdaP3KL2x%V"
prefix = "portal-api-test"
default-expiration = "5m"
master-name = "devmaster01"
[log]
log-to-file = false
@@ -73,8 +74,8 @@ user-uuid = "11a49fa4-fbc7-4fe9-87fe-52a5bc3b71f8"
[bxe]
url = "https://api-pve.bcbs.com/BXDirectConnect/V30"
key = "dacg7jtsmb6ajr3z553jbczg"
secret = "vFhNeWE8JdJpbDZQtcm6AHjX"
key = "c63z7gv9a5qz2zgx7zcm3253"
secret = "hK4Yc9jtBrxaZTr4UU2VsfX9"
[blue365]
url = "https://api-cloud.bcbs.com/blue365deals-stg/v1/validatePrefix/"

View File

@@ -80,7 +80,9 @@ 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`
ON d.user_id = f.user_id
INNER JOIN tab_ride g
ON g.ride_id = a.ride_id `
}
func (c *notificationRepo) GetLastNotificationFromPhoneNumber(notificationType string, phoneNumber string, status string) (entity.Notification, error) {

View File

@@ -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 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

View File

@@ -63,7 +63,8 @@ func (c *userRepo) GetContacts(userID int64) ([]entity.ContactInfo, error) {
a.user_id,
b.contact_type_id,
b.key contact_type_key,
b.name contact_type_name
b.name contact_type_name,
a.contact_uuid
FROM tab_contact a
INNER JOIN tab_contact_type b
ON a.contact_type_id = b.contact_type_id
@@ -79,7 +80,7 @@ func (c *userRepo) GetContacts(userID int64) ([]entity.ContactInfo, error) {
retVal := make([]entity.ContactInfo, 0)
for rows.Next() {
contact := entity.ContactInfo{}
err = rows.Scan(&contact.ID, &contact.Value, &contact.UserID, &contact.Type.ID, &contact.Type.Key, &contact.Type.Value)
err = rows.Scan(&contact.ID, &contact.Value, &contact.User.ID, &contact.Type.ID, &contact.Type.Key, &contact.Type.Value, &contact.UUID)
if err != nil {
return nil, err
}
@@ -354,9 +355,11 @@ func (c *userRepo) Create(user entity.User) (retVal entity.User, err error) {
if retVal.Email != "" {
contact := entity.ContactInfo{
Type: entity.ContactType{Key: "email"},
Value: retVal.Email,
UserID: retVal.ID,
Type: entity.ContactType{Key: "email"},
Value: retVal.Email,
User: entity.User{
ID: retVal.ID,
},
}
contact, err = c.addContactInfo(contact)
@@ -367,9 +370,11 @@ func (c *userRepo) Create(user entity.User) (retVal entity.User, err error) {
if retVal.PhoneNumber != "" {
contact := entity.ContactInfo{
Type: entity.ContactType{Key: "phone"},
Value: retVal.PhoneNumber,
UserID: retVal.ID,
Type: entity.ContactType{Key: "phone"},
Value: retVal.PhoneNumber,
User: entity.User{
ID: retVal.ID,
},
}
contact, err = c.addContactInfo(contact)
@@ -387,19 +392,10 @@ func (c *userRepo) SaveContact(contact entity.ContactInfo) (entity.ContactInfo,
func (c *userRepo) RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error) {
const (
query = `INSERT INTO tab_contact(contact_type_id, user_id, contact)
SELECT a.contact_type_id, ? user_id, ? contact
FROM
tab_contact_type a
LEFT JOIN tab_contact b
ON a.contact_type_id = b.contact_type_id
AND b.user_id = ?
AND b.contact = ?
WHERE a.key = ?
AND b.contact_id IS NULL;`
query = `DELETE FROM tab_contact WHERE contact_uuid = ?;`
)
result, err := c.conn.Exec(query, contact.UserID, contact.Value, contact.UserID, contact.Value, contact.Type.Key)
result, err := c.conn.Exec(query, contact.UUID)
if err != nil {
return contact, err
}
@@ -415,8 +411,8 @@ func (c *userRepo) RemoveContact(contact entity.ContactInfo) (entity.ContactInfo
func (c *userRepo) addContactInfo(contact entity.ContactInfo) (entity.ContactInfo, error) {
const (
query = `INSERT INTO tab_contact(contact_type_id, user_id, contact)
SELECT a.contact_type_id, ? user_id, ? contact
query = `INSERT INTO tab_contact(contact_type_id, user_id, contact, contact_uuid)
SELECT a.contact_type_id, ? user_id, ? contact, ? contact_uuid
FROM
tab_contact_type a
LEFT JOIN tab_contact b
@@ -427,7 +423,13 @@ func (c *userRepo) addContactInfo(contact entity.ContactInfo) (entity.ContactInf
AND b.contact_id IS NULL;`
)
result, err := c.conn.Exec(query, contact.UserID, contact.Value, contact.UserID, contact.Value, contact.Type.Key)
sUUID, err := uuid.NewV4()
if err != nil {
return contact, err
}
contact.UUID = sUUID.String()
result, err := c.conn.Exec(query, contact.User.ID, contact.Value, contact.UUID, contact.User.ID, contact.Value, contact.Type.Key)
if err != nil {
return contact, err
}

View File

@@ -27,6 +27,8 @@ type UserRepo interface {
GetAddressByUUID(addressUUID string) (entity.Address, error)
GetContactType() (retVal []entity.ContactType, err error)
RemoveAddress(addressUUID string) error
SaveContact(contact entity.ContactInfo) (entity.ContactInfo, error)
RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error)
}
// RideRepo defines the data set for Rides
@@ -68,23 +70,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)
}

View File

@@ -34,8 +34,10 @@ type User struct {
type ContactInfo struct {
ID int64 `db:"contact_id" json:"contact_id"`
UUID string `db:"contact_uuid" json:"contact_uuid"`
Type ContactType `db:"contact_type" json:"contact_type"`
UserID int64 `db:"user_id" json:"-"`
User User `db:"user" json:"-"`
Author User `db:"author" json:"-"`
Value string `db:"value" json:"value"`
}

View File

@@ -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) {

View File

@@ -82,6 +82,26 @@ func (s *userService) SaveAddress(address entity.Address) (entity.Address, error
return s.svc.db.Users().SaveAddress(address)
}
func (s *userService) SaveContact(contact entity.ContactInfo) (entity.ContactInfo, error) {
user, err := s.svc.db.Users().GetByUUID(contact.User.UUID, "")
if err != nil {
return entity.ContactInfo{}, nil
}
contact.User = user
return s.svc.db.Users().SaveContact(contact)
}
func (s *userService) RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error) {
user, err := s.svc.db.Users().GetByUUID(contact.User.UUID, "")
if err != nil {
return entity.ContactInfo{}, nil
}
contact.User = user
return s.svc.db.Users().RemoveContact(contact)
}
// GetAddressByUUID returns a list of users by profile
func (s *userService) GetAddressByUUID(addressUUID string) (entity.Address, error) {
return s.svc.db.Users().GetAddressByUUID(addressUUID)

View File

@@ -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
}
]
}

View File

@@ -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
}
]
}

View File

@@ -42,3 +42,7 @@ import:
- package: github.com/ttacon/builder
- package: github.com/casbin/casbin
version: ~1.5.0
- package: github.com/Knetic/govaluate
version: 9aa49832a739dcd78a5542ff189fb82c3e423116
- package: github.com/pkg/errors
version: ^0.8.0

View File

@@ -31,10 +31,11 @@ type RedisCache struct {
func Instance(cfg *config.Config) contract.CacheManager {
once.Do(func() {
client := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "master01",
MasterName: cfg.Cache.Master,
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}

View File

@@ -119,6 +119,7 @@ type CacheConfig struct {
Pass string
Prefix string
DefaultExpiration time.Duration
Master string
}
// CacheConfig represents the configuration values about the documentation config.
@@ -194,6 +195,7 @@ 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"),

1602
returnExample.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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)
}

View File

@@ -0,0 +1 @@
package authorization

View File

@@ -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)
}

View File

@@ -0,0 +1,76 @@
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.Profiles) < 1 {
return viewmodel.Organization{}, fmt.Errorf("User has no organizations %v", user)
}
return user.Profiles[0].Organization, nil
}
func grabOrgFromUserDirectly(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
}
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)
}

View File

@@ -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
}

View File

@@ -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 := grabOrgFromUserDirectly(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
}

View File

@@ -1,6 +1,10 @@
package eligibilityroute
import (
"encoding/xml"
"fmt"
"html"
"strings"
"sync"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
@@ -42,8 +46,22 @@ func (c *controller) handleEligibility(ctx echo.Context) error {
ret, err := c.bcbsi.BXE.CheckEligibility(eligibility)
if err != nil {
fmt.Println("Error Here: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
return routeutils.ResponseAPIOK(ctx, ret)
if ret.QueryResult.HIPPA271.T271 != "" {
xmlString := html.UnescapeString(ret.QueryResult.HIPPA271.T271)
xmlReader := strings.NewReader(xmlString)
var f viewmodel.Interchange271
err = xml.NewDecoder(xmlReader).Decode(&f)
if err != nil {
fmt.Println("Error to unmarshal: ", err.Error())
}
return ctx.JSON(200, f)
} else {
return routeutils.ResponseAPIOK(ctx, ret)
}
}

View File

@@ -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
@@ -78,7 +84,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 +103,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 +128,21 @@ 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)
}
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)
}
@@ -132,12 +162,26 @@ 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)
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)
}
resp, err := c.svc.Organization.GetByUUID(orgUUID, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
@@ -151,11 +195,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 +212,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 +229,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 +266,31 @@ func (c *controller) handleAddAddress(ctx echo.Context) error {
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.CreatedUser.ID = createdUser["useruuid"].(string)
address.UpdatedUser.ID = address.CreatedUser.ID
_, err = c.svc.Organization.SetOrganizationAddress(orgUUID, address)
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
resp, err := c.svc.Organization.GetByUUID(orgUUID)
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
_, err = c.svc.Organization.SetOrganizationAddress(orgUUID, address, 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)
}
@@ -250,19 +310,19 @@ func (c *controller) handleRemoveContact(ctx echo.Context) error {
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{})
contact.UpdatedUser.ID = createdUser["useruuid"].(string)
err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact)
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
resp, err := c.svc.Organization.GetByUUID(orgUUID)
contact.UpdatedUser.ID = authUser.ID
err = c.svc.Organization.InactivateOrganizationContact(orgUUID, contact, 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)
}
@@ -282,20 +342,29 @@ func (c *controller) handleAddContact(ctx echo.Context) error {
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{})
contact.CreatedUser.ID = createdUser["useruuid"].(string)
contact.UpdatedUser.ID = contact.CreatedUser.ID
_, err = c.svc.Organization.SetOrganizationContact(orgUUID, contact)
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
resp, err := c.svc.Organization.GetByUUID(orgUUID)
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
_, err = c.svc.Organization.SetOrganizationContact(orgUUID, contact, 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)
}

View File

@@ -104,8 +104,8 @@ func (c *controller) handleParticipating(ctx echo.Context) error {
// long = -87.624225
// }
lat = 40.442875
long = -80.003112
lat = 41.819078
long = -87.623129
if len(mukID) > 0 {
query = ""
@@ -152,8 +152,8 @@ func (c *controller) handleList(ctx echo.Context) error {
providerParams := npdmodel.ProviderSearchParams{
Name: name,
SearchBy: searchBy,
Latitude: 40.442875,
Longitude: -80.003112,
Latitude: 41.819078,
Longitude: -87.623129,
Distance: distance,
Limit: limit,
Offset: 0,

View File

@@ -33,6 +33,18 @@ func ResponseAPIOK(c echo.Context, data interface{}) error {
return c.JSON(http.StatusOK, data)
}
// ResponseAPIErrorWithData returns a standard API error with additional data to the response
func ResponseAPIErrorWithData(c echo.Context, status int, message string, redirect bool, data interface{}) error {
returnValue := resultWrapper{
Error: true,
Message: message,
Redirect: redirect,
Data: data,
}
return c.JSON(status, returnValue)
}
// ResponseAPIError returns a standard API error to the response
func ResponseAPIError(c echo.Context, status int, message string, redirect bool) error {
returnValue := resultWrapper{
@@ -49,6 +61,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)
@@ -59,6 +76,11 @@ func ResponseAPIValidationError(c echo.Context, message string) error {
return ResponseAPIError(c, http.StatusUnprocessableEntity, message, false)
}
// ResponseAPICustomValidationError returns a standard API validation error with custom data to the response
func ResponseAPICustomValidationError(c echo.Context, message string, data interface{}) error {
return ResponseAPIErrorWithData(c, http.StatusUnprocessableEntity, message, false, data)
}
// ResponseAPIFieldValidationError returns a standard API field validation error to the response
func ResponseAPIFieldValidationError(c echo.Context, field string, message string) error {
err := errors.NewValidationError(field, message)
@@ -70,6 +92,11 @@ func ResponseAPINotFoundError(c echo.Context) error {
return ResponseAPIError(c, http.StatusNotFound, "Not Found", false)
}
//ResponseAPINotEligible returns a standard API not eligible to the response
func ResponseAPINotEligibleError(c echo.Context) error {
return ResponseAPIError(c, http.StatusForbidden, "Eligibility Not Found or Error", false)
}
func ignoreDefaultWrappedErrors(c echo.Context, errorToHandle *errors.WrappedError, handler func(echo.Context, error) error) error {
err := errorToHandle.GetOriginalError()

View File

@@ -15,6 +15,7 @@ import (
"bitbucket.org/nemt/nemt-portal-api/infra/auth"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
"bitbucket.org/nemt/nemt-portal-api/server/validation"
"github.com/labstack/echo"
uuid "github.com/satori/go.uuid"
"google.golang.org/api/googleapi/transport"
@@ -231,6 +232,11 @@ func (c *controller) handle(ctx echo.Context) error {
return routeutils.ResponseAPIValidationError(ctx, "User not found")
}
//Validate ride request
if validationErrors := validation.ValidateRide(&requestRide, &user) ; len(validationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "ride validation failed", validationErrors)
}
createdUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
@@ -869,4 +875,4 @@ func (c *controller) handleReady(ctx echo.Context) error {
}()
return routeutils.ResponseAPIOK(ctx, nextRide)
}
}

View File

@@ -8,13 +8,18 @@ import (
"time"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain"
"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/validation"
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
"github.com/labstack/echo"
"golang.org/x/net/context"
"googlemaps.github.io/maps"
)
var (
@@ -23,15 +28,17 @@ var (
)
type controller struct {
svc *applicationservice.Service
cfg *config.Config
svc *applicationservice.Service
cfg *config.Config
bcbsi *bcbsi.Service
}
func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *controller {
once.Do(func() {
instance = &controller{
svc: svc,
cfg: cfg,
svc: svc,
cfg: cfg,
bcbsi: bcbsi.New(cfg),
}
})
return instance
@@ -127,6 +134,62 @@ func (c *controller) handleRemoveAddress(ctx echo.Context) error {
return routeutils.ResponseNoContent(ctx, addressID)
}
func (c *controller) handlePortalContact(ctx echo.Context) error {
userID, err := routeutils.GetAndValidateStringParam(ctx, "user_uuid", "mandatory field")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
item, err := c.svc.Users.GetByUUID(userID, "")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
createdUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if item.ID == "" {
return routeutils.ResponseAPIValidationError(ctx, "User not found")
} else {
var Contact viewmodel.Contact
if err := ctx.Bind(&Contact); err != nil {
return routeutils.HandleAPIError(ctx, err)
}
Contact.User = item
Contact.Author = createdUser
Contact, err = c.svc.Users.SaveContact(Contact)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
// Contact.User, err = c.svc.Users.GetByUUID(userID, "")
// if err != nil {
// return routeutils.HandleAPIError(ctx, err)
// }
return routeutils.ResponseAPIOK(ctx, Contact)
}
}
func (c *controller) handleRemoveContact(ctx echo.Context) error {
contactUUID, err := routeutils.GetAndValidateStringParam(ctx, "contact_uuid", "mandatory field")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
contact := viewmodel.Contact{
ID: contactUUID,
}
contact, err = c.svc.Users.RemoveContact(contact)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
return routeutils.ResponseNoContent(ctx, contact)
}
func (c *controller) handleMemberAddress(ctx echo.Context) error {
userID, err := routeutils.GetAndValidateStringParam(ctx, "user_uuid", "mandatory field")
if err != nil {
@@ -269,11 +332,17 @@ func (c *controller) handleGetPortal(ctx echo.Context) error {
}
func (c *controller) handleMember(ctx echo.Context) error {
fmt.Println("\n\nHandle member\n\n")
var user viewmodel.User
if err := ctx.Bind(&user); err != nil {
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 +383,67 @@ func (c *controller) handleMember(ctx echo.Context) error {
}
user.Profiles = append(user.Profiles, profile)
user, err = c.svc.Users.Create(user)
eligibility := viewmodel.Eligibility{}
eligibility.Provider.ProviderNPI = "1699849786"
eligibility.Provider.ProviderName = "LITHOLINK CORPORATION"
eligibility.TrackingID = user.ID
eligibility.Subscriber.SubscriberID = *user.Member
eligibility.Subscriber.PatientType = "S"
eligibility.Subscriber.Name.First = user.First
eligibility.Subscriber.Name.Last = user.Last
eligibility.Subscriber.DemographicInfo.DateOfBirth = *user.BirthDate
eligibility.Subscriber.DemographicInfo.Gender = *user.Gender
eligibility.ServiceInfo.DateOfService = time.Now()
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
fmt.Println("\n\nGet271\n\n")
resp, err := c.bcbsi.BXE.Get271(eligibility)
if err != nil {
fmt.Println("Eligibility Not Found or Error: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
address := viewmodel.Address{}
header := resp.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N3_0950
body := resp.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N4_0960
address.AddressTypeName = "Home"
address.AddressType = "home"
address.Name = fmt.Sprintf("%s, %s", header.N301, body.N401)
address.Address = fmt.Sprintf("%s, %s", header.N301, body.N401)
address.CreatedUserUUID = authUser.ID
address.User = user
googleMapsAPI, err := maps.NewClient(maps.WithClientIDAndSignature("gme-bluecrossandblue1", "msqgD-jdqCyR0M_1u5C1HION5iI="))
if err != nil {
fmt.Println("Error to instantiate googles api: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
r := &maps.GeocodingRequest{
Address: address.Address + " " + body.N402 + ", " + body.N403,
}
result, err := googleMapsAPI.Geocode(context.Background(), r)
if err != nil {
fmt.Println("Error to instantiate googles api: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
if len(result) > 0 {
address.Latitude = result[0].Geometry.Location.Lat
address.Longitude = result[0].Geometry.Location.Lng
_, err := c.svc.Users.SaveAddress(address)
if err != nil {
fmt.Println("Error to save address: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
}
//Get ZIP code and check if it is participating
user, err = c.svc.Users.Create(user, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
@@ -328,6 +457,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 +494,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 +508,15 @@ 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 !authorization.CanCreateUser(authUser, user) {
return routeutils.ResponseAPIAuthorizationError(ctx)
}
if len(user.Profiles) == 0 {
return routeutils.ResponseAPIAuthError(ctx, "profile is required", false)
}
@@ -396,6 +539,10 @@ func (c *controller) handlePortal(ctx echo.Context) error {
}
user.Pass = string(pass)
if passwordValidationErrors := validation.ValidatePassword(&user) ; len(passwordValidationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "Password not strong enough", passwordValidationErrors)
}
if len(user.Name) == 0 && len(user.First) == 0 && len(user.Last) == 0 {
return routeutils.ResponseAPIAuthError(ctx, "name is required", false)
}
@@ -404,7 +551,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)
}

View File

@@ -17,6 +17,8 @@ const (
userDetailRoute = "/portal/:user_uuid"
userAddressRoute = "/portal/:user_uuid/address"
userRemoveAddressRoute = "/portal/:user_uuid/address/:address_uuid"
userContactRoute = "/portal/:user_uuid/contact"
userRemoveContactRoute = "/portal/:user_uuid/contact/:contact_uuid"
portalRoute = "/portal"
portalBulkRoute = "/portal/bulk"
contacttypeRoute = "/contacttype"
@@ -41,6 +43,9 @@ func Register(r *echo.Group, cfg *config.Config, svc *applicationservice.Service
r.POST(userAddressRoute, ctrl.handlePortalAddress)
r.PUT(userRemoveAddressRoute, ctrl.handleRemoveAddress)
r.POST(userContactRoute, ctrl.handlePortalContact)
r.PUT(userRemoveContactRoute, ctrl.handleRemoveContact)
//Can be cached
r.GET(contacttypeRoute, ctrl.handleContactType)

View File

@@ -52,16 +52,16 @@ func (s *Server) Run() error {
s.srv.Debug = s.cfg.App.Debug
err := serverconfig.SetMiddlewares(s.srv, s.cfg, s.log, s.svc)
if err != nil {
return errors.Wrap(err)
}
entityMapper := entitymapping.New()
notificationService := notificationservice.New(s.svc, entityMapper, s.cfg, s.cache)
appService := applicationservice.New(s.svc, entityMapper, notificationService, s.cfg)
tncService := tncservice.New(s.svc, entityMapper, s.cfg, notificationService)
err := serverconfig.SetMiddlewares(s.srv, s.cfg, s.log, s.svc, appService)
if err != nil {
return errors.Wrap(err)
}
router.Register(s.srv, s.cfg, appService, tncService, notificationService)
err = s.srv.Start(fmt.Sprintf(":%d", s.cfg.HTTP.Port))

View File

@@ -1,6 +1,8 @@
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"
@@ -44,6 +46,8 @@ func MiddlewareWithConfig(cfg *config.Config, svc *applicationservice.Service, l
config := &DefaultConfig
config.Enforcer = casbin.NewEnforcer("authorization_model.conf", "authorization_policy.csv")
config.Svc = svc
config.Logger = log
config.Application = cfg
@@ -68,26 +72,128 @@ func setAuthorizationMiddleware(e *echo.Echo, log *logger.Logger, cfg *config.Co
func (a *Config) CheckPermission(c echo.Context) bool {
user, err := auth.GetUserDetail(c, a.Application)
if err != nil {
a.Logger.Warningf("Cannot get user details. %v ", err)
a.Logger.Warningf("Cannot get user details. %v\n", err)
user = viewmodel.User{}
}
method := c.Request().Method
path := c.Request().URL.Path
//objectOrganization := a.organizationGoverningObject(c, user)
return a.Enforcer.Enforce(user, path, method)
objectsRole, objectsOrganization, objectsOrganizationType, object := a.policyObjectAttributes(c, user)
currentUsersOrganization := viewmodel.Organization{}
if len(user.Organizations) > 0 {
currentUsersOrganization = user.Organizations[0]
}
currentUsersRole := viewmodel.Profile{}
if len(user.Profiles) > 0 {
currentUsersRole = user.Profiles[0]
}
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)
}
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{}) {
existingUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) > 0
newUser := strings.Contains(c.Request().URL.Path, "/users") && len(c.ParamValues()) <= 0
var object interface{}
const userIDParamName = "user_uuid"
existingUser := strings.Contains(c.Request().URL.Path, "/users/") && c.Param(userIDParamName) != ""
newUser := strings.Contains(c.Request().URL.Path, "/users/") && c.Param(userIDParamName) == ""
const organizationIDParamName = "org_uuid"
existingOrganization := strings.Contains(c.Request().URL.Path, "/organization") && c.Param(organizationIDParamName) != ""
newOrganization := strings.Contains(c.Request().URL.Path, "/organization") && c.Param(organizationIDParamName) == ""
fmt.Println("**********")
fmt.Printf("url %v\n", c.Param(userIDParamName))
fmt.Printf("user %v\n", userDetails.ID)
fmt.Printf("existing %v\n", existingUser)
fmt.Printf("new %v\n", newUser)
fmt.Println("**********")
switch {
case existingUser:
user, _ := a.Svc.Users.GetByUUID(c.ParamValues()[0], "")
result = user.Organizations[0]
case newUser:
result = userDetails.Organizations[0]
object, _ = a.Svc.Users.GetByUUID(c.Param(userIDParamName), "")
case newUser && len(userDetails.Organizations) > 0:
object = userDetails
case existingOrganization:
object, _ = a.Svc.Organization.GetByUUID(c.Param(organizationIDParamName), userDetails)
case newOrganization:
object = viewmodel.Organization{}
}
return
objectsRole := viewmodel.Profile{}
switch obj := object.(type) {
case viewmodel.User:
if len(obj.Profiles) > 0 {
objectsRole = obj.Profiles[0]
}
}
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 {
if requestOrganization.UUID == currentUsersOrganization.UUID {
return "[equal]"
}
for _, childOrg := range currentUsersOrganization.ChildOrgs {
if childOrg.UUID == requestOrganization.UUID {
return "[equal-or-child]"
}
}
for _, childOrg := range requestOrganization.ChildOrgs {
if childOrg.UUID == currentUsersOrganization.UUID {
return "[parent]"
}
}
return "[unrelated]"
}
// 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(object interface{}, currentUser viewmodel.User) string {
switch obj := object.(type) {
case viewmodel.User:
if obj.ID == currentUser.ID {
return "[self]"
}
}
return "[other]"
}

View File

@@ -1,11 +0,0 @@
[request_definition]
r = role, obj, act
[policy_definition]
p = role, obj, act
[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
[matchers]
m = keymatch(r.role, p.role) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")

View File

@@ -1,6 +1,7 @@
package serverconfig
import (
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
@@ -9,7 +10,7 @@ import (
)
// SetMiddlewares attaches middlewares to server
func SetMiddlewares(server *echo.Echo, cfg *config.Config, log *logger.Logger, svc *service.Service) error {
func SetMiddlewares(server *echo.Echo, cfg *config.Config, log *logger.Logger, svc *service.Service, appsvc *applicationservice.Service) error {
setRecoverMiddleware(server)
setGZIPMiddleware(server)
setRequestIDMiddleware(server)
@@ -17,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, svc)
//setAuthorizationMiddleware(server, log, cfg, appsvc)
err := setJWTMiddleware(server, cfg)
if err != nil {

183
server/validation/tnc.go Normal file
View File

@@ -0,0 +1,183 @@
package validation
import (
"time"
"fmt"
"strconv"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
const (
tripTypeFromVisit = "From Visit"
tripTypeToVisit = "To Visit"
tripTypeFromVisitWillCall = "From Visit / Will Call"
tripTypeRoundTrip = "Round Trip"
tripTypeRountTripWillCall = "Round Trip / Will Call"
)
const (
loadingTime = 30 //in minutes
minimumLoadTime = 30 //in minutes
minimumPickupTime = 10 //in minutes
)
const (
hoursInDay = 24
hoursIn180Days = 24*180
time8Hours = 8
time10Minutes = 10
)
func ValidateRide(requestRide *viewmodel.RideRequest, user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
//Step #1 validation
if userID, err := strconv.Atoi(user.ID) ; err != nil || userID <= 0 {
result = append(result, errors.ValidationError{Field : "user_uuid", Message : "Step #1 - Choose a Member" })
}
if originID, err := strconv.Atoi(requestRide.Origin.ID) ; err != nil || originID <= 0 {
result = append (result, errors.ValidationError{Field : "origin.id", Message : "Step #1 - Choose a Pickup Address"})
}
if !requestRide.UserConsent {
result = append (result, errors.ValidationError{Field : "user_consent", Message : "Step #1 - Member must consent to Terms of Use"})
}
//Step #2 validation
if destinationID, err := strconv.Atoi(requestRide.Destination.ID) ; err!= nil || destinationID <= 0 {
result = append (result, errors.ValidationError{Field : "destination.id", Message : "Step #2 - Choose a Provider"})
}
//Step #3 validation
isVisitDayToday := requestRide.VisitDate.Day() == time.Now().Day() && requestRide.VisitDate.Month() == time.Now().Month() && requestRide.VisitDate.Year() == time.Now().Year()
before8Hours := time.Now().Add(-time.Hour*time8Hours)
if requestRide.VisitDate == nil {
result = append (result, errors.ValidationError{Field : "visit_date", Message : "Step #3 - Choose a Date for the Visit"})
}else{
dayBeforeToday := time.Now().Add(-time.Hour*hoursInDay)
if requestRide.VisitDate.Before(dayBeforeToday) {
result = append (result, errors.ValidationError{Field : "visit_date", Message : "Step #3 - Visit cannot occur more than one day before today"})
}
dayAfter180Days := time.Now().Add(time.Hour*hoursIn180Days)
if requestRide.VisitDate.After(dayAfter180Days) {
result = append (result, errors.ValidationError{Field : "visit_date", Message : "Step #3 - Visit cannot occur more than 180 days after today"})
}
if requestRide.VisitTime == nil {
result = append (result, errors.ValidationError{Field : "visit_time", Message : "Step #3 - Choose a Time for the Visit"})
}else{
if isVisitDayToday && requestRide.VisitTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "visit_time", Message : "Step #3 - Visit is more than 8 hours in the past"})
}
}
}
//Step #4 validation
if requestRide.TripType.Value == "" {
result = append (result, errors.ValidationError{Field : "trip_type.value", Message : "Step #4 - Choose a Trip Type"})
}
timeWithDurationAndLoadingTime := requestRide.VisitTime.Add(-time.Duration(requestRide.Duration)*time.Second).Add(-loadingTime*time.Minute)
after10Minutes := time.Now().Add(time.Minute*time10Minutes)
switch requestRide.TripType.Value {
case tripTypeToVisit:
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time before Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Visit cannot occour in the past"})
}
}
case tripTypeFromVisit :
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
timeWithMinimumPickupTime := time.Now().Add(minimumPickupTime*time.Minute)
if isVisitDayToday && requestRide.PickupTime.Before(timeWithMinimumPickupTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : fmt.Sprint("Step #4 - Time must be more than %d minutes from now",minimumPickupTime)})
}
if requestRide.PickupTime.Before(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time after Visit Time"})
}
timeWithMinimumLoadTime := time.Now().Add(minimumLoadTime*time.Minute)
if requestRide.PickupTime.Before(timeWithMinimumLoadTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than Minimum Load Time before Visit Time"})
}
}
case tripTypeFromVisitWillCall:
//no special validation for this case
case tripTypeRoundTrip:
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time before Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(after10Minutes) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must be at least 10 minutes from now"})
}
}
if requestRide.ReturnTime == nil {
result = append (result, errors.ValidationError{Field : "return_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if isVisitDayToday {
if requestRide.ReturnTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "return_time", Message : "Step #4 - Return Time is more than 8 hours after Visit Time"})
}
if requestRide.ReturnTime.Before(after10Minutes) {
result = append (result, errors.ValidationError{Field : "return_time", Message : "Step #4 - Return Time must be at least 10 minutes from now"})
}
}
}
case tripTypeRountTripWillCall:
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time after Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Visit cannot occur in the past "})
}
}
}
return result
}

67
server/validation/user.go Normal file
View File

@@ -0,0 +1,67 @@
package validation
import (
"strings"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
func characterIsUpperCase(character rune) bool {
return (character >= 65) && (character <= 90)
}
func characterIsLowerCase(character rune) bool {
return (character >= 97) && (character <= 122)
}
func characterIsNumber(character rune) bool {
return (character >= 48) && (character <= 57)
}
func ValidatePassword(user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
userOrganizationName := ""
if len(user.Organizations) > 0{
userOrganizationName = user.Organizations[0].Name
}
if (len(user.Pass) < 8) {
result = append(result, errors.ValidationError{Field : "password", Message : "Password must be at least 8 characters."})
}
if (strings.Contains(user.Pass, user.First)){
result = append(result, errors.ValidationError{Field : "password", Message : "Password cannot include your First Name."})
}
if (strings.Contains(user.Pass, user.Last)){
result = append(result, errors.ValidationError{Field : "password", Message : "Password cannot include your Last Name."})
}
if (strings.Contains(user.Pass, userOrganizationName)){
result = append(result, errors.ValidationError{Field : "password", Message : "Password cannot include your Organization Name."})
}
containsUpperCaseLetter := false;
containsLowerCaseLetter := false;
containsNumber := false;
for _, character := range user.Pass {
containsUpperCaseLetter = containsUpperCaseLetter || characterIsUpperCase(character)
containsLowerCaseLetter = containsLowerCaseLetter || characterIsLowerCase(character)
containsNumber = containsNumber || characterIsNumber(character)
}
if !containsUpperCaseLetter || !containsLowerCaseLetter || !containsNumber {
result = append(result, errors.ValidationError{Field : "password", Message : "Password must contain one of EACH :"})
result = append(result, errors.ValidationError{Field : "password-tab", Message : "an uppercase letter"})
result = append(result, errors.ValidationError{Field : "password-tab", Message : "a lowercase letter"})
result = append(result, errors.ValidationError{Field : "password-tab", Message : "a number"})
}
return result
}