From 4054765db562959a47db07c5572ef9e60c2c0dd9 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 20 May 2020 20:27:26 -0700 Subject: [PATCH 1/8] Fixing issue with email and reminder settings --- .../src/components/common/NoEmailAlert.vue | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/appointment-frontend/src/components/common/NoEmailAlert.vue b/appointment-frontend/src/components/common/NoEmailAlert.vue index 5ddbb1565..de2fea14a 100644 --- a/appointment-frontend/src/components/common/NoEmailAlert.vue +++ b/appointment-frontend/src/components/common/NoEmailAlert.vue @@ -10,7 +10,8 @@ dense dismissible > -
+
Please configure your email address to receive notifications
+
Please subscribe to email reminders to receive appointment reminders
@@ -34,20 +35,17 @@ export default class NoEmailAlert extends Vue { private readonly currentUserProfile!: User private showEmailAlert: boolean = false - private alertText: string = '' + private isEmailMissing:boolean = false + private isReminderFlagMissing:boolean = false private mounted () { this.showEmailAlert = !this.currentUserProfile?.email || !this.currentUserProfile?.send_reminders if (!this.currentUserProfile?.email) { - this.alertText = 'Please configure your email address to receive notifications' + this.isEmailMissing = true } else if (!this.currentUserProfile?.send_reminders) { - this.alertText = 'Please subscribe to email reminders to receive appointment reminders' + this.isReminderFlagMissing = true } } - - private goToAccountSettings () { - this.$router.push('/account-settings') - } } From 887edf143f5b99348083f22a2da5f227eb05a713 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 20 May 2020 20:42:58 -0700 Subject: [PATCH 2/8] Fixing issue with email and reminder settings --- .../appointment/AppointmentSummary.vue | 4 +++- .../components/appointment/LocationsList.vue | 18 ------------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/appointment-frontend/src/components/appointment/AppointmentSummary.vue b/appointment-frontend/src/components/appointment/AppointmentSummary.vue index c6727c078..f6b6f34e5 100644 --- a/appointment-frontend/src/components/appointment/AppointmentSummary.vue +++ b/appointment-frontend/src/components/appointment/AppointmentSummary.vue @@ -85,7 +85,9 @@ - + + + diff --git a/appointment-frontend/src/components/appointment/LocationsList.vue b/appointment-frontend/src/components/appointment/LocationsList.vue index 427de9d08..6e03dd805 100644 --- a/appointment-frontend/src/components/appointment/LocationsList.vue +++ b/appointment-frontend/src/components/appointment/LocationsList.vue @@ -6,24 +6,6 @@ - - - - - From 184fea10f681051290a58b4e7e14f8ca7e6f076f Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 20 May 2020 21:07:25 -0700 Subject: [PATCH 3/8] Fixing sonar issues --- api/app/models/theq/time_slot.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/api/app/models/theq/time_slot.py b/api/app/models/theq/time_slot.py index e5cc8d3b8..10d131f28 100644 --- a/api/app/models/theq/time_slot.py +++ b/api/app/models/theq/time_slot.py @@ -36,7 +36,3 @@ def __repr__(self): def __init__(self, **kwargs): super(TimeSlot, self).__init__(**kwargs) - - @classmethod - def find_by_office_id(cls, office_id: int): - return cls.query.filter(office_id == office_id).all() From d94962b861dc038d3269bf4b5f3b7c16636039c6 Mon Sep 17 00:00:00 2001 From: Nitheesh T Ganesh <60233274+nitheesh-aot@users.noreply.github.com> Date: Wed, 20 May 2020 22:59:43 -0700 Subject: [PATCH 4/8] Doc update (#113) * Bug fixes (#102) * Changes for email service and job * persisting data in store properly * Demo feedback changes * update user profile, setup email alert * Update GeoModule to match new module setup * Freezing the requirements.txt * Trying with no flask mail * Trying with no flask mail * Adding dev config to allow cors * Adding dev config to allow cors * Adding changes for CORS and re-enabling email * Changing citizen model * Changing citizen model * Adding onliine flag to appointment * appointment listing * Adding onliine flag to appointment * clearing selected values * Adding changes to delete appointments during blackout appointment creation * appointment listing * clearing selected values * Fix CORS issue for local dev * appointment listing * clearing selected values * appointment listing * clearing selected values * signout * Fixing day_of_week to return array of string * timeslot changes incorporated * Adding authorization for all endpoints * Commenting role based auth * Geocoding and Google Maps logic complete - Replaced all maps with static map API - Calculating distance of all locations and sorting - All Geo/DataBC integration edge conditions * user get * delete appointments * Adding authorization for all endpoints * Adding authorization for all endpoints * edit appointment * show service link if any * Add new rate limited route * Change local proxy URL over to rate limited OpenShift URL * Rename keycloak to keycloak-public.json Used to match OpenShift ConfigMap * Rename keycloak.json in keycloak-public.json * enabling available dates and indicating it * datetime format to common function * avoided unwanted api calls while step change in stepper * indicate already selected office * showing selected time slot on edit mode * Fixing issue with update appointment * appointment success popup fix * More mobile work on location list, header, hours section has line breaks * Mobile responseiveness fo the actions buttons on location page * Adding osd link hard coded - just for demo uat. * Adding osd link hard coded - just for demo uat. * Pinning flask admin to 1.5.5 * Pinning flask admin to 1.5.5 * Adding config templates * Fixing issue with button width in email, and blackout email being deleted * service selection link in option * Excluding checked in appointments cancellation emails * Hide BC Services card configured in configuration.json * Mobile middle column sizing * Reverting back to configuration.json for configs * Accessibility, change default info/success colours * BCEID Registration URL controlled by json param * Adding snowplow and confirmation email changes * Adding snowplow and confirmation email changes * category correction search service list * Adding snowplow and confirmation email changes * phone number optional telephone in acc summary * Change username to display_name for BCEID * Update default configuration * Add ConfigMap to deploymentconfig. * Add missing parsed token variable copy * Fixing issue with timezone * Fixing issue with timezone * Fixing issue with timezone * Fixing issue with timezone * Convert Appointments list to use StaticMap API * Mobile responsiveness for book appointments page * update requirements * Allow Snowplow calls for self serve appointments, where there is no CSR Fix bug with Snowplow calls for blackout appointments * Adding snowplow and confirmation email changes * Adding snowplow and confirmation email changes * Adding snowplow and confirmation email changes * Change username to display_name for BCEID * Update default configuration * Add ConfigMap to deploymentconfig. * Add missing parsed token variable copy * Fixing issue with timezone * Fixing issue with timezone * Fixing issue with timezone * Fixing issue with timezone * timezone dynamic from office * service list as per requirement ! * stepper validation and back button * Add autocomplete: true to geocoder * Lazy load images, reducing Google Maps API calls * Remove duplicate title from merge conflit * Bypass stepper is configurable by env var * Revert "Bypass stepper is configurable by env var" This reverts commit d2b6427b01f7ad379dc779a043f77bebc278d34d. * Commenting out confirmation email to troubleshoot issue with appointments * Added Terms of Service modal * Fixed mobile responsiveness of back button on iphone * allow appointments in non-reception office * Fix cross browser Safari bug * Mobile resposiveness of Date selection * allow appointments in non-reception office * allow appointments in non-reception office * Show error message from API when booking appointment * email alert on booking success modal * text change on external link * external name in category list * UI cleanup * click header logo to home * Fixing issues with timeslot for GA and appointment slots * Fixing issue with sending email asynchronously * Sending confirmation on update * Sending confirmation on update * Adding fix for appointment reminder flag * Troubleshooting issue with slots * Troubleshooting issue with slots * allow appointments in non-reception office * Troubleshooting issue with email subject * Troubleshooting issue with email subject Troubleshooting issue with email subject * Troubleshooting issue with email subject * Troubleshooting issue with email subject * Troubleshooting issue with email subject * Troubleshooting issue with threading in test environment * Adding daemon True for threads to fix issue with parallel running * Fix stepper CSS for very small devices * Responsiveness of time slot selection * Adding CSP to caddy image * Sort service list alphabetically * Refactor alphabetical sort for clarity * Adding CSP to caddy image * Adding CSP to caddy image * Adding CSP to caddy image * Add local proxying to debug on IE on windows machine * IE11 build config and timezone polyfill for date * Add 'Alpha' header * Keycloak-public.json ConfigMap * Adding snowplow fix as per chris.mcintosh * timezone fixes * Updating postman collection and readme document * Fix Safari timezone bug on appointment summary page * Adding delay-request and new params * Fixnpm run build issue from type signature * Adding changes for disabling office selection and button changes * Adding changes to let users to book appointment if the appointment is checked in for the day * Bug fixes * ui fixes, privacy statement * Fixing office list issue * Timezone fix * Adding reminder alert and style fix Co-authored-by: Nitheesh T Ganesh Co-authored-by: Adam Coard Co-authored-by: acoard-aot <61285798+acoard-aot@users.noreply.github.com> Co-authored-by: Karim Gillani Co-authored-by: Chris Co-authored-by: Nitheesh T Ganesh <60233274+nitheesh-aot@users.noreply.github.com> Co-authored-by: ozamani * unavailable page for ie < 11, and user without online appointment role * service selection * Adding manifest-src to CSP * disabled service selection refresh issue fix * Merge branch 'master' of https://github.com/AOT-Technologies/queue-management * Time slot fix * Time slot fix * Time slot fix * Commenting out logs * frontend docs * google mapi api info Co-authored-by: Sumesh Punakkal Kariyil Co-authored-by: Adam Coard Co-authored-by: acoard-aot <61285798+acoard-aot@users.noreply.github.com> Co-authored-by: Karim Gillani Co-authored-by: Chris Co-authored-by: ozamani --- appointment-frontend/README.md | 41 ++++++++++++++-------- documentation/demo-files/.env.appointments | 3 ++ 2 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 documentation/demo-files/.env.appointments diff --git a/appointment-frontend/README.md b/appointment-frontend/README.md index 010c53d9b..8e9708b4b 100644 --- a/appointment-frontend/README.md +++ b/appointment-frontend/README.md @@ -1,5 +1,32 @@ # SBC Appointment Booking +#### Copy these required files to the correct place in your directory structure +``` +cd queue-management +mkdir -p appointment-frontend/public/config/kc + +cp documentation/demo-files/keycloak.json appointment-frontend/public/config/kc/keycloak-public.json + +cp documentation/demo-files/.env.appointments appointment-frontend/.env.local + +-------- + +cd api +mkdir client_secrets +cd .. + +cp documentation/demo-files/secrets.json api/client_secrets/secrets.json +``` + +Note: +- inorder to book an appointment, add a user to the local keycloak with the role ***'online_appointment_user'***. + +- if you need to use BCSC or BCeID services, please point to the dev keycloak + +- Get Google Map API Key from Google developer console. and use it as VUE_APP_GOOGLE_STATIC_MAP_API_KEY in .env.local file + + + ## Project setup ``` npm install @@ -15,20 +42,6 @@ npm run serve npm run build ``` -### Run your tests -``` -npm run test -``` - -### Lints and fixes files -``` -npm run lint -``` - -### Run your unit tests -``` -npm run test:unit -``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/documentation/demo-files/.env.appointments b/documentation/demo-files/.env.appointments new file mode 100644 index 000000000..546df7df7 --- /dev/null +++ b/documentation/demo-files/.env.appointments @@ -0,0 +1,3 @@ +VUE_APP_PATH = / +VUE_APP_GOOGLE_STATIC_MAP_API_KEY = replace_key_here +VUE_APP_ROOT_API = http://localhost:8080/api/v1 From 721bad1d29b795623dced2411f97c2c21707cea4 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 20 May 2020 23:27:11 -0700 Subject: [PATCH 5/8] Adding keycloak documentation --- documentation/Keycloak.md | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 documentation/Keycloak.md diff --git a/documentation/Keycloak.md b/documentation/Keycloak.md new file mode 100644 index 000000000..0015fc5b8 --- /dev/null +++ b/documentation/Keycloak.md @@ -0,0 +1,85 @@ +# Keycloak Setup for TheQ and Online Appointments applications + +#### Keycloak Overview +Keycloak is an open source identity and access management platform. FOI uses Keycloak as an identity broker platform to delegate authentication to other identity providers. + +#### Keycloak Base URL +|Environment|URL| +|---|---| +|DEV| https://sso-dev.pathfinder.gov.bc.ca/auth/admin/vtkayq4c/console/| +|TEST| https://sso-test.pathfinder.gov.bc.ca/auth/admin/vtkayq4c/console/| +|PROD| https://sso.pathfinder.gov.bc.ca/auth/admin/vtkayq4c/console/| + + +#### Identity Providers +|IDP|Users| +|---|---| +|BC Services Card| Citizens using BC Services Card to book appointments online| +|IDIR| Internal staff users| +|BCeID| Citizens to book appointments online and internal staff users| + +#### Roles +Default role mapper is added for all identity ptovider to populate the role by default whenever someone logs in to the application for first time. +This is done using a 'Hardcoded Role' mapper on identity provider. Below are the roles mapped for identity provider; +- IDIR : internal_user +- BCeID : online_appointment_user +- BC Services Card : online_appointment_user + +Enable scope for the client which the application is using to innclude the roles in jwt token. For this; +1. Login to keycloak realm and select the client +2. Go to 'Scope' tab +3. Enable 'Full Scope Allowed' + +#### Groups +For BCeID users who wants to access TheQ application would need internal_user role. Add those users to the group 'theq_internal_user' which would add the internal_user role to them. + +##### Create a custom authentication flow +Keycloak by default needs email as part of the user profile and asks the user to fill it in if the profile doesn't have it. For our application there will be users who doesn't have verified email address linked with their BC Services Card. +To prevent Keycloak asking the user to fill out email if the profile doesn't have email address, create a custom authentication flow to bypass this page. + +1. Login to Keycloak as a realm administrator +2. Navigate to 'Authentication' tab +3. Select First Broker Login +4. Click on 'Copy' button on the right and name it as 'BCSC first broker login' +5. Select 'Actions' link against 'Review Profile' and click on 'Config' +6. Select 'off' for the value 'Update Profile on First Login' +7. Save. + + +#### Disable keycloak account linking +To not allow users to link a verified account with a unverified account. There could be scenario where a Basic BCeID user uses the same email address (unverified) as the BC Services Card user’s email address (verified). IN this case if we allow BCeID user to link the BCSC user account, that may open some security issues. If we have a requirement for user linking, we will need to make sure we have the ability to confirm both users are same. + +1. Disable 'Confirm Link Existing Account’ from the custom first broker login +2. Disable 'Verify Existing Account By Email’ from the custom first broker login +3. Add this custom first broker login for both BCeID and BCSC + + +##### Configure BC Services Card Identity Provider (Using Import) +To import the BC Services Card configuration, +1. Login to Keycloak as a realm administrator +2. Click on 'Import' Link +3. Select the file [keycloak config](/keycloak-config/config.json) for 'Exported json file' +4. Select 'Skip' for 'If a resource exists' +5. Import + +##### Step 3) Change client id and secret for BC Services Card +1. Login to Keycloak as a realm administrator +2. Navigate to 'Identity Providers' +3. Select 'BC Services Card' +4. Scroll down to 'Client ID' and 'Client Secret' and paste the value received from IDIM team +5. Save + +##### Step 4) Add mappers for the attributes from BC Services Card +1. Login to Keycloak as a realm administrator +2. Navigate to 'Identity Providers' +3. Select 'BC Services Card' +4. Select 'Mappers' and create the mappers with the values from below table + + +|Name|Mapper Type|Claim|User Attribute Name| +|---|---|---|---| +|name|Attribute Importer|display_name|displayName| +|lastName|Attribute Importer|family_name|lastName| +|email|Attribute Importer|email|email| +|username|Username Template Importer|\${ALIAS}/\${CLAIM.sub}| +|online appointment role mapper|Hardcoded Role| online_appointment_user| From 193a55db8372bfac0377532aa6600886ac45513f Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 20 May 2020 23:28:40 -0700 Subject: [PATCH 6/8] Adding keycloak documentation --- documentation/Keycloak.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/Keycloak.md b/documentation/Keycloak.md index 0015fc5b8..0d3b2733e 100644 --- a/documentation/Keycloak.md +++ b/documentation/Keycloak.md @@ -58,7 +58,7 @@ To not allow users to link a verified account with a unverified account. There c To import the BC Services Card configuration, 1. Login to Keycloak as a realm administrator 2. Click on 'Import' Link -3. Select the file [keycloak config](/keycloak-config/config.json) for 'Exported json file' +3. Select the file [keycloak config](/documentation/keycloak-config/config.json) for 'Exported json file' 4. Select 'Skip' for 'If a resource exists' 5. Import From 69fef41294f726df647d76317a7eaa26f689013f Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 20 May 2020 23:45:13 -0700 Subject: [PATCH 7/8] Export of realm with new configuration --- keycloak-local-testserver/registry-realm.json | 694 +++++++++++------- 1 file changed, 425 insertions(+), 269 deletions(-) diff --git a/keycloak-local-testserver/registry-realm.json b/keycloak-local-testserver/registry-realm.json index 0b9a6488c..a6caa5173 100644 --- a/keycloak-local-testserver/registry-realm.json +++ b/keycloak-local-testserver/registry-realm.json @@ -3,6 +3,7 @@ "realm": "registry", "notBefore": 1491571623, "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, "accessTokenLifespan": 300, "accessTokenLifespanForImplicitFlow": 900, "ssoSessionIdleTimeout": 1800, @@ -11,6 +12,8 @@ "accessCodeLifespan": 60, "accessCodeLifespanUserAction": 300, "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, "enabled": true, "sslRequired": "external", "registrationAllowed": false, @@ -22,6 +25,7 @@ "resetPasswordAllowed": false, "editUsernameAllowed": false, "bruteForceProtected": false, + "permanentLockout": false, "maxFailureWaitSeconds": 900, "minimumQuickLoginWaitSeconds": 60, "waitIncrementSeconds": 60, @@ -63,6 +67,14 @@ "clientRole": false, "containerId": "registry" }, + { + "id": "5e4710f4-f53d-4477-a69c-282d8afbb613", + "name": "online_appointment_user", + "scopeParamRequired": false, + "composite": false, + "clientRole": false, + "containerId": "registry" + }, { "id": "21463f18-976a-43a1-b12e-71244b13f34f", "name": "offline_access", @@ -78,10 +90,20 @@ "scopeParamRequired": false, "composite": true, "composites": { - "realm": ["editor"] + "realm": [ + "editor" + ] }, "clientRole": false, "containerId": "registry" + }, + { + "id": "f6a090ad-64c2-4d09-9679-e94501116139", + "name": "internal_user", + "scopeParamRequired": false, + "composite": false, + "clientRole": false, + "containerId": "registry" } ], "client": { @@ -110,6 +132,23 @@ "name": "view-users", "description": "${role_view-users}", "scopeParamRequired": false, + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-groups", + "query-users" + ] + } + }, + "clientRole": true, + "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" + }, + { + "id": "cdc69084-1d9c-4e7e-a6c0-909c32a0a806", + "name": "query-users", + "description": "${role_query-users}", + "scopeParamRequired": false, "composite": false, "clientRole": true, "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" @@ -119,7 +158,14 @@ "name": "view-clients", "description": "${role_view-clients}", "scopeParamRequired": false, - "composite": false, + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-clients" + ] + } + }, "clientRole": true, "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" }, @@ -141,6 +187,15 @@ "clientRole": true, "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" }, + { + "id": "e98ee2d5-6505-4eca-9a04-27edd759046b", + "name": "query-realms", + "description": "${role_query-realms}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" + }, { "id": "bffb0879-9df8-4826-9a45-367e03dd8bf7", "name": "view-identity-providers", @@ -180,16 +235,20 @@ "view-authorization", "view-users", "impersonation", + "query-users", "view-clients", "create-client", "manage-authorization", + "query-realms", "view-identity-providers", "view-realm", "manage-users", + "query-groups", "manage-events", "manage-realm", "manage-identity-providers", "manage-clients", + "query-clients", "view-events" ] } @@ -197,6 +256,15 @@ "clientRole": true, "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" }, + { + "id": "80ac5c0d-e15f-4c61-b9b6-173571c7a0d0", + "name": "query-groups", + "description": "${role_query-groups}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" + }, { "id": "076bbf68-63b0-4874-b8ed-f87694664dad", "name": "manage-events", @@ -241,6 +309,15 @@ "composite": false, "clientRole": true, "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" + }, + { + "id": "3a43c9b3-b279-40d4-9593-dac07cbd0cda", + "name": "query-clients", + "description": "${role_query-clients}", + "scopeParamRequired": false, + "composite": false, + "clientRole": true, + "containerId": "b52f66a3-0938-4359-820a-888c3b238c71" } ], "namex-api-service": [], @@ -280,9 +357,13 @@ } }, "groups": [], - "defaultRoles": ["offline_access", "uma_authorization"], - "requiredCredentials": ["password"], - "passwordPolicy": "hashIterations(20000)", + "defaultRoles": [ + "uma_authorization", + "offline_access" + ], + "requiredCredentials": [ + "password" + ], "otpPolicyType": "totp", "otpPolicyAlgorithm": "HmacSHA1", "otpPolicyInitialCounter": 0, @@ -380,18 +461,10 @@ "groups": [] } ], - "clientScopeMappings": { - "realm-management": [ - { - "client": "admin-cli", - "roles": ["realm-admin"] - }, - { - "client": "security-admin-console", - "roles": ["realm-admin"] - } - ] - }, + "otpSupportedApplications": [ + "FreeOTP", + "Google Authenticator" + ], "clients": [ { "id": "5b221d6b-38be-44c0-b08b-d6d169b6c71f", @@ -402,9 +475,16 @@ "enabled": true, "clientAuthenticatorType": "client-secret", "secret": "5abdcb03-9dc6-4789-8c1f-8230c7d7cb79", - "defaultRoles": ["view-profile", "manage-account"], - "redirectUris": ["http://localhost:8080/*"], - "webOrigins": ["*"], + "defaultRoles": [ + "manage-account", + "view-profile" + ], + "redirectUris": [ + "http://localhost:8080/*" + ], + "webOrigins": [ + "*" + ], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -414,8 +494,9 @@ "serviceAccountsEnabled": false, "publicClient": false, "frontchannelLogout": false, + "protocol": "openid-connect", "attributes": {}, - "fullScopeAllowed": false, + "fullScopeAllowed": true, "nodeReRegistrationTimeout": 0, "protocolMappers": [ { @@ -447,6 +528,21 @@ "jsonType.label": "String" } }, + { + "id": "ab738104-0faa-4f97-a434-4f4ca579f0e6", + "name": "display_name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "userinfo.token.claim": "false", + "user.attribute": "displayName", + "id.token.claim": "false", + "access.token.claim": "true", + "claim.name": "display_name", + "jsonType.label": "String" + } + }, { "id": "24ed7c89-f8c7-4e92-9226-d0ddbbd39427", "name": "given name", @@ -531,6 +627,7 @@ "serviceAccountsEnabled": false, "publicClient": true, "frontchannelLogout": false, + "protocol": "openid-connect", "attributes": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, @@ -630,14 +727,17 @@ "useTemplateMappers": false }, { - "id": "7bebf0ed-21cf-46f1-8391-b427039e3b0f", - "clientId": "broker", - "name": "${client_broker}", + "id": "af11ca0c-3c29-420d-b548-77c4e0310946", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "baseUrl": "/auth/admin/registry/console/index.html", "surrogateAuthRequired": false, "enabled": true, "clientAuthenticatorType": "client-secret", "secret": "d6e4b70a-73b1-49f3-be1b-d8c8bcaeaf6d", - "redirectUris": [], + "redirectUris": [ + "/auth/admin/registry/console/*" + ], "webOrigins": [], "notBefore": 0, "bearerOnly": false, @@ -646,30 +746,27 @@ "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false, - "publicClient": false, + "publicClient": true, "frontchannelLogout": false, + "protocol": "openid-connect", "attributes": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, "protocolMappers": [ { - "id": "e380413b-6132-451c-8ada-b01cb1f4f080", - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": true, - "consentText": "${familyName}", + "id": "cc998d54-0c0d-4682-91a1-a26887585410", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" } }, { - "id": "58ad1a0d-63ba-44b0-aad5-3db59c7ee294", + "id": "99b4648d-a000-4a0c-a124-83892efd627e", "name": "full name", "protocol": "openid-connect", "protocolMapper": "oidc-full-name-mapper", @@ -682,7 +779,7 @@ } }, { - "id": "1f11568d-e26d-4a7e-8482-1bea33ba0828", + "id": "d16456e4-9cdb-49b8-b353-aa83e4ab5a23", "name": "given name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -698,19 +795,7 @@ } }, { - "id": "af585617-b189-46b8-baf3-f4daa00f8f91", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - }, - { - "id": "34786671-894d-4469-908f-e05534295dfb", + "id": "3ecc12b9-a10b-4c9b-80fe-6f18923e92ee", "name": "email", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -726,7 +811,7 @@ } }, { - "id": "799c4eb4-5dc4-4c71-8b7a-77773342ddbf", + "id": "b13c6c52-14ae-4d91-b1eb-7169bf1f50b8", "name": "username", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -740,6 +825,38 @@ "claim.name": "preferred_username", "jsonType.label": "String" } + }, + { + "id": "e55c919f-9a38-44a6-a861-89dff16de470", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${familyName}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + }, + { + "id": "e03f4879-8ae8-400e-a3a9-5f85a2291057", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "consentText": "${locale}", + "config": { + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } } ], "useTemplateConfig": false, @@ -876,9 +993,9 @@ "useTemplateMappers": false }, { - "id": "b52f66a3-0938-4359-820a-888c3b238c71", - "clientId": "realm-management", - "name": "${client_realm-management}", + "id": "7bebf0ed-21cf-46f1-8391-b427039e3b0f", + "clientId": "broker", + "name": "${client_broker}", "surrogateAuthRequired": false, "enabled": true, "clientAuthenticatorType": "client-secret", @@ -886,7 +1003,7 @@ "redirectUris": [], "webOrigins": [], "notBefore": 0, - "bearerOnly": true, + "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, @@ -894,12 +1011,13 @@ "serviceAccountsEnabled": false, "publicClient": false, "frontchannelLogout": false, + "protocol": "openid-connect", "attributes": {}, "fullScopeAllowed": false, "nodeReRegistrationTimeout": 0, "protocolMappers": [ { - "id": "3f508c27-62cb-4bb4-b6e5-873b1e7d5cd2", + "id": "e380413b-6132-451c-8ada-b01cb1f4f080", "name": "family name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -915,23 +1033,20 @@ } }, { - "id": "7319c52b-9c36-471c-ad32-51449ca83eae", - "name": "username", + "id": "58ad1a0d-63ba-44b0-aad5-3db59c7ee294", + "name": "full name", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", + "protocolMapper": "oidc-full-name-mapper", "consentRequired": true, - "consentText": "${username}", + "consentText": "${fullName}", "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" + "userinfo.token.claim": "true" } }, { - "id": "6b7fdd43-6d79-4923-8beb-b4a9531460fd", + "id": "1f11568d-e26d-4a7e-8482-1bea33ba0828", "name": "given name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -947,20 +1062,19 @@ } }, { - "id": "08e2628d-de01-403e-aa8f-d1abcfb4e894", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": true, - "consentText": "${fullName}", + "id": "af585617-b189-46b8-baf3-f4daa00f8f91", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" } }, { - "id": "b54d6668-57e9-4757-af84-36ea030f16cb", + "id": "34786671-894d-4469-908f-e05534295dfb", "name": "email", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -976,15 +1090,19 @@ } }, { - "id": "8d4847c8-f8bb-4f26-b52b-b6203be15169", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, + "id": "799c4eb4-5dc4-4c71-8b7a-77773342ddbf", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": true, + "consentText": "${username}", "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" } } ], @@ -993,56 +1111,47 @@ "useTemplateMappers": false }, { - "id": "af11ca0c-3c29-420d-b548-77c4e0310946", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "baseUrl": "/auth/admin/registry/console/index.html", + "id": "703e065e-a1e2-4185-ad7c-1b1936d8b5f9", + "clientId": "vue-client", + "name": "vue-client", "surrogateAuthRequired": false, "enabled": true, "clientAuthenticatorType": "client-secret", "secret": "ec6b9969-f314-4c41-b8ea-a51616df1e93", - "redirectUris": ["/auth/admin/registry/console/*"], - "webOrigins": [], + "redirectUris": [ + "http://localhost/*", + "http://registry.wolpert.ca:8083/*" + ], + "webOrigins": [ + "*" + ], "notBefore": 0, "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, + "directAccessGrantsEnabled": true, "serviceAccountsEnabled": false, "publicClient": true, "frontchannelLogout": false, - "attributes": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "cc998d54-0c0d-4682-91a1-a26887585410", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - }, - { - "id": "99b4648d-a000-4a0c-a124-83892efd627e", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": true, - "consentText": "${fullName}", - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "saml.authnstatement": "false", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "saml.onetimeuse.condition": "false" + }, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "protocolMappers": [ { - "id": "d16456e4-9cdb-49b8-b353-aa83e4ab5a23", + "id": "6b417f92-5a31-4f32-a061-44f85f52836c", "name": "given name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -1058,67 +1167,76 @@ } }, { - "id": "3ecc12b9-a10b-4c9b-80fe-6f18923e92ee", - "name": "email", + "id": "2aedb708-5345-4cf3-b2c2-a37f604e966b", + "name": "username", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", "consentRequired": true, - "consentText": "${email}", + "consentText": "${username}", "config": { "userinfo.token.claim": "true", - "user.attribute": "email", + "user.attribute": "username", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "email", + "claim.name": "preferred_username", "jsonType.label": "String" } }, { - "id": "b13c6c52-14ae-4d91-b1eb-7169bf1f50b8", - "name": "username", + "id": "532c0a1b-e839-4ffd-8144-07b0d521954f", + "name": "family name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", "consentRequired": true, - "consentText": "${username}", + "consentText": "${familyName}", "config": { "userinfo.token.claim": "true", - "user.attribute": "username", + "user.attribute": "lastName", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "preferred_username", + "claim.name": "family_name", "jsonType.label": "String" } }, { - "id": "e55c919f-9a38-44a6-a861-89dff16de470", - "name": "family name", + "id": "8c95a355-eaf4-4ac7-b7c0-6b015bfd7099", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + }, + { + "id": "651370bb-78a1-469b-bc9c-842cb25def2e", + "name": "email", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", "consentRequired": true, - "consentText": "${familyName}", + "consentText": "${email}", "config": { "userinfo.token.claim": "true", - "user.attribute": "lastName", + "user.attribute": "email", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "family_name", + "claim.name": "email", "jsonType.label": "String" } }, { - "id": "e03f4879-8ae8-400e-a3a9-5f85a2291057", - "name": "locale", + "id": "1de9ac9f-de7b-4377-8da4-f3f50c47126f", + "name": "full name", "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "consentText": "${locale}", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" + "userinfo.token.claim": "true" } } ], @@ -1127,61 +1245,47 @@ "useTemplateMappers": false }, { - "id": "703e065e-a1e2-4185-ad7c-1b1936d8b5f9", - "clientId": "vue-client", - "name": "vue-client", + "id": "b52f66a3-0938-4359-820a-888c3b238c71", + "clientId": "realm-management", + "name": "${client_realm-management}", "surrogateAuthRequired": false, "enabled": true, "clientAuthenticatorType": "client-secret", "secret": "3c486358-220b-4752-baae-6f5ec62310f2", - "redirectUris": [ - "http://registry.wolpert.ca:8083/*", - "http://localhost/*" - ], - "webOrigins": ["*"], + "redirectUris": [], + "webOrigins": [], "notBefore": 0, - "bearerOnly": false, + "bearerOnly": true, "consentRequired": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, + "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false, - "publicClient": true, + "publicClient": false, "frontchannelLogout": false, "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "saml.authnstatement": "false", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "saml.onetimeuse.condition": "false" - }, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, + "attributes": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, "protocolMappers": [ { - "id": "6b417f92-5a31-4f32-a061-44f85f52836c", - "name": "given name", + "id": "3f508c27-62cb-4bb4-b6e5-873b1e7d5cd2", + "name": "family name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", "consentRequired": true, - "consentText": "${givenName}", + "consentText": "${familyName}", "config": { "userinfo.token.claim": "true", - "user.attribute": "firstName", + "user.attribute": "lastName", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "given_name", + "claim.name": "family_name", "jsonType.label": "String" } }, { - "id": "2aedb708-5345-4cf3-b2c2-a37f604e966b", + "id": "7319c52b-9c36-471c-ad32-51449ca83eae", "name": "username", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -1197,35 +1301,36 @@ } }, { - "id": "532c0a1b-e839-4ffd-8144-07b0d521954f", - "name": "family name", + "id": "6b7fdd43-6d79-4923-8beb-b4a9531460fd", + "name": "given name", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", "consentRequired": true, - "consentText": "${familyName}", + "consentText": "${givenName}", "config": { "userinfo.token.claim": "true", - "user.attribute": "lastName", + "user.attribute": "firstName", "id.token.claim": "true", "access.token.claim": "true", - "claim.name": "family_name", + "claim.name": "given_name", "jsonType.label": "String" } }, { - "id": "8c95a355-eaf4-4ac7-b7c0-6b015bfd7099", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, + "id": "08e2628d-de01-403e-aa8f-d1abcfb4e894", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": true, + "consentText": "${fullName}", "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" } }, { - "id": "651370bb-78a1-469b-bc9c-842cb25def2e", + "id": "b54d6668-57e9-4757-af84-36ea030f16cb", "name": "email", "protocol": "openid-connect", "protocolMapper": "oidc-usermodel-property-mapper", @@ -1241,16 +1346,15 @@ } }, { - "id": "1de9ac9f-de7b-4377-8da4-f3f50c47126f", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": true, - "consentText": "${fullName}", + "id": "8d4847c8-f8bb-4f26-b52b-b6203be15169", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" } } ], @@ -1262,36 +1366,22 @@ "clientTemplates": [], "browserSecurityHeaders": { "xContentTypeOptions": "nosniff", + "xRobotsTag": "none", "xFrameOptions": "SAMEORIGIN", - "contentSecurityPolicy": "frame-src 'self'" + "xXSSProtection": "1; mode=block", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" }, "smtpServer": {}, "eventsEnabled": false, - "eventsListeners": ["jboss-logging"], + "eventsListeners": [ + "jboss-logging" + ], "enabledEventTypes": [], "adminEventsEnabled": false, "adminEventsDetailsEnabled": false, "components": { "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - "id": "5be2dea8-f688-4aec-a450-f6c4edd00401", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": ["true"], - "client-uris-must-match": ["true"] - } - }, - { - "id": "0c7fa637-322e-4c37-b73a-d37fc4a0fdbd", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, { "id": "9f3fc2dc-e93a-4812-a176-8e3f49deccc9", "name": "Full Scope Disabled", @@ -1307,29 +1397,34 @@ "subType": "anonymous", "subComponents": {}, "config": { - "max-clients": ["200"] + "max-clients": [ + "200" + ] } }, { - "id": "442a5d32-184b-4d77-8383-6d341576c93e", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", + "id": "5be2dea8-f688-4aec-a450-f6c4edd00401", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", "subType": "anonymous", "subComponents": {}, "config": { - "allowed-protocol-mapper-types": [ - "saml-user-attribute-mapper", - "oidc-usermodel-attribute-mapper", - "saml-user-property-mapper", - "oidc-usermodel-property-mapper", - "oidc-full-name-mapper", - "oidc-address-mapper", - "oidc-sha256-pairwise-sub-mapper", - "saml-role-list-mapper" + "host-sending-registration-request-must-match": [ + "true" ], - "consent-required-for-all-mappers": ["true"] + "client-uris-must-match": [ + "true" + ] } }, + { + "id": "24e86563-cf93-4f3e-ba62-55237ea94eef", + "name": "Allowed Client Templates", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": {} + }, { "id": "0dae4b3a-9b5d-4c28-9818-cb7200f928ee", "name": "Allowed Client Templates", @@ -1346,25 +1441,49 @@ "subComponents": {}, "config": { "allowed-protocol-mapper-types": [ - "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", - "saml-user-property-mapper", + "saml-role-list-mapper", "oidc-usermodel-property-mapper", - "oidc-full-name-mapper", + "saml-user-attribute-mapper", "oidc-address-mapper", - "oidc-sha256-pairwise-sub-mapper", - "saml-role-list-mapper" + "saml-user-property-mapper", + "oidc-full-name-mapper", + "oidc-sha256-pairwise-sub-mapper" ], - "consent-required-for-all-mappers": ["true"] + "consent-required-for-all-mappers": [ + "true" + ] } }, { - "id": "24e86563-cf93-4f3e-ba62-55237ea94eef", - "name": "Allowed Client Templates", - "providerId": "allowed-client-templates", - "subType": "authenticated", + "id": "0c7fa637-322e-4c37-b73a-d37fc4a0fdbd", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", "subComponents": {}, "config": {} + }, + { + "id": "442a5d32-184b-4d77-8383-6d341576c93e", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "saml-user-property-mapper", + "oidc-address-mapper", + "saml-user-attribute-mapper", + "oidc-usermodel-property-mapper", + "oidc-full-name-mapper", + "saml-role-list-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-attribute-mapper" + ], + "consent-required-for-all-mappers": [ + "true" + ] + } } ], "org.keycloak.keys.KeyProvider": [ @@ -1380,7 +1499,20 @@ "certificate": [ "MIICmzCCAYMCBgFTPQ+6VzANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZncmFpbHMwHhcNMTYwMzAzMTUxNzM0WhcNMjYwMzAzMTUxOTE0WjARMQ8wDQYDVQQDDAZncmFpbHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRDZA3hwLFzXQDNvsILi5qzt5+I9k7DBQfKTEsh8e1zw7HDY+SgGtJ4zID+yQJ7AO8wlkeZzZI52cDoOmpnquVd7tHrLMzjK0ciDiKMTj49ii2I/SVRNNOAh/eZu9oCItRNlXWzPhOOZxKT3m/iZvgKypoMwYT7YQ/KnQNbQ0GprKdoThpUq4Y7EkCiwkEFmh0A6W2GkxTn2EvsmoFdAko29CzLGclgeAmctZoZSfwPz5jUwwmBWNKua3Gq//ZyhVpImtGpJiKuf4aZiBEZFH8FTIiKRRE7IYujlj8u1S+5NAzW960eRx3csk/sylaob08PO/HjXYVs/DSwhLMIuBpAgMBAAEwDQYJKoZIhvcNAQELBQADggEBALj8TqkAJFynu8fxmV3CakTPQM6SMTOyviIM0Kns+aT2qeQTrrf2Iglj0naRU3cfv2lbiRDUjIIrA6wKTI7RL8kfXwlIB/eN1Tn/QdGUzW9/Zkzq2sr+YdnyJLWf7zDIDJbvQaStOjR9aIBXZJ4JoYVOatV3Y/OZSDampU7/sYwHdCe1UtdxQzxcOkguRfdJC5/jSTgxjx/OUoN/4i60hJrfhGh/HLrVC180niyg0gOIZjY+VUQzYiXnR1gJiSRrpY3oJdHhHPNQs5lbXoez3jppu78wmQqZWqjeygBT5uBdwJUpuPSNy9FQGpeTZm+UV0QI8w944C7xZtZIVS53DqQ=" ], - "priority": ["100"] + "priority": [ + "100" + ] + } + }, + { + "id": "8fcc06c9-e7b7-4e1a-ba17-d618b79f5e38", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] } }, { @@ -1389,9 +1521,9 @@ "providerId": "hmac-generated", "subComponents": {}, "config": { - "kid": ["bfc10789-857b-48f6-8512-ef0752110944"], - "secret": ["2ePPzy1H4s8Qr_jP-e_MCcso5DtwKuc1S9UtUzCOrqc"], - "priority": ["100"] + "priority": [ + "100" + ] } } ] @@ -1400,7 +1532,7 @@ "supportedLocales": [], "authenticationFlows": [ { - "id": "af8b1160-068b-486a-a81a-57010c8597d9", + "id": "9efee42f-0a19-45b4-b959-fdaee96f0f3b", "alias": "Handle Existing Account", "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", "providerId": "basic-flow", @@ -1431,7 +1563,7 @@ ] }, { - "id": "dc4982cf-2ba6-40d2-bffe-2363d3fbfbf2", + "id": "d1b25912-b6a9-4c8f-b2d9-0e834f7d6bf1", "alias": "Verify Existing Account by Re-authentication", "description": "Reauthentication of existing account", "providerId": "basic-flow", @@ -1455,7 +1587,7 @@ ] }, { - "id": "8988c89f-6767-4f7a-a26e-37877988f731", + "id": "40d90ee1-11d8-438b-807e-f234850cab40", "alias": "browser", "description": "browser based authentication", "providerId": "basic-flow", @@ -1493,7 +1625,7 @@ ] }, { - "id": "68c3e0d3-e91f-43db-ac04-cfd879b6eaa8", + "id": "2393b56b-7b2f-4aff-9ff9-715cc8d16c4c", "alias": "clients", "description": "Base authentication for clients", "providerId": "client-flow", @@ -1517,7 +1649,7 @@ ] }, { - "id": "6737217e-fe50-44ad-a682-ac14c7ddc6a2", + "id": "9c40bbb3-50a7-4391-a2f8-811b3903a954", "alias": "direct grant", "description": "OpenID Connect Resource Owner Grant", "providerId": "basic-flow", @@ -1548,7 +1680,24 @@ ] }, { - "id": "cbaf9a54-6811-4b5a-9a57-2f528cefce81", + "id": "80468827-0db3-4af3-8eff-f34623312a06", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "requirement": "REQUIRED", + "priority": 10, + "userSetupAllowed": false, + "autheticatorFlow": false + } + ] + }, + { + "id": "7fba12e2-32be-4da4-8247-2cf0ea8bcc19", "alias": "first broker login", "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", "providerId": "basic-flow", @@ -1581,7 +1730,7 @@ ] }, { - "id": "6c7ca63d-8616-4a07-944b-cb987d6968d4", + "id": "028360b1-9331-4450-9f17-ab1171ad6579", "alias": "forms", "description": "Username, password, otp and other auth forms.", "providerId": "basic-flow", @@ -1605,7 +1754,7 @@ ] }, { - "id": "2d76cb85-bbdd-49af-ab70-919de8aefa30", + "id": "af6718e6-1f12-4f47-96a6-72a97b6c770f", "alias": "registration", "description": "registration flow", "providerId": "basic-flow", @@ -1623,7 +1772,7 @@ ] }, { - "id": "9fd9ed04-492b-4177-81f3-dfd61df98f83", + "id": "75ee3b3e-b753-41a1-b90e-997fd81edc8d", "alias": "registration form", "description": "registration form", "providerId": "form-flow", @@ -1661,7 +1810,7 @@ ] }, { - "id": "9453229e-f122-4c2c-b36d-30402e3c4659", + "id": "f839aa65-9f81-4124-a248-19307c97d0a7", "alias": "reset credentials", "description": "Reset credentials for a user if they forgot their password or something", "providerId": "basic-flow", @@ -1699,7 +1848,7 @@ ] }, { - "id": "0e965304-9dba-4d64-a507-3f6c3242ed0f", + "id": "21bc71a9-cc19-42cf-9171-fc89d4c517d2", "alias": "saml ecp", "description": "SAML ECP Profile Authentication Flow", "providerId": "basic-flow", @@ -1718,14 +1867,14 @@ ], "authenticatorConfig": [ { - "id": "2714a0ad-6ad4-495c-af1b-64596d64f05e", + "id": "95a9cfba-ee8d-4544-9855-4504f38840cc", "alias": "create unique user config", "config": { "require.password.update.after.registration": "false" } }, { - "id": "1ed48f70-3a22-48b9-9995-d2bf77506df7", + "id": "03b79da1-4335-4cc7-9dea-b90c8875e370", "alias": "review profile config", "config": { "update.profile.on.first.login": "missing" @@ -1779,17 +1928,24 @@ "directGrantFlow": "direct grant", "resetCredentialsFlow": "reset credentials", "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", "attributes": { + "_browser_header.xXSSProtection": "1; mode=block", "_browser_header.xFrameOptions": "SAMEORIGIN", - "failureFactor": "30", + "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains", + "permanentLockout": "false", "quickLoginCheckMilliSeconds": "1000", + "_browser_header.xRobotsTag": "none", + "maxFailureWaitSeconds": "900", + "minimumQuickLoginWaitSeconds": "60", + "failureFactor": "30", + "actionTokenGeneratedByUserLifespan": "300", "maxDeltaTimeSeconds": "43200", "_browser_header.xContentTypeOptions": "nosniff", + "actionTokenGeneratedByAdminLifespan": "43200", "bruteForceProtected": "false", - "maxFailureWaitSeconds": "900", - "_browser_header.contentSecurityPolicy": "frame-src 'self'", - "minimumQuickLoginWaitSeconds": "60", + "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", "waitIncrementSeconds": "60" }, - "keycloakVersion": "3.0.0.Final" -} + "keycloakVersion": "3.4.3.Final" +} \ No newline at end of file From cf5ddb8b95830c8383bc027b134dc2818baa4271 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 25 May 2020 13:11:47 -0700 Subject: [PATCH 8/8] Adding sort to time slots after slot calculation --- api/app/services/availability_service.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/app/services/availability_service.py b/api/app/services/availability_service.py index a05b43fd4..86d63f24e 100644 --- a/api/app/services/availability_service.py +++ b/api/app/services/availability_service.py @@ -76,6 +76,9 @@ def get_available_slots(office: Office, days: [datetime], format_time: bool = Tr end_time = add_delta_to_time(end_time, minutes=appointment_duration, timezone=office.timezone.timezone_name) + # Sort the slot by time for the day + available_slots_per_day[formatted_date].sort(key=lambda x: x['start_time']) + # Check if the slots are already booked for actual_slot in available_slots_per_day[formatted_date]: for booked_slot in grouped_appointments.get(formatted_date, []): @@ -134,7 +137,6 @@ def group_appointments(appointments, timezone: str): }) return filtered_appointments - @staticmethod def prune_appointments(available_slots_per_day: Dict): for key, slots in available_slots_per_day.items():