From 3cbfaab10e7ed9516c823322d06d43c820bdd2d1 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:31:28 +0200 Subject: [PATCH] feat: customize OIDC login page --- .github/workflows/cd.yml | 12 +- .github/workflows/ci.yml | 1 + .github/workflows/deploy.yml | 3 + docker-compose.override.yml | 21 ++++ docker-compose.prod.yml | 1 + docker-compose.yml | 17 +-- helm/api-platform/keycloak/Dockerfile | 18 +++ .../keycloak/config/realm-demo.json | 1 + .../themes/api-platform-demo/login/login.ftl | 112 ++++++++++++++++++ .../api-platform-demo/login/theme.properties | 2 + helm/api-platform/values.yaml | 5 +- pwa/tests/User.spec.ts | 11 ++ 12 files changed, 184 insertions(+), 20 deletions(-) create mode 100644 helm/api-platform/keycloak/Dockerfile create mode 100644 helm/api-platform/keycloak/themes/api-platform-demo/login/login.ftl create mode 100644 helm/api-platform/keycloak/themes/api-platform-demo/login/theme.properties diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 2bb66d4b6..48f4aaf51 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -16,8 +16,9 @@ jobs: runs-on: ubuntu-latest env: PHP_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/php:${{ github.sha }} - CADDY_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:${{ github.sha }} PWA_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/pwa:${{ github.sha }} + CADDY_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:${{ github.sha }} + KEYCLOAK_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/keycloak:${{ github.sha }} steps: - name: Checkout @@ -62,17 +63,20 @@ jobs: name: Docker tag latest run: | docker tag $PHP_DOCKER_IMAGE eu.gcr.io/${{ secrets.GKE_PROJECT }}/php:latest - docker tag $CADDY_DOCKER_IMAGE eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:latest docker tag $PWA_DOCKER_IMAGE eu.gcr.io/${{ secrets.GKE_PROJECT }}/pwa:latest + docker tag $CADDY_DOCKER_IMAGE eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:latest + docker tag $KEYCLOAK_DOCKER_IMAGE eu.gcr.io/${{ secrets.GKE_PROJECT }}/keycloak:latest - name: Docker push run: | docker push $PHP_DOCKER_IMAGE docker push eu.gcr.io/${{ secrets.GKE_PROJECT }}/php:latest - docker push $CADDY_DOCKER_IMAGE - docker push eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:latest docker push $PWA_DOCKER_IMAGE docker push eu.gcr.io/${{ secrets.GKE_PROJECT }}/pwa:latest + docker push $CADDY_DOCKER_IMAGE + docker push eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:latest + docker push $KEYCLOAK_DOCKER_IMAGE + docker push eu.gcr.io/${{ secrets.GKE_PROJECT }}/keycloak:latest deploy: name: Deploy diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 509b2e915..b2946c38e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,7 @@ jobs: PHP_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/php:latest PWA_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/pwa:latest CADDY_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/caddy:latest + KEYCLOAK_DOCKER_IMAGE: eu.gcr.io/${{ secrets.GKE_PROJECT }}/keycloak:latest APP_SECRET: ba63418865d58089f7f070e0a437b6d16b1fb970 CADDY_MERCURE_JWT_SECRET: 33b04d361e437e0d7d715600fc24fdefba317154 NEXTAUTH_SECRET: 77e4c3f5a6fb652b6245a5df8a704e04ad90bc7e diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f3f03233b..37da1b6bb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -111,6 +111,9 @@ jobs: --wait \ --namespace=${{ inputs.namespace }} \ --set=app.version=${{ github.sha }} \ + --set=keycloak.image.repository=eu.gcr.io/${{ secrets.gke-project }}/keycloak \ + --set=keycloak.image.tag=${{ inputs.docker-images-version }} \ + --set=keycloak.image.pullPolicy=Always \ --set=keycloak.auth.adminPassword=${{ secrets.keycloak-admin-password }} \ --set=keycloak.extraEnvVars[0].name=KC_HOSTNAME_URL \ --set-string=keycloak.extraEnvVars[0].value=https://${{ inputs.url }}/oidc/ \ diff --git a/docker-compose.override.yml b/docker-compose.override.yml index b7b3277e7..da266ed43 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -53,3 +53,24 @@ services: ###> symfony/mercure-bundle ### ###< symfony/mercure-bundle ### + + keycloak: + build: + context: ./helm/api-platform/keycloak/ + target: keycloak + volumes: + - ./helm/api-platform/keycloak/themes/api-platform-demo:/opt/bitnami/keycloak/themes/api-platform-demo + + keycloak-config-cli: + image: bitnami/keycloak-config-cli:5-debian-11 + environment: + KEYCLOAK_URL: http://caddy/oidc/ + KEYCLOAK_USER: ${KEYCLOAK_ADMIN_USER:-admin} + KEYCLOAK_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-!ChangeMe!} + KEYCLOAK_AVAILABILITYCHECK_ENABLED: true + KEYCLOAK_AVAILABILITYCHECK_TIMEOUT: 120s + IMPORT_FILES_LOCATIONS: "/config/*" + depends_on: + - keycloak + volumes: + - ./helm/api-platform/keycloak/config:/config diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 51b878b40..837995596 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -45,6 +45,7 @@ services: POSTGRES_PASSWORD: ${KEYCLOAK_POSTGRES_PASSWORD} keycloak: + image: ${KEYCLOAK_DOCKER_IMAGE} environment: KEYCLOAK_PRODUCTION: "true" KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} diff --git a/docker-compose.yml b/docker-compose.yml index dc676cb33..d6181dbca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -94,7 +94,7 @@ services: - keycloak_db_data:/var/lib/postgresql/data keycloak: - image: bitnami/keycloak:${KEYCLOAK_VERSION:-21-debian-11} + image: app_keycloak environment: KEYCLOAK_DATABASE_HOST: keycloak-database KEYCLOAK_DATABASE_NAME: ${KEYCLOAK_POSTGRES_DB:-keycloak} @@ -106,6 +106,7 @@ services: KEYCLOAK_HTTP_RELATIVE_PATH: /oidc/ # https://www.keycloak.org/server/hostname KC_HOSTNAME_URL: https://${SERVER_NAME:-localhost}/oidc/ + KC_HOSTNAME_ADMIN_URL: https://${SERVER_NAME:-localhost}/oidc/ depends_on: - keycloak-database ports: @@ -113,20 +114,6 @@ services: published: 8080 protocol: tcp - keycloak-config-cli: - image: bitnami/keycloak-config-cli:5-debian-11 - environment: - KEYCLOAK_URL: http://caddy/oidc/ - KEYCLOAK_USER: ${KEYCLOAK_ADMIN_USER:-admin} - KEYCLOAK_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-!ChangeMe!} - KEYCLOAK_AVAILABILITYCHECK_ENABLED: true - KEYCLOAK_AVAILABILITYCHECK_TIMEOUT: 120s - IMPORT_FILES_LOCATIONS: "/config/*" - depends_on: - - keycloak - volumes: - - ./helm/api-platform/keycloak/config:/config - volumes: php_socket: caddy_data: diff --git a/helm/api-platform/keycloak/Dockerfile b/helm/api-platform/keycloak/Dockerfile new file mode 100644 index 000000000..75503a37a --- /dev/null +++ b/helm/api-platform/keycloak/Dockerfile @@ -0,0 +1,18 @@ +#syntax=docker/dockerfile:1.4 + + + + +# Versions +FROM bitnami/keycloak:22-debian-11 AS keycloak_upstream + + +# The different stages of this Dockerfile are meant to be built into separate images +# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage +# https://docs.docker.com/compose/compose-file/#target + + +# Keycloak image +FROM keycloak_upstream AS keycloak + +COPY --link themes/api-platform-demo /opt/bitnami/keycloak/themes/api-platform-demo diff --git a/helm/api-platform/keycloak/config/realm-demo.json b/helm/api-platform/keycloak/config/realm-demo.json index 720c2ca81..e6e99092a 100755 --- a/helm/api-platform/keycloak/config/realm-demo.json +++ b/helm/api-platform/keycloak/config/realm-demo.json @@ -4,6 +4,7 @@ "enabled": true, "registrationAllowed": false, "accessCodeLifespan": 1, + "loginTheme": "api-platform-demo", "users": [ { "username": "chuck.norris", diff --git a/helm/api-platform/keycloak/themes/api-platform-demo/login/login.ftl b/helm/api-platform/keycloak/themes/api-platform-demo/login/login.ftl new file mode 100644 index 000000000..6559a36a3 --- /dev/null +++ b/helm/api-platform/keycloak/themes/api-platform-demo/login/login.ftl @@ -0,0 +1,112 @@ +<#import "template.ftl" as layout> +<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section> + <#if section = "header"> + ${msg("loginAccountTitle")} + <#elseif section = "form"> +