Skip to content

Commit

Permalink
Merge pull request #112 from bcgov/feature/server-env
Browse files Browse the repository at this point in the history
Add new config to determine deployed environment, and sso api connection
  • Loading branch information
kyle1morel authored Jul 12, 2024
2 parents 022358e + 110d424 commit 275e408
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .github/environments/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ config:
SERVER_CHES_APIPATH: https://ches-dev.api.gov.bc.ca/api/v1
SERVER_CHES_TOKENURL: https://dev.loginproxy.gov.bc.ca/auth/realms/comsvcauth/protocol/openid-connect/token
SERVER_DB_PORT: "5432"
SERVER_ENV: dev
# SERVER_LOGFILE: ~
SERVER_LOGLEVEL: http
SERVER_OIDC_AUTHORITY: https://dev.loginproxy.gov.bc.ca/auth/realms/standard
SERVER_OIDC_IDENTITYKEY: idir_user_guid,bceid_user_guid,github_id
SERVER_OIDC_PUBLICKEY: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuy7zfh2ZgpDV5mH/aXyLDTddZK81rGakJcTy4KvCNOkDDxt1KAhW02lmbCo8YhHCOzjNZBp1+Vi6QiMRgBqAe2GTPZYEiV70aXfROGZe3Nvwcjbtki6HoyRte3SpqLJEIPL2F+hjJkw1UPGnjPTWZkEx9p74b9i3BjuE8RnjJ0Sza2MWw83zoQUZEJRGiopSL0yuVej6t2LO2btVdVf7QuZfPt9ehkcQYlPKpVvJA+pfeqPAdnNt7OjEIeYxinjurZr8Z04hz8UhkRefcWlSbFzFQYmL7O7iArjW0bsSvq8yNUd5r0KCOQkFduwZy26yTzTxj8OLFT91fEmbBBl4rQIDAQAB
SERVER_PORT: "8080"
SERVER_SSO_APIPATH: https://api.loginproxy.gov.bc.ca/api/v1
SERVER_SSO_TOKENURL: https://loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token
SERVER_SSO_CLIENTID: service-account-team-1850-5484
SERVER_SSO_INTEGRATION: "5138"

patroni:
enabled: true
5 changes: 5 additions & 0 deletions .github/environments/values.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ config:
SERVER_CHES_APIPATH: https://ches.api.gov.bc.ca/api/v1
SERVER_CHES_TOKENURL: https://loginproxy.gov.bc.ca/auth/realms/comsvcauth/protocol/openid-connect/token
SERVER_DB_PORT: "5432"
SERVER_ENV: prod
# SERVER_LOGFILE: ~
SERVER_LOGLEVEL: http
SERVER_OIDC_AUTHORITY: https://loginproxy.gov.bc.ca/auth/realms/standard
SERVER_OIDC_IDENTITYKEY: idir_user_guid,bceid_user_guid
SERVER_OIDC_PUBLICKEY: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmHiuPKOkpkq4GXN1ktr23rJtDl6Vdu/Y37ZAd3PnQ8/IDfAODvy1Y81aAUZicKe9egolv+OTRANN3yOg+TAbRhkeXLE5p/473EK0aQ0NazTCuWo6Am3oDQ7Yt8x0pw56/qcLtkTuXNyo5EnVV2Z2BzCnnaL31JOhyitolku0DNT6GDoRBmT4o2ItqEVHk5nM25cf1t2zbwI2790W6if1B2qVRkxxivS8tbH7nYC61Is3XCPockKptkH22cm2ZQJmtYd5sZKuXaGsvtyzHmn8/l0Kd1xnHmUu4JNuQ67YiNZGu3hOkrF0Js3BzAk1Qm4kvYRaxbJFCs/qokLZ4Z0W9wIDAQAB
SERVER_PORT: "8080"
SERVER_SSO_APIPATH: https://api.loginproxy.gov.bc.ca/api/v1
SERVER_SSO_TOKENURL: https://loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token
SERVER_SSO_CLIENTID: service-account-team-1850-5484
SERVER_SSO_INTEGRATION: "5138"

patroni:
enabled: true
5 changes: 5 additions & 0 deletions .github/environments/values.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ config:
SERVER_CHES_APIPATH: https://ches-test.api.gov.bc.ca/api/v1
SERVER_CHES_TOKENURL: https://test.loginproxy.gov.bc.ca/auth/realms/comsvcauth/protocol/openid-connect/token
SERVER_DB_PORT: "5432"
SERVER_ENV: test
# SERVER_LOGFILE: ~
SERVER_LOGLEVEL: http
SERVER_OIDC_AUTHORITY: https://test.loginproxy.gov.bc.ca/auth/realms/standard
SERVER_OIDC_IDENTITYKEY: idir_user_guid,bceid_user_guid
SERVER_OIDC_PUBLICKEY: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiFdv9GA83uHuy8Eu9yiZHGGF9j6J8t7FkbcpaN81GDjwbjsIJ0OJO9dKRAx6BAtTC4ubJTBJMPvQER5ikOhIeBi4o25fg61jpgsU6oRZHkCXc9gX6mrjMjbsPaf3/bjjYxP5jicBDJQeD1oRa24+tiGggoQ7k6gDEN+cRYqqNpzC/GQbkUPk8YsgroncEgu8ChMh/3ERsLV2zorchMANUq76max16mHrhtWIQxrb/STpSt4JuSlUzzBV/dcXjJe5gywZHe0jAutFhNqjHzHdgyaC4RAd3eYQo+Kl/JOgy2AZrnx+CiPmvOJKe9tAW4k4H087ng8aVE40v4HW/FEbnwIDAQAB
SERVER_PORT: "8080"
SERVER_SSO_APIPATH: https://api.loginproxy.gov.bc.ca/api/v1
SERVER_SSO_TOKENURL: https://loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token
SERVER_SSO_CLIENTID: service-account-team-1850-5484
SERVER_SSO_INTEGRATION: "5138"

patroni:
enabled: true
10 changes: 9 additions & 1 deletion app/config/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"port": "SERVER_DB_PORT",
"username": "SERVER_DB_USERNAME"
},
"env": "SERVER_ENV",
"logFile": "SERVER_LOGFILE",
"logLevel": "SERVER_LOGLEVEL",
"oidc": {
Expand All @@ -68,6 +69,13 @@
"identityKey": "SERVER_OIDC_IDENTITYKEY",
"publicKey": "SERVER_OIDC_PUBLICKEY"
},
"port": "SERVER_PORT"
"port": "SERVER_PORT",
"sso": {
"apiPath": "SERVER_SSO_APIPATH",
"tokenUrl": "SERVER_SSO_TOKENURL",
"clientId": "SERVER_SSO_CLIENTID",
"clientSecret": "SERVER_SSO_CLIENTSECRET",
"integration": "SERVER_SSO_INTEGRATION"
}
}
}
18 changes: 18 additions & 0 deletions app/src/controllers/sso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ const controller = {
}
},

searchIdirUsers: async (req: Request, res: Response, next: NextFunction) => {
try {
const response = await ssoService.searchIdirUsers(req.query);
res.status(response.status).json(response.data);
} catch (e: unknown) {
next(e);
}
},

searchBasicBceidUsers: async (req: Request, res: Response, next: NextFunction) => {
try {
const response = await ssoService.searchBasicBceidUsers(req.query);
res.status(response.status).json(response.data);
} catch (e: unknown) {
next(e);
}
},

getRoles: async (req: Request, res: Response, next: NextFunction) => {
try {
const response = await ssoService.getRoles();
Expand Down
8 changes: 8 additions & 0 deletions app/src/routes/v1/sso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ router.post('/requestBasicAccess', (req: Request, res: Response, next: NextFunct
ssoController.requestBasicAccess(req, res, next);
});

router.get('/idir/users', (req: Request, res: Response, next: NextFunction): void => {
ssoController.searchIdirUsers(req, res, next);
});

router.get('/basic-bceid/users', (req: Request, res: Response, next: NextFunction): void => {
ssoController.searchBasicBceidUsers(req, res, next);
});

router.get('/roles', (req: Request, res: Response, next: NextFunction): void => {
ssoController.getRoles(req, res, next);
});
Expand Down
58 changes: 56 additions & 2 deletions app/src/services/sso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ import { AccessRole } from '../utils/enums/application';

import type { AxiosInstance } from 'axios';

// Types

type IdirSearchParams = {
firstName: string;
lastName: string;
email: string;
};

type BCeIdSearchParams = {
guid: string;
};

/**
* @function getToken
* Gets Auth token using SSO credentials
Expand Down Expand Up @@ -52,8 +64,9 @@ function ssoAxios(): AxiosInstance {
const service = {
requestBasicAccess: async (username: string) => {
try {
const env = config.get('server.env');
const integration = config.get('server.sso.integration');
const { data, status } = await ssoAxios().post(`/integrations/${integration}/dev/users/${username}/roles`, [
const { data, status } = await ssoAxios().post(`/integrations/${integration}/${env}/users/${username}/roles`, [
{
name: AccessRole.PCNS_PROPONENT
}
Expand All @@ -74,10 +87,51 @@ const service = {
}
},

searchIdirUsers: async (params?: IdirSearchParams) => {
try {
const env = config.get('server.env');
const { data, status } = await ssoAxios().get(`/${env}/idir/users`, { params: params });
return { data: data.data, status };
} catch (e: unknown) {
if (axios.isAxiosError(e)) {
return {
data: e.response?.data.message,
status: e.response ? e.response.status : 500
};
} else {
return {
data: 'Error',
status: 500
};
}
}
},

searchBasicBceidUsers: async (params?: BCeIdSearchParams) => {
try {
const env = config.get('server.env');
const { data, status } = await ssoAxios().get(`/${env}/basic-bceid/users`, { params: params });
return { data: data.data, status };
} catch (e: unknown) {
if (axios.isAxiosError(e)) {
return {
data: e.response?.data.message,
status: e.response ? e.response.status : 500
};
} else {
return {
data: 'Error',
status: 500
};
}
}
},

getRoles: async () => {
try {
const env = config.get('server.env');
const integration = config.get('server.sso.integration');
const { data, status } = await ssoAxios().get(`/integrations/${integration}/dev/roles`);
const { data, status } = await ssoAxios().get(`/integrations/${integration}/${env}/roles`);
return { data: data.data, status };
} catch (e: unknown) {
if (axios.isAxiosError(e)) {
Expand Down
2 changes: 1 addition & 1 deletion charts/pcns/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: nr-permitconnect-navigator-service
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.0.9
version: 0.0.10
kubeVersion: ">= 1.13.0"
description: PermitConnect Navigator Service
# A chart can be either an 'application' or a 'library' chart.
Expand Down
4 changes: 2 additions & 2 deletions charts/pcns/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# nr-permitconnect-navigator-service

![Version: 0.0.9](https://img.shields.io/badge/Version-0.0.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square)
![Version: 0.0.10](https://img.shields.io/badge/Version-0.0.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square)

PermitConnect Navigator Service

Expand Down Expand Up @@ -35,7 +35,7 @@ Kubernetes: `>= 1.13.0`
| autoscaling.targetCPUUtilizationPercentage | int | `80` | |
| chesSecretOverride.password | string | `nil` | |
| chesSecretOverride.username | string | `nil` | |
| config.configMap | object | `{"FRONTEND_APIPATH":"api/v1","FRONTEND_CHES_ROADMAP_BCC":null,"FRONTEND_CHES_SUBMISSION_CC":null,"FRONTEND_COMS_APIPATH":null,"FRONTEND_COMS_BUCKETID":null,"FRONTEND_GEOCODER_APIPATH":null,"FRONTEND_OIDC_AUTHORITY":null,"FRONTEND_OIDC_CLIENTID":null,"FRONTEND_OPENSTREETMAP_APIPATH":null,"FRONTEND_ORGBOOK_APIPATH":null,"SERVER_APIPATH":"/api/v1","SERVER_BODYLIMIT":"30mb","SERVER_CHEFS_APIPATH":null,"SERVER_CHES_APIPATH":null,"SERVER_CHES_TOKENURL":null,"SERVER_DB_HOST":null,"SERVER_DB_POOL_MAX":"10","SERVER_DB_POOL_MIN":"2","SERVER_DB_PORT":"5432","SERVER_LOGLEVEL":"http","SERVER_OIDC_AUTHORITY":null,"SERVER_OIDC_IDENTITYKEY":null,"SERVER_OIDC_PUBLICKEY":null,"SERVER_PORT":"8080"}` | These values will be wholesale added to the configmap as is; refer to the pcns documentation for what each of these values mean and whether you need them defined. Ensure that all values are represented explicitly as strings, as non-string values will not translate over as expected into container environment variables. For configuration keys named `*_ENABLED`, either leave them commented/undefined, or set them to string value "true". |
| config.configMap | object | `{"FRONTEND_APIPATH":"api/v1","FRONTEND_CHES_ROADMAP_BCC":null,"FRONTEND_CHES_SUBMISSION_CC":null,"FRONTEND_COMS_APIPATH":null,"FRONTEND_COMS_BUCKETID":null,"FRONTEND_GEOCODER_APIPATH":null,"FRONTEND_OIDC_AUTHORITY":null,"FRONTEND_OIDC_CLIENTID":null,"FRONTEND_OPENSTREETMAP_APIPATH":null,"FRONTEND_ORGBOOK_APIPATH":null,"SERVER_APIPATH":"/api/v1","SERVER_BODYLIMIT":"30mb","SERVER_CHEFS_APIPATH":null,"SERVER_CHES_APIPATH":null,"SERVER_CHES_TOKENURL":null,"SERVER_DB_HOST":null,"SERVER_DB_POOL_MAX":"10","SERVER_DB_POOL_MIN":"2","SERVER_DB_PORT":"5432","SERVER_ENV":null,"SERVER_LOGLEVEL":"http","SERVER_OIDC_AUTHORITY":null,"SERVER_OIDC_IDENTITYKEY":null,"SERVER_OIDC_PUBLICKEY":null,"SERVER_PORT":"8080"}` | These values will be wholesale added to the configmap as is; refer to the pcns documentation for what each of these values mean and whether you need them defined. Ensure that all values are represented explicitly as strings, as non-string values will not translate over as expected into container environment variables. For configuration keys named `*_ENABLED`, either leave them commented/undefined, or set them to string value "true". |
| config.enabled | bool | `false` | Set to true if you want to let Helm manage and overwrite your configmaps. |
| config.releaseScoped | bool | `false` | This should be set to true if and only if you require configmaps and secrets to be release scoped. In the event you want all instances in the same namespace to share a similar configuration, this should be set to false |
| dbSecretOverride.password | string | `nil` | |
Expand Down
5 changes: 5 additions & 0 deletions charts/pcns/templates/deploymentconfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ spec:
secretKeyRef:
key: password
name: {{ include "pcns.configname" . }}-oidc
- name: SERVER_SSO_CLIENTSECRET
valueFrom:
secretKeyRef:
key: password
name: {{ include "pcns.configname" . }}-sso
envFrom:
- configMapRef:
name: {{ include "pcns.configname" . }}-config
Expand Down
18 changes: 18 additions & 0 deletions charts/pcns/templates/secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
{{- $chesUsername := (randAlphaNum 32) }}
{{- $oPassword := (randAlphaNum 32) }}
{{- $oUsername := (randAlphaNum 32) }}
{{- $ssoPassword := (randAlphaNum 32) }}
{{- $ssoUsername := (randAlphaNum 32) }}

{{- $dbSecretName := printf "%s-%s" (include "pcns.configname" .) "passphrase" }}
{{- $dbSecret := (lookup "v1" "Secret" .Release.Namespace $dbSecretName ) }}
Expand All @@ -19,6 +21,8 @@
{{- $chesSecret := (lookup "v1" "Secret" .Release.Namespace $chesSecretName ) }}
{{- $oSecretName := printf "%s-%s" (include "pcns.configname" .) "oidc" }}
{{- $oSecret := (lookup "v1" "Secret" .Release.Namespace $oSecretName ) }}
{{- $ssoSecretName := printf "%s-%s" (include "pcns.configname" .) "sso" }}
{{- $ssoSecret := (lookup "v1" "Secret" .Release.Namespace $ssoSecretName ) }}

{{- if and (not $dbSecret) (not .Values.patroni.enabled) }}
---
Expand Down Expand Up @@ -101,4 +105,18 @@ type: kubernetes.io/basic-auth
data:
password: {{ .Values.oidcSecretOverride.password | default $oPassword | b64enc | quote }}
username: {{ .Values.oidcSecretOverride.username | default $oUsername | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
{{- if not .Values.config.releaseScoped }}
annotations:
"helm.sh/resource-policy": keep
{{- end }}
name: {{ $ssoSecretName }}
labels: {{ include "pcns.labels" . | nindent 4 }}
type: kubernetes.io/basic-auth
data:
password: {{ .Values.ssoSecretOverride.password | default $ssoPassword | b64enc | quote }}
username: {{ .Values.ssoSecretOverride.username | default $ssoUsername | b64enc | quote }}
{{- end }}
13 changes: 12 additions & 1 deletion charts/pcns/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,22 @@ config:
SERVER_DB_POOL_MIN: "2"
SERVER_DB_POOL_MAX: "10"

SERVER_ENV: ~

# SERVER_LOGFILE: ~
SERVER_LOGLEVEL: http
SERVER_PORT: "8080"

SERVER_OIDC_AUTHORITY: ~
SERVER_OIDC_IDENTITYKEY: ~
SERVER_OIDC_PUBLICKEY: ~

SERVER_PORT: "8080"

SERVER_SSO_APIPATH: ~
SERVER_SSO_TOKENURL: ~
SERVER_SSO_CLIENTID: ~
SERVER_SSO_INTEGRATION: ~

# Modify the following variables if you need to acquire secret values from a custom-named resource
dbSecretOverride:
username: ~
Expand All @@ -179,6 +187,9 @@ chesSecretOverride:
oidcSecretOverride:
username: ~
password: ~
ssoSecretOverride:
username: ~
password: ~

# Patroni subchart configuration overrides
patroni:
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/services/permissionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ export default class PermissionService {
return appAxios().post('sso/requestBasicAccess');
}

public async searchIdirUsers(params?: any) {
return appAxios().get('sso/idir/users', { params: params });
}

public async searchBasicBceidUsers(params?: any) {
return appAxios().get('sso/basic-bceid/users', { params: params });
}

public async getRoles() {
return appAxios().get('sso/roles');
}
Expand Down
17 changes: 14 additions & 3 deletions frontend/src/views/DeveloperView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ async function ssoRequestBasicAccess() {
await permissionService.requestBasicAccess();
}
async function ssGetRoles() {
async function searchIdirUsers() {
await permissionService.searchIdirUsers({ firstName: 'Kyle' });
}
async function searchBasicBceidUsers() {
await permissionService.searchBasicBceidUsers({ guid: 'tb914nlltlo4mz05viha1b4hdyi4xnad' });
}
async function ssoGetRoles() {
await permissionService.getRoles();
}
</script>
Expand Down Expand Up @@ -84,10 +92,13 @@ async function ssGetRoles() {
<div class="flex align-items-center mt-3">
<h3 class="mr-2">SSO Test</h3>
<div>
<Button @click="ssoRequestBasicAccess">SSO Test</Button>
<Button @click="searchIdirUsers">SSO search idir</Button>
</div>
<div>
<Button @click="searchBasicBceidUsers">SSO search basic bceid</Button>
</div>
<div>
<Button @click="ssGetRoles">SSO Test 2</Button>
<Button @click="ssoGetRoles">SSO get roles</Button>
</div>
</div>
</div>
Expand Down

0 comments on commit 275e408

Please sign in to comment.