Commit af5c5105 authored by Dimitrios Gogos's avatar Dimitrios Gogos
Browse files

feat: customize login screen based on our theme

parent 2f61a707
Loading
Loading
Loading
Loading
+24 −0
Changes for oop-platform-chart/charts/keycloak/README.md: 24 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ All in the platform namespace (`oop`):
| Init container | `wait-for-database` | Waits until the `keycloak` database accepts logins, because Keycloak exits if it cannot reach it. |
| Service | `keycloak` | Port 8080. The umbrella chart makes it a NodePort (30081) so browsers can reach it. |
| ConfigMap | `keycloak-realms` | The realm JSON files (`oop.json`, `federation.json`) imported on first start. |
| ConfigMap | `keycloak-theme` | The `oop` login theme, mounted at `/opt/keycloak/themes/oop` ([section 14](#change-the-login-page)). |
| Secret | `keycloak-credentials` | Every generated password and client secret ([section 10](#10-secrets-and-passwords)). |

Health endpoints are on port 9000: `/health/started`, `/health/ready`, `/health/live`.
@@ -131,6 +132,7 @@ Where things are defined:
| Realm JSON (roles, clients, users, token mappers) | [`templates/realms-configmap.yaml`](templates/realms-configmap.yaml) |
| User profile (which fields a user has) | `keycloak.oop.userProfile` in [`templates/_helpers.tpl`](templates/_helpers.tpl) |
| Environment variables and startup | [`templates/deployment.yaml`](templates/deployment.yaml) |
| Login page look (logo, background, colours, texts) | [`themes/oop/login`](themes/oop/login) |
| Platform-wide settings (`global.*`) | [`../../values.yaml`](../../values.yaml) |

## 5. Realm `oop`: people
@@ -197,6 +199,7 @@ unless Keycloak's public URL is `http://localhost[:port]` or `http://127.0.0.1[:
| Login with email | on | People may type their email instead of their username. |
| Email verification | off | There is no mail server. |
| Forgot password | the link stays, but the text says "ask your administrator" | No mail server, so no reset emails. An admin resets it ([section 14](#reset-a-password)). |
| Login theme | `oop` | The Portal's colours, font and square corners, with the OpenOP logo and a photo panel on wide screens. |
| Brute-force protection | on | Locks an account temporarily after repeated wrong passwords. |
| Require SSL | `external` | HTTPS is required except from private addresses (localhost, 10.x, 192.168.x, …). |
| Access token lifetime | 5 minutes | A stolen token is useless quickly; the Portal refreshes it. |
@@ -411,6 +414,7 @@ Every token's `iss` is built from the **public URL**, even when a pod fetched it
| `global.federation.audience` | `federation-manager` | Audience in partner tokens. |
| `keycloak.hostname` | `""` | Overrides the public URL, e.g. behind an ingress. |
| `keycloak.admin.password` | `""` (generated) | Keycloak admin password on first start. |
| `keycloak.theme.enabled` | `true` | Mount the `oop` login theme and import realm `oop` with it. |
| `keycloak.realms.oop.settings.*` | see [section 5](#realm-settings-worth-knowing) | Token lifetimes, SSL, brute force. |
| `keycloak.realms.oop.portal.baseUrl` | `""` (derived) | Portal URL used for login redirects. |
| `keycloak.realms.oop.initialAdmin.enabled` | `true` | Create `oop-admin`. |
@@ -505,6 +509,26 @@ chart are ignored. You have two options:
  **Realm settings** → **Action** (top right) → **Delete**, then
  `kubectl -n oop rollout restart deployment/keycloak`. The realm is imported again from the chart.

### Change the login page

The login, registration and password pages use the `oop` theme in [`themes/oop/login`](themes/oop/login).
It extends Keycloak's own `keycloak.v2` theme with CSS only, so Keycloak upgrades keep working:

| To change | Edit |
|---|---|
| Colours, font, spacing | the tokens at the top of `resources/css/oop.css`, copied from the Portal's `src/index.css` |
| Logo | `resources/img/logo.png` and `logo-dark.png` (dark mode) |
| Photo panel | `resources/img/background.webp` |
| Texts | `messages/messages_en.properties`, using keys from Keycloak's `messages_en.properties` |

Dark mode follows the operating system, since Keycloak cannot read the Portal's own theme choice.
The files travel in a ConfigMap, which Kubernetes caps at 1 MiB and Helm's release record at
about the same, so keep images small: the whole theme is about 210 KB.

`helm upgrade` restarts Keycloak when a theme file changes. A realm created before the theme
existed keeps its old look until you pick it: admin console → realm `oop` → **Realm settings** →
**Themes** → **Login theme** → `oop` → **Save**.

## 15. Troubleshooting

| What you see | Likely cause | What to do |
+8 −0
Changes for oop-platform-chart/charts/keycloak/templates/_helpers.tpl: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -11,6 +11,14 @@ app.kubernetes.io/managed-by: {{ .Release.Service }}
{{ include "keycloak.selectorLabels" . }}
{{- end }}

{{/*
ConfigMap key for a file under themes/oop: keys cannot hold "/", so the path is flattened and
the volume's items map each key back to its path.
*/}}
{{- define "keycloak.themeKey" -}}
{{- trimPrefix "themes/oop/" . | replace "/" "__" -}}
{{- end }}

{{/*
Selector labels
*/}}
+20 −0
Changes for oop-platform-chart/charts/keycloak/templates/deployment.yaml: 20 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@ spec:
    metadata:
      labels:
        {{- include "keycloak.labels" . | nindent 8 }}
      {{- if .Values.theme.enabled }}
      annotations:
        # Keycloak caches themes in production mode, so a theme change needs a restart.
        checksum/theme: {{ include (print $.Template.BasePath "/theme-configmap.yaml") . | sha256sum }}
      {{- end }}
    spec:
      initContainers:
        # Keycloak exits if its database is missing; the postgresql chart creates it in a
@@ -148,8 +153,23 @@ spec:
            - name: realms
              mountPath: /opt/keycloak/data/import
              readOnly: true
            {{- if .Values.theme.enabled }}
            - name: theme
              mountPath: /opt/keycloak/themes/oop
              readOnly: true
            {{- end }}
      volumes:
        - name: realms
          configMap:
            name: {{ .Values.name }}-realms
        {{- if .Values.theme.enabled }}
        - name: theme
          configMap:
            name: {{ .Values.name }}-theme
            items:
              {{- range $path, $_ := .Files.Glob "themes/oop/**" }}
              - key: {{ include "keycloak.themeKey" $path }}
                path: {{ trimPrefix "themes/oop/" $path }}
              {{- end }}
        {{- end }}
{{- end }}
+3 −0
Changes for oop-platform-chart/charts/keycloak/templates/realms-configmap.yaml: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ data:
      "enabled": true,
      "displayName": {{ .displayName | toJson }},
      "sslRequired": {{ .settings.sslRequired | toJson }},
      {{- if $.Values.theme.enabled }}
      "loginTheme": "oop",
      {{- end }}
      "registrationAllowed": true,
      "registrationEmailAsUsername": false,
      "loginWithEmailAllowed": true,
+13 −0
Changes for oop-platform-chart/charts/keycloak/templates/theme-configmap.yaml: 13 added lines, 0 removed lines.
Original line number Diff line number Diff line
{{- if and (include "keycloak.authEnabled" .) .Values.theme.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.name }}-theme
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "keycloak.labels" . | nindent 4 }}
binaryData:
  {{- range $path, $_ := .Files.Glob "themes/oop/**" }}
  {{ include "keycloak.themeKey" $path }}: {{ $.Files.Get $path | b64enc }}
  {{- end }}
{{- end }}
Loading