diff --git a/Dockerfile.run b/Dockerfile.run index bd39e27..4c1fc6c 100644 --- a/Dockerfile.run +++ b/Dockerfile.run @@ -1,4 +1,10 @@ -FROM amazonlinux +FROM nginx:latest + +RUN apt-get update; apt-get install -y openssl + +RUN rm -rf /etc/nginx/conf.d/*; +COPY ./dist/default.conf /etc/nginx/conf.d/ +COPY ./dist/nginx.conf /etc/nginx/ # Sets the arguments. ARG BIN_NAME=nemt-portal-api @@ -7,12 +13,14 @@ ARG WORKDIR=/opt/app/ # Creates the necessary directories. RUN mkdir -p /opt/app/docs +RUN mkdir -p /opt/app/certs RUN mkdir -p /opt/app/static RUN mkdir -p /var/log/bsbsi # Copies the files to the container. COPY ./dist/${BIN_NAME} /opt/app/${BIN_NAME} ADD ./dist/docs/ /opt/app/docs/ +ADD ./dist/certs/ /opt/app/certs/ ADD ./dist/static/ /opt/app/static/ ADD ./dist/config.toml /opt/app/config.toml ADD ./dist/authorization_model.conf /opt/app/authorization_model.conf @@ -20,5 +28,8 @@ ADD ./dist/authorization_policy.csv /opt/app/authorization_policy.csv # Sets and executes the app. WORKDIR /opt/app -EXPOSE 5000 -CMD ./nemt-portal-api + +EXPOSE 80 +EXPOSE 443 + +CMD nginx & ./nemt-portal-api diff --git a/Makefile b/Makefile index 6811a76..db60b55 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ RUN_CONTAINER_NAME = ${APP_NAME}-run ############################# set-loc: - $(eval DEPLOY_ENV := loc) + $(eval DEPLOY_ENV := dev) set-dev: $(eval DEPLOY_ENV := dev) @@ -49,6 +49,7 @@ build: clean create-build-container # Creates the necessary folders. mkdir -p dist/static mkdir -p dist/docs + mkdir -p dist/certs # Builds inside the container. docker run \ @@ -66,6 +67,9 @@ build: clean create-build-container # Copies the docs and the static files to the correct folder. cp -R static/* ./dist/static/ cp -R docs/swagger/ ./dist/docs/ + cp -R certs/${DEPLOY_ENV}/ ./dist/certs/ + cp default.${DEPLOY_ENV}.conf ./dist/default.conf + cp nginx.conf ./dist/nginx.conf cp config.${DEPLOY_ENV}.toml ./dist/config.toml cp authorization_model.conf ./dist/authorization_model.conf cp authorization_policy.csv ./dist/authorization_policy.csv diff --git a/application/applicationservice/organization.go b/application/applicationservice/organization.go index e297d7f..7b5859a 100644 --- a/application/applicationservice/organization.go +++ b/application/applicationservice/organization.go @@ -48,6 +48,16 @@ func (s *organizationService) GetByType(organizationTypeKey string, user viewmod 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 { + fmt.Println("Error to get the Organization data by UUID", err) + return viewmodel.Organization{}, err + } + return s.mapEntity.Organization.ToOrganizationModel(result), nil +} + +func (s *organizationService) GetByTypeAndReferenceID(typeKey string, referenceID int64, user viewmodel.User) (viewmodel.Organization, error) { + userEntity := s.mapEntity.User.ToUserEntity(user) + result, err := s.svc.Organization.GetByTypeAndReferenceID(typeKey, referenceID, userEntity) if err != nil { return viewmodel.Organization{}, err } @@ -185,17 +195,17 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio var provider npdmodel.ProviderResponse bProvider, err := ffjson.Marshal(organization.Reference) if err != nil { - fmt.Println("Error to marshal provider") + fmt.Println("Error to marshal provider", err) return viewmodel.Organization{}, nil } if err := ffjson.Unmarshal(bProvider, &provider); err != nil { - fmt.Println("Error to convert provider") + fmt.Println("Error to convert provider", err) return viewmodel.Organization{}, nil } eProviders, err := s.svc.Provider.Save(s.mapEntity.Provider.ToProviderEntitySlice([]npdmodel.ProviderResponse{provider}), enUser) if err != nil { - fmt.Println("Error to save provider") + fmt.Println("Error to save provider", err) return viewmodel.Organization{}, nil } respProvider := eProviders[0] @@ -203,17 +213,19 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio lat, _ := strconv.ParseFloat(provider.Latitude, 64) long, _ := strconv.ParseFloat(provider.Longitude, 64) - address := entity.OrganizationAddress{ - InternalID: provider.MukID, - Name: "Main Address", - Address: fmt.Sprintf("%s %s - %s, %s (%s)", provider.StreetName1, provider.StreetName2, provider.CityName, provider.State, provider.ZipCode), - Latitude: lat, - Longitude: long, - CreatedUser: enOrg.Author, - UpdatedUser: enOrg.LastEditor, + if lat != 0 && long != 0 && len(provider.StreetName1) > 0 { + address := entity.OrganizationAddress{ + InternalID: provider.MukID, + Name: "Main Address", + Address: fmt.Sprintf("%s %s - %s, %s (%s)", provider.StreetName1, provider.StreetName2, provider.CityName, provider.State, provider.ZipCode), + Latitude: lat, + Longitude: long, + CreatedUser: enOrg.Author, + UpdatedUser: enOrg.LastEditor, + } + enOrg.Addresses = append(enOrg.Addresses, address) } - enOrg.Addresses = append(enOrg.Addresses, address) - fmt.Println("Phone Number: ", provider.PhoneNumber) + if provider.PhoneNumber != "" { formattedPhone := "+1" + strings.Replace(provider.PhoneNumber, "-", "", -1) contact := entity.OrganizationContact{ @@ -232,6 +244,7 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio enOrg, err = s.svc.Organization.AddOrganization(enOrg, enUser) if err != nil { + fmt.Println("Error to save organization on DB", err) return viewmodel.Organization{}, nil } diff --git a/application/applicationservice/provider.go b/application/applicationservice/provider.go index 5501226..9823d59 100644 --- a/application/applicationservice/provider.go +++ b/application/applicationservice/provider.go @@ -58,3 +58,13 @@ func (s *providerService) GetByUUID(providerUUID string, user viewmodel.User) (v return s.mapEntity.Provider.ToProviderRespModel(provider), nil } + +func (s *providerService) GetByNPI(NPI string, user viewmodel.User) (viewmodel.ProviderResp, error) { + eUser := s.mapEntity.User.ToUserEntity(user) + provider, err := s.svc.Provider.GetByNPI(NPI, eUser) + if err != nil { + return viewmodel.ProviderResp{}, err + } + + return s.mapEntity.Provider.ToProviderRespModel(provider), nil +} diff --git a/application/entitymapping/provider.go b/application/entitymapping/provider.go index 059b9ba..cdf037a 100644 --- a/application/entitymapping/provider.go +++ b/application/entitymapping/provider.go @@ -37,6 +37,7 @@ func (mapping *providerMapping) ToProviderRespEntity(item viewmodel.ProviderResp LastName: item.LastName, Title: item.Title, Distance: item.Distance, + Organization: mapping.mapper.Organization.ToOrganizationEntity(item.Organization), } } @@ -68,6 +69,7 @@ func (mapping *providerMapping) ToProviderRespModel(item entity.Provider) viewmo Keys: mapping.ToProviderKeyModelSlice(item.Keys), Address: mapping.ToProviderRespAddressModel(item.Address), Distance: item.Distance, + Organization: mapping.mapper.Organization.ToOrganizationModel(item.Organization), } } diff --git a/application/viewmodel/provider.go b/application/viewmodel/provider.go index 1fd4d2d..d4c4b78 100644 --- a/application/viewmodel/provider.go +++ b/application/viewmodel/provider.go @@ -16,6 +16,7 @@ type ProviderResp struct { Keys []ProviderKey `json:"keys,omitempty"` Address ProviderAddress `json:"address,omitempty"` Distance float64 `json:"distance,omitempty"` + Organization Organization `json:"organization,omitempty"` } type ProviderKey struct { diff --git a/application/viewmodel/user.go b/application/viewmodel/user.go index b03e1af..4d4682d 100644 --- a/application/viewmodel/user.go +++ b/application/viewmodel/user.go @@ -24,6 +24,8 @@ type User struct { Profiles []Profile `json:"profiles,omitempty"` Types []OrganizationType `json:"types,omitempty"` Organizations []Organization `json:"organizations,omitempty"` + Provider *ProviderResp `json:"provider,omitempty"` + Consent bool `json:"consent,omitempty"` } type Contact struct { diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 434bf54..89fe208 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -14,11 +14,13 @@ pipelines: - rm -rf vendor/ - glide install -force - go build -o nemt-portal-api - - mkdir -p dist/{static,docs} + - mkdir -p dist/{static,docs,certs} - cp nemt-portal-api ./dist/ - cp -R static/* ./dist/static/ - cp -R docs/swagger/ ./dist/docs/ - cp config.prd.toml ./dist/config.toml + - cp default.prd.conf ./dist/default.conf + - cp nginx.conf ./dist/nginx.conf - 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 . @@ -43,11 +45,13 @@ pipelines: - rm -rf vendor/ - glide install -force - go build -o nemt-portal-api - - mkdir -p dist/{static,docs} + - mkdir -p dist/{static,docs,certs} - cp nemt-portal-api ./dist/ - cp -R static/* ./dist/static/ - cp -R docs/swagger/ ./dist/docs/ - cp config.stg.toml ./dist/config.toml + - cp default.stg.conf ./dist/default.conf + - cp nginx.conf ./dist/nginx.conf - 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 . diff --git a/certs/dev/private.key b/certs/dev/private.key new file mode 100644 index 0000000..1c321b8 --- /dev/null +++ b/certs/dev/private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0VyKNSM/a/CzE +16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/ +ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK +qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p +oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK +uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts +l5njh/MhAgMBAAECggEAHSE+CYhLWtoE+T7FGu1YjBvwNxc5TlSEN0qVkpixE+k9 +Ndl+r+txjEaq9xRPIJE48LWVynC5DqFhx/lC7K9n6JIgsdz9ijlQuHau2W3adAmo +pfReHscVn5ofJ0/X3j2jSMP3Q3fxJmGwQza3pz/dH8kn+7SkMuXqABYm1peUeXCr +BOIl0/C9UpuIlDrK0TL4VVC3gR/sXSTJV7CV12o6mqWMc5eRjYdz5Tn3W6yC5Cir +GrI3zHEDnhUM8xMtLHTxJ41Sim8To1NSuSrUk9Zd/sEQfT1daqYM3jPnfCePgzOH +b6zDzKwIDqb8T0LOOnn9uDjgz3TkRzkfEhw4xJE36QKBgQDmeR7mkENRtU5+DErI +vKWv1+SfUklfzrhgr/MqmNzvBmgqV9shVWPPg4TtERL+kiPvTFVWmAvUcC81h0Bx +ztGg49067reZq0bEYSCNaCvDvNGf9i2wirWpdOxofLI7AONcWQMm7pIwA+/ph0tG +liW6Q4Ppl4/qQfiHQ/fyqOBzXwKBgQDIUIpbUFslaEhPwAPlPAgulzu0uZxG99TG +Qxl5JKQapv5WlJ1HzU6EtMrMS4p+8Hkq2x6SRQnteZTBCvgi61eHauw7MfswhNFi +elZW7AHzydoNM+mJV8pWIVhfNtnQkVsmu0Id/dXo7U/6qWMK1yEbICAqsBkZIdfM +6EQTWxupfwKBgDK168qna2iLEB5D7iCFAZ/TTQaRQHvILGF51XNF9zbQnhLTCfAn +rbJ3KcRPwXIqDaYVkaFgCxpPJNQOUmu4Kf/Qo1jYNaWmPgfvpw32IcsLvMQJkrwJ +iTcj9vB2n3DEHUKwgzUJwTi3ZQ5pKnL5jouRV3EKXCwbH+gDWIcYCWrZAoGBALs6 +BEebEMYi9UuNFlcBSEh71DN0NOxkIfz5pGqFY9kBcsHsACGndJc3AEH47Ub+btIu +oiFm5AORWwcfwJOq0lHhD1G4wqYzzh00aVSvHJgHd4ZVmhdj9duRKS89blKyObc2 +2XJ82Z3viYypG8h7ERdwbIBZveuupSyBf3dz9aPzAoGBAKSN9nskGkSMfPdPlohA +BAmZGciAbob0un6db34ahExKEfkjhPA/C1AIs6LZz9QNy/OTUlXzVSx4axHMeqxo +HAb5yVRkj2VDBnWl//BEAxXKj+r1KOqESdqaKeQcYzXzAMQ36DJia7DOiej7HNSx +Y3ydXe8hO8lutgiU5rsBNVLM +-----END PRIVATE KEY----- diff --git a/certs/dev/ssl_certificate.cer b/certs/dev/ssl_certificate.cer new file mode 100755 index 0000000..ce970c5 --- /dev/null +++ b/certs/dev/ssl_certificate.cer @@ -0,0 +1,88 @@ +-----BEGIN CERTIFICATE----- +MIIGvjCCBaagAwIBAgIQC3nVkJVbuOa1WFfJQc+IMDANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E +aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN +MjAwNTIwMTIwMDAwWjCBhTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz +MRAwDgYDVQQHEwdDaGljYWdvMS8wLQYDVQQKEyZCbHVlIENyb3NzIGFuZCBCbHVl +IFNoaWVsZCBBc3NvY2lhdGlvbjEgMB4GA1UEAwwXKi5kZXYuYmNic2luc3RpdHV0 +ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0VyKNSM/a/CzE +16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/ +ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK +qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p +oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK +uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts +l5njh/MhAgMBAAGjggNfMIIDWzAfBgNVHSMEGDAWgBQPgGEcgjFh1S8o541GOLQs +4cbZ4jAdBgNVHQ4EFgQUOlOHeILArFmCfRgy4zob9YD7ZdMwIgYDVR0RBBswGYIX +Ki5kZXYuYmNic2luc3RpdHV0ZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8v +Y3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDov +L2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3 +BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu +Y29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho +dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl +cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw +CQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHYApLkJkLQYWBSH +uxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFjhC1vrQAABAMARzBFAiEAjDaMTkKz +JL1M7AloHKciZwIm9PhTpRJhtDedIoV2l5oCIEyT5kke4/OXoBE9guw1TPCKwuS5 +klDOeG+rlHiTHZvbAHcAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMA +AAFjhC1xQwAABAMASDBGAiEAzo+0zJUoqV0X0IqzaZ+9boXzWvIzZCR/OqT1qcAe +a3QCIQCdMYaIEYnhnsaOXPMsyShv+ry41lQ9UvUZ3EAvhjgCeQB3ALvZ37wfinG1 +k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABY4QtcKQAAAQDAEgwRgIhAJ4XGViz +vfkGsR3/UWlVZhX9t5rLAlyhW/t1K17vkNjJAiEAhzQycmcTPIVb1Ul1Ug5UgWQ4 +eD2rp/4raewQVACs26QwDQYJKoZIhvcNAQELBQADggEBADjGzhdcyCYxemKuWoP9 +Umd0jnS6gHPivwgpy2Ra4SSsFCkucHX8dRMi63MRghiKi4FPj9LsFoLpdHacfi+6 +Q1lX3fZ6Mv2ZpNjMtBe/g6SATLsFxUQl+UP5bMShEXHsQduinAvSW3m8UpQZ2UxG +7L/XmNfeW8x213Mi4G2DNUJKDMjO28bO/GbCNB85HGfhnaDxj7OsQYllbE5oEDXN +Wkx1QZFrvqE3/2zoOa1ga36xymRXt0Sn3OSFr/ukZh3MCWAL5fuT4zjnSjybHDqT +2qdmV08ECgXwVNUMtbTFq9kenBN0xTrfPFR0Y0IPzqXQP5kTPktgrrYiAf+S875J +IVo= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg +U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 +nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd +KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f +/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX +kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 +/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C +AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 +Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 +oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD +QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh +xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB +CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl +5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA +8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC +2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit +c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 +j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/certs/prd/private.key b/certs/prd/private.key new file mode 100644 index 0000000..6982877 --- /dev/null +++ b/certs/prd/private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCs4SiZVk5EI7BQ +c43SAmeAriEKoxLb0d32fCXltF/hbFouMDVA3h5TacTTVCH9JrKIykV2hbJXd8DM +UUOO0gAJ6DOjvmHeDrUquT3+eXqX71QLGVKSVgcDBy+IjdSlNj1RDdxT1gBKdWYj +OHFHsFZgGZc1OysXiww9mUhx+JhFSq5EOo7jVM6/uOfA7dXazk6sCxiT+SuEN9Hh +uPZdlHUnf+S/BPDI1PK90AG6Wj8U+nroWZZ8ZMGyh10FBLnmdZ30iO7Ll73leqR4 +7rF9Ox4w4DDwWYaaiNWX3CvneYUdmTCUPJC5G82AYlMVZ9dVloIOYPMz1XwH9gs1 +vzwCAH2lAgMBAAECggEAYOUh2C+jVlWacL0Tc+2dDWaLZmbYHxSVj50tsH1UcAhG +0zR55I2Z+a6Cft/c3QJfdoPIQxHUT2nzSZESiG3zT5oxt0jxmYAs0nFY6dQ0fgvJ +0x6yRQqqi2vvnF3CHYc0/sUCBIshRppeUMdF1qRjBSHSuicbk+p/Rdcv35Ex50Nz +rskvhtmPU0b7B/tVyvp+pLD+5uC42epW4Eh7R2er7WWp6m8e6mh9gjn1TYLdbprV +p/SNTJnGp4dUNO851wgsqeJcokGA6wdOb3UxIcEbW7EvX5ybozVZfUk3vP5toTmS +bNCm0UlwELE7+zX21ka7Wrfc5vGLYsdRE0Pa3V3X0QKBgQDj0E/sQ8lApJzlKf8T +9GEcuf7NM1f9DHeUmj2N8v055uAqUcE3h7PdUWSrJCbotowrJQ3jGTJd1uFrQVI4 +4FEgestZDYaJ/8Bq7xt8cuebfTHzYj/o3ace4uAUKKfpxJz8+WzIK42mrcMDC221 +HMmV5A4IFaM6bsvCia/LXJ91iwKBgQDCROGH8bFeriXOk8QXoq6Vq1paxEtukWBH +dtKcsAqJsUtKsVWclei+XucBrN0lrzDBii/ewcq/EH2GEknGwg0ooTG0mUD9nbCu +L9a3NUxBLxdKLZaDVsl7sxkbL9HIn4yGvznqfo4rjA4X8jY5OB7X6oR8yWdKhFJf +dT8Yi1YfjwKBgQCtSLSiaGVa0FuvTKSDzy1XJnsUJuvUxXjoBfKwWJYZRu5YAlvQ +G17LB7BlJVibRs+Tudm4VmAjVOGeLc+XB7lt1Tl8AXfG3EzGih4EKXrWoQIvuRoX +zRHjwnrjmpEulak8G5WNJOPYVu+xDy5hxwXnB9NMfvjr538B+K1JKKj6RQKBgHmI +K+sm2YZYvdAhAvCiVkPNocXcvS/bhHbQr+tT+hOvtWFx1RQTeDn4Ft4mbWbQ1ViO +gWoCpDqpL027jSnpZeAAD59irJS8nLYruVB96ElzE0fVgy6BEaTwIwmt/bhbj8cQ +REQdjgVSJdL3NNLQ+AKtdNq4CIVGiF2tdJ5/NI6jAoGBAJnsp+bti4F+LrQVPMNb +Ptyxw1eOfNkjqyoAJQXJ6HBN3uDVes/peR+9k4ATsZRMUyo+P07ggAo397+i8PY2 +FeAwbzACVIb0TVNki8dP/U30e7087DgyxzMK9/ggeCuzcHczEekkioTVQubfd5vJ +4N4yQGflInls/OMIodPBir1j +-----END PRIVATE KEY----- diff --git a/certs/prd/ssl_certificate.cer b/certs/prd/ssl_certificate.cer new file mode 100755 index 0000000..ce970c5 --- /dev/null +++ b/certs/prd/ssl_certificate.cer @@ -0,0 +1,88 @@ +-----BEGIN CERTIFICATE----- +MIIGvjCCBaagAwIBAgIQC3nVkJVbuOa1WFfJQc+IMDANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E +aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN +MjAwNTIwMTIwMDAwWjCBhTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz +MRAwDgYDVQQHEwdDaGljYWdvMS8wLQYDVQQKEyZCbHVlIENyb3NzIGFuZCBCbHVl +IFNoaWVsZCBBc3NvY2lhdGlvbjEgMB4GA1UEAwwXKi5kZXYuYmNic2luc3RpdHV0 +ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0VyKNSM/a/CzE +16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/ +ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK +qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p +oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK +uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts +l5njh/MhAgMBAAGjggNfMIIDWzAfBgNVHSMEGDAWgBQPgGEcgjFh1S8o541GOLQs +4cbZ4jAdBgNVHQ4EFgQUOlOHeILArFmCfRgy4zob9YD7ZdMwIgYDVR0RBBswGYIX +Ki5kZXYuYmNic2luc3RpdHV0ZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8v +Y3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDov +L2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3 +BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu +Y29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho +dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl +cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw +CQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHYApLkJkLQYWBSH +uxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFjhC1vrQAABAMARzBFAiEAjDaMTkKz +JL1M7AloHKciZwIm9PhTpRJhtDedIoV2l5oCIEyT5kke4/OXoBE9guw1TPCKwuS5 +klDOeG+rlHiTHZvbAHcAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMA +AAFjhC1xQwAABAMASDBGAiEAzo+0zJUoqV0X0IqzaZ+9boXzWvIzZCR/OqT1qcAe +a3QCIQCdMYaIEYnhnsaOXPMsyShv+ry41lQ9UvUZ3EAvhjgCeQB3ALvZ37wfinG1 +k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABY4QtcKQAAAQDAEgwRgIhAJ4XGViz +vfkGsR3/UWlVZhX9t5rLAlyhW/t1K17vkNjJAiEAhzQycmcTPIVb1Ul1Ug5UgWQ4 +eD2rp/4raewQVACs26QwDQYJKoZIhvcNAQELBQADggEBADjGzhdcyCYxemKuWoP9 +Umd0jnS6gHPivwgpy2Ra4SSsFCkucHX8dRMi63MRghiKi4FPj9LsFoLpdHacfi+6 +Q1lX3fZ6Mv2ZpNjMtBe/g6SATLsFxUQl+UP5bMShEXHsQduinAvSW3m8UpQZ2UxG +7L/XmNfeW8x213Mi4G2DNUJKDMjO28bO/GbCNB85HGfhnaDxj7OsQYllbE5oEDXN +Wkx1QZFrvqE3/2zoOa1ga36xymRXt0Sn3OSFr/ukZh3MCWAL5fuT4zjnSjybHDqT +2qdmV08ECgXwVNUMtbTFq9kenBN0xTrfPFR0Y0IPzqXQP5kTPktgrrYiAf+S875J +IVo= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg +U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 +nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd +KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f +/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX +kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 +/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C +AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 +Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 +oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD +QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh +xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB +CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl +5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA +8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC +2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit +c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 +j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/certs/stg/private.key b/certs/stg/private.key new file mode 100644 index 0000000..1c321b8 --- /dev/null +++ b/certs/stg/private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0VyKNSM/a/CzE +16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/ +ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK +qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p +oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK +uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts +l5njh/MhAgMBAAECggEAHSE+CYhLWtoE+T7FGu1YjBvwNxc5TlSEN0qVkpixE+k9 +Ndl+r+txjEaq9xRPIJE48LWVynC5DqFhx/lC7K9n6JIgsdz9ijlQuHau2W3adAmo +pfReHscVn5ofJ0/X3j2jSMP3Q3fxJmGwQza3pz/dH8kn+7SkMuXqABYm1peUeXCr +BOIl0/C9UpuIlDrK0TL4VVC3gR/sXSTJV7CV12o6mqWMc5eRjYdz5Tn3W6yC5Cir +GrI3zHEDnhUM8xMtLHTxJ41Sim8To1NSuSrUk9Zd/sEQfT1daqYM3jPnfCePgzOH +b6zDzKwIDqb8T0LOOnn9uDjgz3TkRzkfEhw4xJE36QKBgQDmeR7mkENRtU5+DErI +vKWv1+SfUklfzrhgr/MqmNzvBmgqV9shVWPPg4TtERL+kiPvTFVWmAvUcC81h0Bx +ztGg49067reZq0bEYSCNaCvDvNGf9i2wirWpdOxofLI7AONcWQMm7pIwA+/ph0tG +liW6Q4Ppl4/qQfiHQ/fyqOBzXwKBgQDIUIpbUFslaEhPwAPlPAgulzu0uZxG99TG +Qxl5JKQapv5WlJ1HzU6EtMrMS4p+8Hkq2x6SRQnteZTBCvgi61eHauw7MfswhNFi +elZW7AHzydoNM+mJV8pWIVhfNtnQkVsmu0Id/dXo7U/6qWMK1yEbICAqsBkZIdfM +6EQTWxupfwKBgDK168qna2iLEB5D7iCFAZ/TTQaRQHvILGF51XNF9zbQnhLTCfAn +rbJ3KcRPwXIqDaYVkaFgCxpPJNQOUmu4Kf/Qo1jYNaWmPgfvpw32IcsLvMQJkrwJ +iTcj9vB2n3DEHUKwgzUJwTi3ZQ5pKnL5jouRV3EKXCwbH+gDWIcYCWrZAoGBALs6 +BEebEMYi9UuNFlcBSEh71DN0NOxkIfz5pGqFY9kBcsHsACGndJc3AEH47Ub+btIu +oiFm5AORWwcfwJOq0lHhD1G4wqYzzh00aVSvHJgHd4ZVmhdj9duRKS89blKyObc2 +2XJ82Z3viYypG8h7ERdwbIBZveuupSyBf3dz9aPzAoGBAKSN9nskGkSMfPdPlohA +BAmZGciAbob0un6db34ahExKEfkjhPA/C1AIs6LZz9QNy/OTUlXzVSx4axHMeqxo +HAb5yVRkj2VDBnWl//BEAxXKj+r1KOqESdqaKeQcYzXzAMQ36DJia7DOiej7HNSx +Y3ydXe8hO8lutgiU5rsBNVLM +-----END PRIVATE KEY----- diff --git a/certs/stg/ssl_certificate.cer b/certs/stg/ssl_certificate.cer new file mode 100755 index 0000000..ce970c5 --- /dev/null +++ b/certs/stg/ssl_certificate.cer @@ -0,0 +1,88 @@ +-----BEGIN CERTIFICATE----- +MIIGvjCCBaagAwIBAgIQC3nVkJVbuOa1WFfJQc+IMDANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E +aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN +MjAwNTIwMTIwMDAwWjCBhTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz +MRAwDgYDVQQHEwdDaGljYWdvMS8wLQYDVQQKEyZCbHVlIENyb3NzIGFuZCBCbHVl +IFNoaWVsZCBBc3NvY2lhdGlvbjEgMB4GA1UEAwwXKi5kZXYuYmNic2luc3RpdHV0 +ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0VyKNSM/a/CzE +16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/ +ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK +qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p +oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK +uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts +l5njh/MhAgMBAAGjggNfMIIDWzAfBgNVHSMEGDAWgBQPgGEcgjFh1S8o541GOLQs +4cbZ4jAdBgNVHQ4EFgQUOlOHeILArFmCfRgy4zob9YD7ZdMwIgYDVR0RBBswGYIX +Ki5kZXYuYmNic2luc3RpdHV0ZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8v +Y3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDov +L2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3 +BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu +Y29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho +dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl +cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw +CQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHYApLkJkLQYWBSH +uxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFjhC1vrQAABAMARzBFAiEAjDaMTkKz +JL1M7AloHKciZwIm9PhTpRJhtDedIoV2l5oCIEyT5kke4/OXoBE9guw1TPCKwuS5 +klDOeG+rlHiTHZvbAHcAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMA +AAFjhC1xQwAABAMASDBGAiEAzo+0zJUoqV0X0IqzaZ+9boXzWvIzZCR/OqT1qcAe +a3QCIQCdMYaIEYnhnsaOXPMsyShv+ry41lQ9UvUZ3EAvhjgCeQB3ALvZ37wfinG1 +k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABY4QtcKQAAAQDAEgwRgIhAJ4XGViz +vfkGsR3/UWlVZhX9t5rLAlyhW/t1K17vkNjJAiEAhzQycmcTPIVb1Ul1Ug5UgWQ4 +eD2rp/4raewQVACs26QwDQYJKoZIhvcNAQELBQADggEBADjGzhdcyCYxemKuWoP9 +Umd0jnS6gHPivwgpy2Ra4SSsFCkucHX8dRMi63MRghiKi4FPj9LsFoLpdHacfi+6 +Q1lX3fZ6Mv2ZpNjMtBe/g6SATLsFxUQl+UP5bMShEXHsQduinAvSW3m8UpQZ2UxG +7L/XmNfeW8x213Mi4G2DNUJKDMjO28bO/GbCNB85HGfhnaDxj7OsQYllbE5oEDXN +Wkx1QZFrvqE3/2zoOa1ga36xymRXt0Sn3OSFr/ukZh3MCWAL5fuT4zjnSjybHDqT +2qdmV08ECgXwVNUMtbTFq9kenBN0xTrfPFR0Y0IPzqXQP5kTPktgrrYiAf+S875J +IVo= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg +U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 +nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd +KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f +/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX +kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 +/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C +AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 +Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 +oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD +QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh +xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB +CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl +5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA +8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC +2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit +c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 +j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/data/datamysql/organization.go b/data/datamysql/organization.go index 3673bb4..a8345f9 100644 --- a/data/datamysql/organization.go +++ b/data/datamysql/organization.go @@ -214,7 +214,11 @@ func (c *organizationRepo) parseEntity(row scanner) (retVal entity.Organization, err = row.Scan( &retVal.ID, &retVal.UUID, &retVal.Type.ID, &retVal.Type.Name, &retVal.Type.Key, &retVal.Name, &retVal.Description, &retVal.ReferenceID, &retVal.ParentID, &retVal.Main, &retVal.Created, &retVal.Updated, &retVal.Active, &retVal.Suspended, &retVal.Blocked, &retVal.Author.ID, &retVal.Author.UUID, &retVal.Author.Name, &retVal.LastEditor.ID, &retVal.LastEditor.UUID, &retVal.LastEditor.Name) - return retVal, errors.Wrap(err) + if err == sql.ErrNoRows { + return retVal, nil + } else { + return retVal, errors.Wrap(err) + } } // parseSet parses a result set result to an entity array @@ -352,6 +356,17 @@ func (c *organizationRepo) GetByID(organizationID int64, user entity.User) (enti return c.parseEntity(c.conn.QueryRow(query, organizationID)) } +func (c *organizationRepo) GetByTypeAndReferenceID(typeKey string, referenceID 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 b.organization_type_key = ? AND a.organization_reference_id = ? " + where + + return c.parseEntity(c.conn.QueryRow(query, typeKey, referenceID)) +} + func (c *organizationRepo) GetChildsByID(organizationID int64, user entity.User) ([]entity.Organization, error) { query, where, err := c.getProfileQuery(user) if err != nil { diff --git a/data/datamysql/provider.go b/data/datamysql/provider.go index 2aa2870..316835e 100644 --- a/data/datamysql/provider.go +++ b/data/datamysql/provider.go @@ -72,44 +72,44 @@ func (c *providerRepo) getSelectQueryBaseKey() string { func (c *providerRepo) getSelectQueryBase() string { return `SELECT DISTINCT - a.provider_id, - a.provider_uuid, - a.provider_internal_id, - a.provider_internal_id_suffix, - a.provider_muk_id, - a.organization_name, - a.gender, - a.accept_new_patients, - a.provider_name, - a.first_name, - a.last_name, - a.middle_name, - a.provider_title, - a.street_name1, - a.street_name2, - a.city_name, - a.state, - a.zipcode, - a.country, - a.latitude, - a.longitude, - a.phone_number, - a.create_at, - a.update_at, - a.active, - a.enabled, - a.created_user, - (3959 * acos ( - cos ( radians(?) ) - * cos( radians( a.latitude ) ) - * cos( radians( a.longitude ) - radians(?) ) - + sin ( radians(?) ) - * sin( radians( a.latitude ) ) - )) AS distance_in_miles - FROM - tab_provider a - INNER JOIN tab_provider_key b - ON a.provider_id = b.provider_id ` + a.provider_id, + a.provider_uuid, + a.provider_internal_id, + IFNULL(a.provider_internal_id_suffix, '') provider_internal_id_suffix, + IFNULL(a.provider_muk_id, '') provider_muk_id, + IFNULL(a.organization_name, '') organization_name, + IFNULL(a.gender, '') gender, + IFNULL(a.accept_new_patients, '') accept_new_patients, + IFNULL(a.provider_name, '') provider_name, + IFNULL(a.first_name, '') first_name, + IFNULL(a.last_name, '') last_name, + IFNULL(a.middle_name, '') middle_name, + IFNULL(a.provider_title, '') provider_title, + IFNULL(a.street_name1, '') street_name1, + IFNULL(a.street_name2, '') street_name2, + IFNULL(a.city_name, '') city_name, + IFNULL(a.state, '') state, + IFNULL(a.zipcode, '') zipcode, + IFNULL(a.country, '') country, + IFNULL(a.latitude, 0) latitude, + IFNULL(a.longitude, 0) longitude, + IFNULL(a.phone_number, '') phone_number, + a.create_at, + a.update_at, + a.active, + a.enabled, + a.created_user, + (3959 * acos ( + cos ( radians(?) ) + * cos( radians( IFNULL(a.latitude, 0) ) ) + * cos( radians( IFNULL(a.longitude, 0) ) - radians(?) ) + + sin ( radians(?) ) + * sin( radians( IFNULL(a.latitude, 0) ) ) + )) AS distance_in_miles + FROM + tab_provider a + INNER JOIN tab_provider_key b + ON a.provider_id = b.provider_id ` } func (c *providerRepo) GetAll(user entity.User) ([]entity.Provider, error) { @@ -159,6 +159,20 @@ func (c *providerRepo) GetByMukID(mukID string, user entity.User) (entity.Provid return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, mukID)) } +func (c *providerRepo) GetByNPI(NPI string, user entity.User) (entity.Provider, error) { + lat := 41.886406 + long := -87.624225 + + query, where, err := c.getProfileQuery(user) + if err != nil { + return entity.Provider{}, err + } + + query = c.getSelectQueryBase() + query + " WHERE a.provider_internal_id = ? " + where + + return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, NPI)) +} + func (c *providerRepo) Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user entity.User) ([]entity.Provider, error) { filter := " WHERE 1 = 1 " params := make([]interface{}, 0) @@ -307,7 +321,11 @@ func (c *providerRepo) parseEntity(row scanner) (retVal entity.Provider, err err err = row.Scan( &retVal.ProviderID, &retVal.ProviderUUID, &retVal.InternalID, &retVal.InternalSuffixID, &retVal.MukID, &retVal.OrganizatioName, &retVal.Gender, &retVal.AcceptNewPatients, &retVal.Name, &retVal.FirstName, &retVal.LastName, &retVal.MiddleName, &retVal.Title, &retVal.Address.StreetAddress1, &retVal.Address.StreetAddress2, &retVal.Address.CityName, &retVal.Address.State, &retVal.Address.ZipCode, &retVal.Address.Country, &retVal.Address.Latitude, &retVal.Address.Longitude, &retVal.Address.PhoneNumber, &retVal.CreateDate, &retVal.UpdateDate, &retVal.Active, &retVal.Enabled, &retVal.CreatedUser.ID, &retVal.Distance) - return retVal, errors.Wrap(err) + if err == sql.ErrNoRows { + return retVal, nil + } else { + return retVal, errors.Wrap(err) + } } func (c *providerRepo) Save(providers []entity.ProviderResponse, user entity.User) ([]entity.Provider, error) { diff --git a/default.dev.conf b/default.dev.conf new file mode 100644 index 0000000..3fc630f --- /dev/null +++ b/default.dev.conf @@ -0,0 +1,36 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + server_name portal-api.dev.bcbinstitute.com; + + location / { + proxy_pass http://127.0.0.1:5100; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} + +server { + listen 443; + ssl on; + ssl_certificate /opt/app/certs/ssl_certificate.cer; + ssl_certificate_key /opt/app/certs/private.key; + server_name portal-api.dev.bcbsinstitute.com; + server_tokens off; + + location / { + proxy_pass http://127.0.0.1:5100; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} \ No newline at end of file diff --git a/default.prd.conf b/default.prd.conf new file mode 100644 index 0000000..8470fc3 --- /dev/null +++ b/default.prd.conf @@ -0,0 +1,36 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + server_name portal-api.bcbinstitute.com; + + location / { + proxy_pass http://127.0.0.1:5100; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} + +server { + listen 443; + ssl on; + ssl_certificate /opt/app/certs/ssl_certificate.cer; + ssl_certificate_key /opt/app/certs/private.key; + server_name portal-api.bcbsinstitute.com; + server_tokens off; + + location / { + proxy_pass http://127.0.0.1:5100; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} \ No newline at end of file diff --git a/default.stg.conf b/default.stg.conf new file mode 100644 index 0000000..3fc630f --- /dev/null +++ b/default.stg.conf @@ -0,0 +1,36 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + server_name portal-api.dev.bcbinstitute.com; + + location / { + proxy_pass http://127.0.0.1:5100; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} + +server { + listen 443; + ssl on; + ssl_certificate /opt/app/certs/ssl_certificate.cer; + ssl_certificate_key /opt/app/certs/private.key; + server_name portal-api.dev.bcbsinstitute.com; + server_tokens off; + + location / { + proxy_pass http://127.0.0.1:5100; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} \ No newline at end of file diff --git a/domain/contract/repo.go b/domain/contract/repo.go index 06dca1d..5c03b0f 100644 --- a/domain/contract/repo.go +++ b/domain/contract/repo.go @@ -58,6 +58,7 @@ type ProviderRepo interface { Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user entity.User) ([]entity.Provider, error) GetByMukID(mukID string, user entity.User) (entity.Provider, error) GetByUUID(providerUUID string, user entity.User) (entity.Provider, error) + GetByNPI(NPI string, user entity.User) (entity.Provider, error) } // NotificationRepo defines the data set for Notification @@ -74,6 +75,7 @@ type OrganizationRepo interface { GetAllTypes() ([]entity.OrganizationType, error) GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error) GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) + GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error) GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error) GetContactsByOrganizationID(organizationID int64) ([]entity.OrganizationContact, error) GetContactsByUUID(contactUUID string) (entity.OrganizationContact, error) diff --git a/domain/entity/provider.go b/domain/entity/provider.go index 1f3be21..d262f78 100644 --- a/domain/entity/provider.go +++ b/domain/entity/provider.go @@ -26,6 +26,7 @@ type Provider struct { Keys []ProviderKey `json:"keys"` Address ProviderAddress `json:"address"` Distance float64 `json:"distance"` + Organization Organization `json:"organization"` } type ProviderKey struct { diff --git a/domain/service/organization.go b/domain/service/organization.go index f26c76b..e75424a 100644 --- a/domain/service/organization.go +++ b/domain/service/organization.go @@ -28,6 +28,10 @@ func (s *organizationService) GetByName(name string, searchType string, user ent return s.svc.db.Organization().GetByName(name, searchType, user) } +func (s *organizationService) GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error) { + return s.svc.db.Organization().GetByTypeAndReferenceID(typeKey, referenceID, user) +} + func (s *organizationService) GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) { organization, err := s.svc.db.Organization().GetByUUID(organizationUUID, user) if err != nil { diff --git a/domain/service/provider.go b/domain/service/provider.go index c03e036..0351e99 100644 --- a/domain/service/provider.go +++ b/domain/service/provider.go @@ -42,9 +42,46 @@ func (s *providerService) Get(query string, lat float64, long float64, distance } func (s *providerService) GetByMukID(mukID string, user entity.User) (entity.Provider, error) { - return s.svc.db.Provider().GetByMukID(mukID, user) + provider, err := s.svc.db.Provider().GetByMukID(mukID, user) + if err != nil { + return provider, err + } + + organization, err := s.svc.db.Organization().GetByTypeAndReferenceID("provider", provider.ProviderID, user) + if err != nil { + return provider, err + } + + provider.Organization = organization + return provider, nil } func (s *providerService) GetByUUID(providerUUID string, user entity.User) (entity.Provider, error) { - return s.svc.db.Provider().GetByUUID(providerUUID, user) + provider, err := s.svc.db.Provider().GetByUUID(providerUUID, user) + if err != nil { + return provider, err + } + + organization, err := s.svc.db.Organization().GetByTypeAndReferenceID("provider", provider.ProviderID, user) + if err != nil { + return provider, err + } + + provider.Organization = organization + return provider, nil +} + +func (s *providerService) GetByNPI(NPI string, user entity.User) (entity.Provider, error) { + provider, err := s.svc.db.Provider().GetByNPI(NPI, user) + if err != nil { + return provider, err + } + + organization, err := s.svc.db.Organization().GetByTypeAndReferenceID("provider", provider.ProviderID, user) + if err != nil { + return provider, err + } + + provider.Organization = organization + return provider, nil } diff --git a/ecs.dev.json b/ecs.dev.json index 511b6d5..27c34aa 100644 --- a/ecs.dev.json +++ b/ecs.dev.json @@ -1,35 +1,26 @@ { "containerDefinitions": [ { - "name": "api-development", - "image": "xxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/dev.nemt-portal-api:latest", + "name": "portal-api", + "image": "105690980714.dkr.ecr.us-east-2.amazonaws.com/nemt-portal-api:dev", "cpu": 128, "memory": 128, "essential": true, "logConfiguration": { "logDriver": "awslogs", "options": { - "awslogs-group": "nemt-portal-api", - "awslogs-region": "sa-east-1", - "awslogs-stream-prefix": "development" + "awslogs-group": "portal-api", + "awslogs-region": "us-east-2", + "awslogs-stream-prefix": "test" } }, "portMappings": [ { - "containerPort": 5100 - } - ], - "environment": [ - { - "name": "SERVICE_5100_NAME", - "value": "portal-api" - }, - { - "name": "SERVICE_5100_TAG", - "value": "api" + "containerPort": 443, + "hostPort": 5100 } ] } ], - "family": "api-development" + "family": "portal-api-dev" } \ No newline at end of file diff --git a/ecs.prd.json b/ecs.prd.json index a2e2bfd..d32915e 100644 --- a/ecs.prd.json +++ b/ecs.prd.json @@ -16,7 +16,7 @@ }, "portMappings": [ { - "containerPort": 5100, + "containerPort": 443, "hostPort": 5100 } ] diff --git a/ecs.stg.json b/ecs.stg.json index 9ff6ace..27c34aa 100644 --- a/ecs.stg.json +++ b/ecs.stg.json @@ -16,7 +16,7 @@ }, "portMappings": [ { - "containerPort": 5100, + "containerPort": 443, "hostPort": 5100 } ] diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..7efc4fa --- /dev/null +++ b/nginx.conf @@ -0,0 +1,32 @@ +user nginx; +worker_processes 1; +daemon on; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} \ No newline at end of file diff --git a/server/router/selfregisterroute/controller.go b/server/router/selfregisterroute/controller.go index 04c0392..4ef910a 100644 --- a/server/router/selfregisterroute/controller.go +++ b/server/router/selfregisterroute/controller.go @@ -1,12 +1,19 @@ package selfregisterroute import ( + "fmt" "sync" + b64 "encoding/base64" + "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/third/npd/npdmodel" + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" + "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" ) @@ -33,6 +40,104 @@ func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *co } func (c *controller) handle(ctx echo.Context) error { + var user viewmodel.User + if err := ctx.Bind(&user); err != nil { + return routeutils.HandleAPIError(ctx, err) + } - return routeutils.ResponseAPIOK(ctx, "OK") + authUser, err := auth.GetUserDetail(ctx, c.cfg) + if err != nil { + return routeutils.HandleAPIError(ctx, err) + } + if user.PhoneNumber == nil || len(*user.PhoneNumber) == 0 { + return routeutils.ResponseAPIValidationError(ctx, "phonenumber is required") + } + + if user.Email == nil || len(*user.Email) == 0 { + return routeutils.ResponseAPIValidationError(ctx, "email is required") + } + + if len(user.Pass) == 0 { + return routeutils.ResponseAPIValidationError(ctx, "password is required") + } + + pass, err := b64.StdEncoding.DecodeString(user.Pass) + if err != nil { + return routeutils.ResponseAPIValidationError(ctx, "Invalid password") + } + 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.ResponseAPIValidationError(ctx, "name is required") + } + + if len(user.First) != 0 && len(user.Last) != 0 { + user.Name = fmt.Sprintf("%s %s", user.First, user.Last) + } + + if len(user.Provider.InternalID) == 0 || len(user.Provider.InternalID) > 10 { + return routeutils.ResponseAPIValidationError(ctx, "Provider NPI is invalid") + } + + if len(user.Provider.OrganizatioName) == 0 { + return routeutils.ResponseAPIValidationError(ctx, "Provider Organization Name is invalid") + } + + provider, err := c.svc.Provider.GetByNPI(user.Provider.InternalID, authUser) + if err != nil { + fmt.Println("Error to create organization", err) + return routeutils.HandleAPIError(ctx, err) + } + + var organization viewmodel.Organization + if provider.ProviderUUID == "" { + org := viewmodel.Organization{ + Author: authUser, + LastEditor: authUser, + Name: user.Provider.OrganizatioName, + Type: viewmodel.OrganizationType{ + Key: "provider", + Name: "Provider", + }, + Reference: npdmodel.ProviderResponse{ + OrgName: user.Provider.OrganizatioName, + FivePartKeyGroups: []npdmodel.PartKeyGroup{ + npdmodel.PartKeyGroup{ + ProviderNum: user.Provider.InternalID, + }, + }, + }, + } + + organization, err = c.svc.Organization.AddOrganization(org, authUser) + if err != nil { + fmt.Println("Error to create organization", err) + return routeutils.HandleAPIError(ctx, err) + } + + if organization.UUID == "" { + return routeutils.ResponseAPIValidationError(ctx, "Error to create organization") + } + } else { + organization = provider.Organization + } + + user.Organizations = []viewmodel.Organization{organization} + user.Profiles = []viewmodel.Profile{viewmodel.Profile{ + Name: "Visit Reporter", + Key: "VIRPT", + Organization: organization, + }} + + user, err = c.svc.Users.Create(user, authUser) + if err != nil { + fmt.Println("Error to create user", err) + return routeutils.HandleAPIError(ctx, err) + } + + return routeutils.ResponseAPIOK(ctx, user) } diff --git a/server/router/usersroute/controller.go b/server/router/usersroute/controller.go index f6bad4d..ce5f1c6 100644 --- a/server/router/usersroute/controller.go +++ b/server/router/usersroute/controller.go @@ -345,6 +345,11 @@ func (c *controller) handleMember(ctx echo.Context) error { return routeutils.HandleAPIError(ctx, err) } + //Validate member + if validationErrors := validation.ValidateEligibility(&user) ; len(validationErrors) > 0 { + return routeutils.ResponseAPICustomValidationError(ctx, "eligibility validation failed", validationErrors) + } + authUser, err := auth.GetUserDetail(ctx, c.cfg) if err != nil { return routeutils.HandleAPIError(ctx, err) diff --git a/server/validation/eligibility.go b/server/validation/eligibility.go new file mode 100644 index 0000000..79e3c42 --- /dev/null +++ b/server/validation/eligibility.go @@ -0,0 +1,150 @@ +package validation + +import ( + "regexp" + "time" + + "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" + "bitbucket.org/nemt/nemt-portal-api/infra/errors" +) + +const ( + firstNameMaxLength = 50 + lastNameMaxLength = 50 + emailMaxLength = 150 + + memberNumberValidNumberOfLetters = 3 +) + +const ( + formModeVisit = 1 + formModeRide = 2 +) + +func isAlphabetic(input string) bool { + for _, character := range input { + if !(characterIsUpperCase(character) || characterIsLowerCase(character)){ + return false + } + } + return true +} + +func isNumeric(input string) bool { + for _, character := range input { + if !characterIsNumber(character){ + return false + } + } + + return true +} + +func isEmailValid (email string) bool { + validEmailRegex := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") + + return validEmailRegex.MatchString(email) +} + +func isMemberNumberValid(input string) bool { + if len(input) < memberNumberValidNumberOfLetters { + return false + } + + if !isAlphabetic(input[:memberNumberValidNumberOfLetters]) { + return false + } + + if !isNumeric(input[memberNumberValidNumberOfLetters:]){ + return false + } + + return true +} + +func ValidateEligibility(user *viewmodel.User) []errors.ValidationError { + var result []errors.ValidationError + + formMode:= formModeVisit // This should be red from request, not hardcoded + + //First name validation + if len(user.First) < 1 { + result = append(result, errors.ValidationError{Field: "first", Message: "First Name is required"}) + } + + if !isAlphabetic(user.First){ + result = append(result, errors.ValidationError{Field: "first", Message: "First Name contains non-alphabetic characters"}) + } + + if len(user.First) > firstNameMaxLength { + result = append(result, errors.ValidationError{Field: "first", Message: "First Name is too long"}) + } + + //Last name validation + if len(user.Last) < 1 { + result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is required"}) + } + + if !isAlphabetic(user.Last){ + result = append(result, errors.ValidationError{Field: "last", Message: "Last Name contains non-alphabetic characters"}) + } + + if len(user.Last) > lastNameMaxLength { + result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is too long"}) + } + + //Email validation + if user.Email != nil { + if (formMode==formModeRide) && len(*user.Email) < 1 { + result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"}) + } + + if !isEmailValid(*user.Email) { + result = append(result, errors.ValidationError{Field: "email", Message: "Email is invalid"}) + } + + if len(*user.Email) > emailMaxLength { + result = append(result, errors.ValidationError{Field: "email", Message: "Email is too long"}) + } + }else{ + if (formMode==formModeRide){ + result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"}) + } + } + + //Gender validation + if ((user.Gender != nil) && len(*user.Gender) < 1) || (user.Gender == nil) { + result = append(result, errors.ValidationError{Field: "gender", Message: "Member Gender is required"}) + } + + //Member type validation + if (user.Type != nil && len(*user.Type) < 1) || (user.Type == nil) { + result = append(result, errors.ValidationError{Field: "type", Message: "Member Type is required"}) + } + + //Member# validation + if !isMemberNumberValid(*user.Member){ + result = append(result, errors.ValidationError{Field: "member", Message: "Member# is invalid"}) + } + //Birthdate validation + if user.BirthDate == nil { + result = append(result, errors.ValidationError{Field: "birthdate", Message: "Choose a Birth Date"}) + }else{ + yesterday := time.Now().Add(-1*time.Hour*hoursInDay) + if user.BirthDate.After(yesterday) { + result = append(result, errors.ValidationError{Field: "birthdate", Message: "Choose a valid Birth Date"}) + } + } + //Mobile validation + if formMode == formModeRide { + if (user.PhoneNumber != nil && len(*user.PhoneNumber) < 1) || (user.PhoneNumber == nil) { + result = append(result, errors.ValidationError{Field: "phonenumber", Message: "Phone number is required"}) + } + } + //User consent validation + if !user.Consent{ + result = append(result, errors.ValidationError{Field: "consent", Message: "Must be 'Checked'"}) + } + + return result +} \ No newline at end of file diff --git a/server/validation/user.go b/server/validation/user.go index c4b73d8..1aa8a4c 100644 --- a/server/validation/user.go +++ b/server/validation/user.go @@ -39,8 +39,10 @@ func ValidatePassword(user *viewmodel.User) []errors.ValidationError { 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."}) + if len(userOrganizationName) > 0 { + if strings.Contains(user.Pass, userOrganizationName) { + result = append(result, errors.ValidationError{Field: "password", Message: "Password cannot include your Organization Name."}) + } } containsUpperCaseLetter := false