From 51200fa7b492c96150ffbe395c24e56c57fbacff Mon Sep 17 00:00:00 2001
From: Alexander Ungefug <82446024+AlexanderUngefug@users.noreply.github.com>
Date: Thu, 28 Nov 2024 11:18:14 +0100
Subject: [PATCH 1/7] SPSH-1496 (#89)

* add error handling if user is found in privcyIDea

* handle: Authentication failed. The user has no tokens assigned

* change text
---
 .../schulportal/login/messages/messages_de.properties      | 7 ++++---
 src/themes/schulportal/login/template.ftl                  | 4 +++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/themes/schulportal/login/messages/messages_de.properties b/src/themes/schulportal/login/messages/messages_de.properties
index 09c75ee..153577c 100644
--- a/src/themes/schulportal/login/messages/messages_de.properties
+++ b/src/themes/schulportal/login/messages/messages_de.properties
@@ -6,7 +6,7 @@ help=Hilfe
 legalNotice=Impressum
 loginAccountTitle=Anmeldung
 passwordConfirm=Neues Passwort erneut eingeben
-passwordHelpText=Passwort vergessen?<br>Wenden Sie sich bitte an Ihre schulischen Administratorinnen und Administratoren.
+passwordHelpText=Passwort vergessen?<br>Wenden Sie sich an Ihre schulischen Administratorinnen und Administratoren.
 passwordNew=Neues Passwort eingeben
 passwordUpdatePrompt=Bitte legen Sie ein neues, selbstgewähltes Passwort fest.
 privacyPolicy=Datenschutzerklärung
@@ -18,7 +18,7 @@ accountDisabledMessage=Ihr Benutzerkonto ist gesperrt. Bitte wenden Sie sich an
 authenticationOtpFailedMessage=Ungültiges Einmalpasswort. Bitte versuchen Sie es erneut oder wenden Sie sich an Ihre schulischen Administratorinnen oder Administratoren.
 authenticationFailedMessage=Leider gibt es technische Probleme bei der Zweifaktor-Authentifizierung. Bitte versuchen Sie es zu einem späteren Zeitpunkt erneut. Falls das Problem bestehen bleibt, wenden Sie sich bitte an Ihre schulischen Administratorinnen und Administratoren.
 authenticationOtpUsedAgainFailedMessage=Zwei-Faktor-Authentifizierung fehlgeschlagen: Das eingegebene OTP wurde bereits verwendet. Bitte warten Sie auf das nächste OTP und versuchen Sie es erneut.
-authenticationFailedFailcounterExceededMessage=Zwei-Faktor-Authentifizierung fehlgeschlagen: Die erlaubte Anzahl fehlgeschlagener Versuche wurde überschritten. Ihr Token ist gesperrt. Bitte wenden Sie sich an Ihre schulischen Administratorinnen und Administratoren., um einen neuen Token zu erstellen.
+authenticationFailedFailcounterExceededMessage=Zwei-Faktor-Authentifizierung fehlgeschlagen: Die erlaubte Anzahl fehlgeschlagener Versuche wurde überschritten. Ihr Token ist gesperrt. Bitte wenden Sie sich an Ihre schulischen Administratorinnen und Administratoren, um einen neuen Token zu erstellen.
 title=Schulportal SH
 mindPasswordGuidelines=Bitte beachten Sie die untenstehenden Vorgaben.
 passwordRequirementsTitle=Das Passwort muss folgende Vorgaben erfüllen:
@@ -29,4 +29,5 @@ passwordRequirementUpper=Mindestens 1 Großbuchstaben enthalten
 passwordRequirementDigit=Mindestens 1 Ziffer enthalten
 passwordRequirementHistory=Nicht dem bisherigen Passwort entsprechen
 passwordRequirementNoWhitespace=Keine Leerzeichen enthalten
-systemStatus=Systemstatus
\ No newline at end of file
+systemStatus=Systemstatus
+userNotFound=Diese Aktion setzt eine Zweifaktor-Authentifizierung (2FA) voraus. Bitte melden Sie sich im Schulportal an und richten dort eine 2FA ein oder wenden Sie sich an Ihre schulischen Administratorinnen und Administratoren.
\ No newline at end of file
diff --git a/src/themes/schulportal/login/template.ftl b/src/themes/schulportal/login/template.ftl
index 32a173f..7028536 100644
--- a/src/themes/schulportal/login/template.ftl
+++ b/src/themes/schulportal/login/template.ftl
@@ -137,7 +137,9 @@
                 "UngültigesPasswort:Esmussmindestens8Zeichenlangsein." : msg("mindPasswordGuidelines"),
                 "UngültigesPasswort:Esmussmindestens1Zahl(en)beinhalten." : msg("mindPasswordGuidelines"),
                 "UngültigesPasswort:Esdarfnichteinemderletzten3Passwörterentsprechen." : msg("mindPasswordGuidelines"),
-                "UngültigesPasswort:EsentsprichtnichtdemRegex-Muster." : msg("mindPasswordGuidelines")
+                "UngültigesPasswort:EsentsprichtnichtdemRegex-Muster." : msg("mindPasswordGuidelines"),
+                "ERR904:Theusercannotbefoundinanyresolverinthisrealm!" : msg("userNotFound"),
+                "Authenticationfailed.Theuserhasnotokensassigned" : msg("userNotFound")
             }>
     
             <div id="kc-content">

From 1ce0d26f3dc0810b07653a77184c9517a15a1de2 Mon Sep 17 00:00:00 2001
From: "Marvin Rode (Cap)" <127723478+marode-cap@users.noreply.github.com>
Date: Fri, 29 Nov 2024 10:29:58 +0100
Subject: [PATCH 2/7] SPSH-1530 Load certificates from 1password (#91)

* Load certificate from 1password
---
 charts/dbildungs-iam-keycloak/dev-realm-spsh.json       | 2 +-
 charts/dbildungs-iam-keycloak/prod-realm-spsh.json      | 2 +-
 charts/dbildungs-iam-keycloak/templates/deployment.yaml | 5 +++++
 charts/dbildungs-iam-keycloak/templates/secret.yaml     | 1 +
 charts/dbildungs-iam-keycloak/values.yaml               | 1 +
 5 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/charts/dbildungs-iam-keycloak/dev-realm-spsh.json b/charts/dbildungs-iam-keycloak/dev-realm-spsh.json
index dfabf84..3596dd6 100644
--- a/charts/dbildungs-iam-keycloak/dev-realm-spsh.json
+++ b/charts/dbildungs-iam-keycloak/dev-realm-spsh.json
@@ -853,7 +853,7 @@
           "oidc.ciba.grant.enabled": "false",
           "client.secret.creation.time": "1727357679",
           "backchannel.logout.session.required": "true",
-          "jwt.credential.certificate": "MIICpzCCAY8CBgGSudz1xDANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxzcHNoLXNlcnZpY2UwHhcNMjQxMDIzMTQ1MDE4WhcNMzQxMDIzMTQ1MTU4WjAXMRUwEwYDVQQDDAxzcHNoLXNlcnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4+xc3VFrYv+1A5Eoa+7firuYN/+3FwoLKSYAe68FQrPTDA27qyTdtPwbZfYe33lxREq7YgAF0T9qGVShXQrQqv+vvf0IDBdsTWd2UbEnJ02vj0CvDKV+1bFBWQt2Ead7MF6Wsw0HbK1tWMlvdZZl7YwypH8uHmXtGvdnnYNCLzJYPEWU4so6CPVAB89cTdspceYGg9HUnoWKv7IklAL/fJfJ/IWO/D/tEmPqM5taONuQmnwmYFhXMFAVRu32uixIYXNzr8Tw9w5naHIjENib83OtiqwidZrGbL7djNidIIs0XOzTxRlOzJ/+ajvUUQJLEQPEpjyd0QFEk2RshtcD9AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGsR/rbVu+Yf0rvYsfz59etjNoEtTq8l4jbDMChJRnanLHJvAxqHl0co1m+MbxTYB+l2cnqS6tpwea0LfKICXAamMScxe8dcq86DHV8RFOpWLszZgxFuPNplVxZxWde2AhwxCTz/wF2bPllJGc8mxJK0DJkuC50zh9yXQ6XFfwT9qTVAvqv3aEEKidmY3uDxRYFnzmLzqu7ac+Q3e/AWtP+PCQ+vmSJaSK4Uyn21wu3VN+1Gb8clPVI2pkNypSExq/OeS6g1BZy6Sng9mxG42602RLQj7QwK4GQHxYqMCEagf2W1OzC9pt+kGGg0JlN1kxeodiKLvU/Q8zWGCURWY30=",
+          "jwt.credential.certificate": "${KC_SERVICE_CLIENT_CERTIFICATE}",
           "oauth2.device.authorization.grant.enabled": "false",
           "display.on.consent.screen": "false",
           "backchannel.logout.revoke.offline.tokens": "false"
diff --git a/charts/dbildungs-iam-keycloak/prod-realm-spsh.json b/charts/dbildungs-iam-keycloak/prod-realm-spsh.json
index 8814877..1e3a884 100644
--- a/charts/dbildungs-iam-keycloak/prod-realm-spsh.json
+++ b/charts/dbildungs-iam-keycloak/prod-realm-spsh.json
@@ -851,7 +851,7 @@
           "oidc.ciba.grant.enabled": "false",
           "client.secret.creation.time": "1727357679",
           "backchannel.logout.session.required": "true",
-          "jwt.credential.certificate": "MIICpzCCAY8CBgGSudz1xDANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxzcHNoLXNlcnZpY2UwHhcNMjQxMDIzMTQ1MDE4WhcNMzQxMDIzMTQ1MTU4WjAXMRUwEwYDVQQDDAxzcHNoLXNlcnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4+xc3VFrYv+1A5Eoa+7firuYN/+3FwoLKSYAe68FQrPTDA27qyTdtPwbZfYe33lxREq7YgAF0T9qGVShXQrQqv+vvf0IDBdsTWd2UbEnJ02vj0CvDKV+1bFBWQt2Ead7MF6Wsw0HbK1tWMlvdZZl7YwypH8uHmXtGvdnnYNCLzJYPEWU4so6CPVAB89cTdspceYGg9HUnoWKv7IklAL/fJfJ/IWO/D/tEmPqM5taONuQmnwmYFhXMFAVRu32uixIYXNzr8Tw9w5naHIjENib83OtiqwidZrGbL7djNidIIs0XOzTxRlOzJ/+ajvUUQJLEQPEpjyd0QFEk2RshtcD9AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGsR/rbVu+Yf0rvYsfz59etjNoEtTq8l4jbDMChJRnanLHJvAxqHl0co1m+MbxTYB+l2cnqS6tpwea0LfKICXAamMScxe8dcq86DHV8RFOpWLszZgxFuPNplVxZxWde2AhwxCTz/wF2bPllJGc8mxJK0DJkuC50zh9yXQ6XFfwT9qTVAvqv3aEEKidmY3uDxRYFnzmLzqu7ac+Q3e/AWtP+PCQ+vmSJaSK4Uyn21wu3VN+1Gb8clPVI2pkNypSExq/OeS6g1BZy6Sng9mxG42602RLQj7QwK4GQHxYqMCEagf2W1OzC9pt+kGGg0JlN1kxeodiKLvU/Q8zWGCURWY30=",
+          "jwt.credential.certificate": "${KC_SERVICE_CLIENT_CERTIFICATE}",
           "oauth2.device.authorization.grant.enabled": "false",
           "display.on.consent.screen": "false",
           "backchannel.logout.revoke.offline.tokens": "false"
diff --git a/charts/dbildungs-iam-keycloak/templates/deployment.yaml b/charts/dbildungs-iam-keycloak/templates/deployment.yaml
index 50d66b5..9e0dc03 100644
--- a/charts/dbildungs-iam-keycloak/templates/deployment.yaml
+++ b/charts/dbildungs-iam-keycloak/templates/deployment.yaml
@@ -80,6 +80,11 @@ spec:
                 secretKeyRef:
                   name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
                   key: keycloak-adminSecret
+            - name: KC_SERVICE_CLIENT_CERTIFICATE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
+                  key: keycloak-serviceClientCertificate
             - name: KC_ITSLEARNING_CLIENT_SECRET
               valueFrom:
                 secretKeyRef:
diff --git a/charts/dbildungs-iam-keycloak/templates/secret.yaml b/charts/dbildungs-iam-keycloak/templates/secret.yaml
index fa32c7e..42f2d43 100644
--- a/charts/dbildungs-iam-keycloak/templates/secret.yaml
+++ b/charts/dbildungs-iam-keycloak/templates/secret.yaml
@@ -11,6 +11,7 @@ data:
   db-password: {{ .Values.database.password }}
   keycloak-adminSecret: {{ .Values.auth.keycloak_adminSecret }}
   keycloak-clientSecret: {{ .Values.auth.keycloak_clientSecret }}
+  keycloak-serviceClientCertificate: {{ .Values.auth.keycloak_serviceClientCertificate }}
   keycloak-itslearning-clientSecret: {{ .Values.auth.keycloak_itslearning_clientSecret }}
   keycloak-ox-clientSecret: {{ .Values.auth.keycloak_ox_clientSecret }}  
   pi-admin-password: {{ .Values.auth.pi_admin_password }}
diff --git a/charts/dbildungs-iam-keycloak/values.yaml b/charts/dbildungs-iam-keycloak/values.yaml
index 86072ca..e7406cd 100644
--- a/charts/dbildungs-iam-keycloak/values.yaml
+++ b/charts/dbildungs-iam-keycloak/values.yaml
@@ -16,6 +16,7 @@ auth:
   admin_user: ""
   keycloak_adminSecret: ""
   keycloak_clientSecret: ""
+  keycloak_serviceClientCertificate: ""
   keycloak_itslearning_clientSecret: ""
   keycloak_ox_clientSecret: ""
   keycloak_nextcloud_clientId: ""

From 2f793eb0b556dc167ff937e9f418ff21c2c42ea3 Mon Sep 17 00:00:00 2001
From: "Marvin Rode (Cap)" <127723478+marode-cap@users.noreply.github.com>
Date: Fri, 29 Nov 2024 10:32:07 +0100
Subject: [PATCH 3/7] SPSH-1307 SchoolSH client and realm keys (RELEASE) (#88)

* Client for school-sh

* Use full URLs

* Add to configmap

* Replace dashes with underscores

* Switch to manual provider

* Fix typo

* cleanup

* Accidental space

* Update prod realm

* Switch to invalid TLD for dev

* Add client ID
---
 .../dev-realm-spsh.json                       | 85 ++++++++++++++++++-
 .../prod-realm-spsh.json                      | 85 ++++++++++++++++++-
 .../templates/configmap.yaml                  |  2 +
 .../templates/deployment.yaml                 | 25 ++++++
 .../templates/secret.yaml                     |  5 ++
 charts/dbildungs-iam-keycloak/values.yaml     | 10 +++
 6 files changed, 208 insertions(+), 4 deletions(-)

diff --git a/charts/dbildungs-iam-keycloak/dev-realm-spsh.json b/charts/dbildungs-iam-keycloak/dev-realm-spsh.json
index 3596dd6..898e2ee 100644
--- a/charts/dbildungs-iam-keycloak/dev-realm-spsh.json
+++ b/charts/dbildungs-iam-keycloak/dev-realm-spsh.json
@@ -1445,6 +1445,72 @@
           "configure": true,
           "manage": true
         }
+      },
+      {
+        "id": "dd986a17-44c7-4ec9-87f6-addf1646ecf0",
+        "clientId": "${KC_SCHOOLSH_CLIENT_ID}",
+        "name": "School-SH",
+        "description": "",
+        "rootUrl": "${KC_SCHOOLSH_CLIENT_ROOT_URL}",
+        "adminUrl": "",
+        "baseUrl": "",
+        "surrogateAuthRequired": false,
+        "enabled": true,
+        "alwaysDisplayInConsole": false,
+        "clientAuthenticatorType": "client-secret",
+        "secret": "${KC_SCHOOLSH_CLIENT_SECRET}",
+        "redirectUris": [
+          "/cgi/samlauth"
+        ],
+        "webOrigins": [
+          "+"
+        ],
+        "notBefore": 0,
+        "bearerOnly": false,
+        "consentRequired": false,
+        "standardFlowEnabled": true,
+        "implicitFlowEnabled": false,
+        "directAccessGrantsEnabled": false,
+        "serviceAccountsEnabled": false,
+        "publicClient": false,
+        "frontchannelLogout": true,
+        "protocol": "saml",
+        "attributes": {
+          "saml.assertion.signature": "true",
+          "saml_assertion_consumer_url_redirect": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/samlauth",
+          "saml_single_logout_service_url_post": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/tmlogout",
+          "saml.force.post.binding": "true",
+          "saml.encrypt": "true",
+          "saml_assertion_consumer_url_post": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/samlauth",
+          "saml.server.signature": "true",
+          "saml.server.signature.keyinfo.ext": "false",
+          "saml.signing.certificate": "${KC_SCHOOLSH_CLIENT_SIGNING_CERTIFICATE}",
+          "saml_single_logout_service_url_redirect": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/tmlogout",
+          "saml.artifact.binding": "false",
+          "saml.signature.algorithm": "RSA_SHA256",
+          "saml_force_name_id_format": "false",
+          "saml.client.signature": "true",
+          "saml.encryption.certificate": "${KC_SCHOOLSH_CLIENT_ENCRYPTION_CERTIFICATE}",
+          "saml.authnstatement": "true",
+          "display.on.consent.screen": "false",
+          "saml_name_id_format": "username",
+          "saml.allow.ecp.flow": "false",
+          "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#",
+          "saml.onetimeuse.condition": "false",
+          "saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer": "NONE"
+        },
+        "authenticationFlowBindingOverrides": {},
+        "fullScopeAllowed": true,
+        "nodeReRegistrationTimeout": -1,
+        "defaultClientScopes": [
+          "role_list"
+        ],
+        "optionalClientScopes": [],
+        "access": {
+          "view": true,
+          "configure": true,
+          "manage": true
+        }
       }
     ],
     "clientScopes": [
@@ -2126,12 +2192,27 @@
         },
         {
           "id": "d47622d7-8d04-4d38-b7f0-d80eb182f80d",
-          "name": "rsa-generated",
-          "providerId": "rsa-generated",
+          "name": "rsa",
+          "providerId": "rsa",
           "subComponents": {},
           "config": {
+            "privateKey": [
+              "${KC_RS256_PRIVATE_KEY}"
+            ],
+            "certificate": [
+              "${KC_RS256_CERTIFICATE}"
+            ],
+            "active": [
+              "true"
+            ],
+            "enabled": [
+              "true"
+            ],
             "priority": [
               "100"
+            ],
+            "algorithm": [
+              "RS256"
             ]
           }
         },
diff --git a/charts/dbildungs-iam-keycloak/prod-realm-spsh.json b/charts/dbildungs-iam-keycloak/prod-realm-spsh.json
index 1e3a884..4043b4a 100644
--- a/charts/dbildungs-iam-keycloak/prod-realm-spsh.json
+++ b/charts/dbildungs-iam-keycloak/prod-realm-spsh.json
@@ -1282,6 +1282,72 @@
           "configure": true,
           "manage": true
         }
+      },
+      {
+        "id": "dd986a17-44c7-4ec9-87f6-addf1646ecf0",
+        "clientId": "${KC_SCHOOLSH_CLIENT_ID}",
+        "name": "School-SH",
+        "description": "",
+        "rootUrl": "${KC_SCHOOLSH_CLIENT_ROOT_URL}",
+        "adminUrl": "",
+        "baseUrl": "",
+        "surrogateAuthRequired": false,
+        "enabled": true,
+        "alwaysDisplayInConsole": false,
+        "clientAuthenticatorType": "client-secret",
+        "secret": "${KC_SCHOOLSH_CLIENT_SECRET}",
+        "redirectUris": [
+          "/cgi/samlauth"
+        ],
+        "webOrigins": [
+          "+"
+        ],
+        "notBefore": 0,
+        "bearerOnly": false,
+        "consentRequired": false,
+        "standardFlowEnabled": true,
+        "implicitFlowEnabled": false,
+        "directAccessGrantsEnabled": false,
+        "serviceAccountsEnabled": false,
+        "publicClient": false,
+        "frontchannelLogout": true,
+        "protocol": "saml",
+        "attributes": {
+          "saml.assertion.signature": "true",
+          "saml_assertion_consumer_url_redirect": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/samlauth",
+          "saml_single_logout_service_url_post": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/tmlogout",
+          "saml.force.post.binding": "true",
+          "saml.encrypt": "true",
+          "saml_assertion_consumer_url_post": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/samlauth",
+          "saml.server.signature": "true",
+          "saml.server.signature.keyinfo.ext": "false",
+          "saml.signing.certificate": "${KC_SCHOOLSH_CLIENT_SIGNING_CERTIFICATE}",
+          "saml_single_logout_service_url_redirect": "${KC_SCHOOLSH_CLIENT_ROOT_URL}/cgi/tmlogout",
+          "saml.artifact.binding": "false",
+          "saml.signature.algorithm": "RSA_SHA256",
+          "saml_force_name_id_format": "false",
+          "saml.client.signature": "true",
+          "saml.encryption.certificate": "${KC_SCHOOLSH_CLIENT_ENCRYPTION_CERTIFICATE}",
+          "saml.authnstatement": "true",
+          "display.on.consent.screen": "false",
+          "saml_name_id_format": "username",
+          "saml.allow.ecp.flow": "false",
+          "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#",
+          "saml.onetimeuse.condition": "false",
+          "saml.server.signature.keyinfo.xmlSigKeyInfoKeyNameTransformer": "NONE"
+        },
+        "authenticationFlowBindingOverrides": {},
+        "fullScopeAllowed": true,
+        "nodeReRegistrationTimeout": -1,
+        "defaultClientScopes": [
+          "role_list"
+        ],
+        "optionalClientScopes": [],
+        "access": {
+          "view": true,
+          "configure": true,
+          "manage": true
+        }
       }
     ],
     "clientScopes": [
@@ -1963,12 +2029,27 @@
         },
         {
           "id": "d47622d7-8d04-4d38-b7f0-d80eb182f80d",
-          "name": "rsa-generated",
-          "providerId": "rsa-generated",
+          "name": "rsa",
+          "providerId": "rsa",
           "subComponents": {},
           "config": {
+            "privateKey": [
+              "${KC_RS256_PRIVATE_KEY}"
+            ],
+            "certificate": [
+              "${KC_RS256_CERTIFICATE}"
+            ],
+            "active": [
+              "true"
+            ],
+            "enabled": [
+              "true"
+            ],
             "priority": [
               "100"
+            ],
+            "algorithm": [
+              "RS256"
             ]
           }
         },
diff --git a/charts/dbildungs-iam-keycloak/templates/configmap.yaml b/charts/dbildungs-iam-keycloak/templates/configmap.yaml
index 4fbaf3e..e6596fe 100644
--- a/charts/dbildungs-iam-keycloak/templates/configmap.yaml
+++ b/charts/dbildungs-iam-keycloak/templates/configmap.yaml
@@ -11,5 +11,7 @@ data:
   KC_ROOT_URL: "https://{{ .Values.frontendHostname }}"
   KC_PROXY: "edge"
   KEYCLOAK_ADMIN: admin
+  KC_SCHOOLSH_CLIENT_ID: "{{ .Values.schoolsh.clientId }}"
+  KC_SCHOOLSH_CLIENT_ROOT_URL: "{{ .Values.schoolsh.rootUrl }}"
   KC_HTTP_MANAGEMENT_PORT: "8090"
   STATUS_URL: "{{ .Values.status.url }}"
\ No newline at end of file
diff --git a/charts/dbildungs-iam-keycloak/templates/deployment.yaml b/charts/dbildungs-iam-keycloak/templates/deployment.yaml
index 9e0dc03..2face79 100644
--- a/charts/dbildungs-iam-keycloak/templates/deployment.yaml
+++ b/charts/dbildungs-iam-keycloak/templates/deployment.yaml
@@ -70,6 +70,16 @@ spec:
                 secretKeyRef:
                   name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
                   key: db-password
+            - name: KC_RS256_PRIVATE_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
+                  key: keycloak-rs256-privateKey
+            - name: KC_RS256_CERTIFICATE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
+                  key: keycloak-rs256-certificate
             - name: KC_CLIENT_SECRET
               valueFrom:
                 secretKeyRef:
@@ -132,6 +142,21 @@ spec:
                   key: keycloak-nextcloud-clientSecret
             - name: KC_DB_URL
               value: "jdbc:postgresql://$(DB_HOST)/$(DB_NAME)"
+            - name: KC_SCHOOLSH_CLIENT_SECRET
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
+                  key: keycloak-schoolsh-clientSecret
+            - name: KC_SCHOOLSH_CLIENT_SIGNING_CERTIFICATE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
+                  key: keycloak-schoolsh-signingCertificate
+            - name: KC_SCHOOLSH_CLIENT_ENCRYPTION_CERTIFICATE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default .Values.auth.existingSecret .Values.auth.secretName }}
+                  key: keycloak-schoolsh-encryptionCertificate
             {{- if .Values.extraEnvVars }}
             {{ toYaml .Values.extraEnvVars | nindent 12 }}
             {{- end }}
diff --git a/charts/dbildungs-iam-keycloak/templates/secret.yaml b/charts/dbildungs-iam-keycloak/templates/secret.yaml
index 42f2d43..ea0ff8c 100644
--- a/charts/dbildungs-iam-keycloak/templates/secret.yaml
+++ b/charts/dbildungs-iam-keycloak/templates/secret.yaml
@@ -9,6 +9,8 @@ data:
   admin-password: {{ .Values.auth.admin_password }}
   db-host: {{ .Values.database.host }}
   db-password: {{ .Values.database.password }}
+  keycloak-rs256-privateKey: {{ .Values.auth.keycloak_rs256_privateKey }}
+  keycloak-rs256-certificate: {{ .Values.auth.keycloak_rs256_certificate }}
   keycloak-adminSecret: {{ .Values.auth.keycloak_adminSecret }}
   keycloak-clientSecret: {{ .Values.auth.keycloak_clientSecret }}
   keycloak-serviceClientCertificate: {{ .Values.auth.keycloak_serviceClientCertificate }}
@@ -21,5 +23,8 @@ data:
   pi-user-realm: {{ .Values.auth.pi_user_realm }}
   keycloak-nextcloud-clientId: {{ .Values.auth.keycloak_nextcloud_clientId }}
   keycloak-nextcloud-clientSecret: {{ .Values.auth.keycloak_nextcloud_clientSecret }}
+  keycloak-schoolsh-clientSecret: {{ .Values.auth.keycloak_schoolsh_clientSecret }}
+  keycloak-schoolsh-signingCertificate: {{ .Values.auth.keycloak_schoolsh_signingCertificate }}
+  keycloak-schoolsh-encryptionCertificate: {{ .Values.auth.keycloak_schoolsh_encryptionCertificate }}
 
 {{- end }}
\ No newline at end of file
diff --git a/charts/dbildungs-iam-keycloak/values.yaml b/charts/dbildungs-iam-keycloak/values.yaml
index e7406cd..3423534 100644
--- a/charts/dbildungs-iam-keycloak/values.yaml
+++ b/charts/dbildungs-iam-keycloak/values.yaml
@@ -8,12 +8,18 @@ image:
   tag: ""
   pullPolicy: Always
 
+schoolsh:
+  clientId: https://school-sh.invalid
+  rootUrl: https://school-sh.invalid
+
 auth:
   # existingSecret: Refers to a secret already present in the cluster, which is required for the authentication and configuration of the database setup tasks.
   existingSecret: ""
   secretName: dbildungs-iam-keycloak
   admin_password: ""
   admin_user: ""
+  keycloak_rs256_privateKey: ""
+  keycloak_rs256_certificate: ""
   keycloak_adminSecret: ""
   keycloak_clientSecret: ""
   keycloak_serviceClientCertificate: ""
@@ -26,6 +32,10 @@ auth:
   pi_admin_password: ""
   pi_user_resolver: ""
   pi_user_realm: ""
+  schoolsh_clientSecret: ""
+  schoolsh_signingCertificate: ""
+  schoolsh_encryptionCertificate: ""
+
 
 command: []
 

From 7e817f8dbf182ff5a2c6239227f98fee68d2a5b5 Mon Sep 17 00:00:00 2001
From: Alexander Ungefug <82446024+AlexanderUngefug@users.noreply.github.com>
Date: Tue, 3 Dec 2024 11:47:15 +0100
Subject: [PATCH 4/7] Spsh 1195 (#84)

* Create keycloak-metrics-spi-6.0.1-SNAPSHOT.jar

* implementing service monitor yaml

* add serviceMonitor setting to values.yaml

* fixing charts

* fixing chart settings

* add metrics event listener

* Set Metrics disable external access

* change metrics endpoint and port

* remove metrics spi and event listener

* Spsh-1496 (#87)

* add error handling if user is found in privcyIDea

* handle: Authentication failed. The user has no tokens assigned

* change text
---
 Dockerfile                                    |  3 ++-
 .../templates/keycloak-servicemonitor.yaml    | 21 +++++++++++++++++++
 charts/dbildungs-iam-keycloak/values.yaml     |  7 +++++++
 3 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 charts/dbildungs-iam-keycloak/templates/keycloak-servicemonitor.yaml

diff --git a/Dockerfile b/Dockerfile
index 29f55bb..6d15283 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -44,7 +44,8 @@ ENV KC_HEALTH_ENABLED=true \
     KC_DB=postgres \
     KC_FEATURES_DISABLED=impersonation,par \
     KC_CACHE=ispn \
-    KC_CACHE_STACK=kubernetes
+    KC_CACHE_STACK=kubernetes \
+    DISABLE_EXTERNAL_ACCESS=true
 
 # Build Keycloak for deployment
 RUN /opt/keycloak/bin/kc.sh build
diff --git a/charts/dbildungs-iam-keycloak/templates/keycloak-servicemonitor.yaml b/charts/dbildungs-iam-keycloak/templates/keycloak-servicemonitor.yaml
new file mode 100644
index 0000000..85a83f3
--- /dev/null
+++ b/charts/dbildungs-iam-keycloak/templates/keycloak-servicemonitor.yaml
@@ -0,0 +1,21 @@
+{{- if .Values.keycloak.serviceMonitor.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: {{ template "common.names.name" . }}
+  namespace: {{ template "common.names.namespace" . }}
+  labels:
+    {{- include "common.labels" . | nindent 4 }}
+    app.kubernetes.io/component: keycloak
+spec:
+  namespaceSelector:
+    matchNames:
+      - {{ include "common.names.namespace" . | quote }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ template "common.names.name" . }}
+  endpoints:
+    - port: {{ .Values.keycloak.serviceMonitor.port }}
+      path: {{ .Values.keycloak.serviceMonitor.path }}
+      interval: {{ .Values.keycloak.serviceMonitor.interval | default "30s" }}
+{{- end }}
diff --git a/charts/dbildungs-iam-keycloak/values.yaml b/charts/dbildungs-iam-keycloak/values.yaml
index 3423534..b0940de 100644
--- a/charts/dbildungs-iam-keycloak/values.yaml
+++ b/charts/dbildungs-iam-keycloak/values.yaml
@@ -121,6 +121,13 @@ service:
   ports:
     http: 80
 
+keycloak:
+  serviceMonitor:
+    enabled: true
+    path: "/metrics"
+    endpoints:
+      - port: 'mgmt'
+
 autoscaling:
   enabled: false
   minReplicas: 1

From e790ccf3d8d2c95c16748f2313acfb0f1ada97ce Mon Sep 17 00:00:00 2001
From: mcpovel <Michael.Povel@capgemini.com>
Date: Thu, 5 Dec 2024 12:05:39 +0100
Subject: [PATCH 5/7] Added 2nd ingress (#96)

* Added 2nd ingress

* Test 2nd ingress

* removed test entries
---
 .../templates/ingress2nd.yaml                 | 29 +++++++++++++++++++
 charts/dbildungs-iam-keycloak/values.yaml     |  3 ++
 2 files changed, 32 insertions(+)
 create mode 100644 charts/dbildungs-iam-keycloak/templates/ingress2nd.yaml

diff --git a/charts/dbildungs-iam-keycloak/templates/ingress2nd.yaml b/charts/dbildungs-iam-keycloak/templates/ingress2nd.yaml
new file mode 100644
index 0000000..bb594ed
--- /dev/null
+++ b/charts/dbildungs-iam-keycloak/templates/ingress2nd.yaml
@@ -0,0 +1,29 @@
+{{if .Values.ingress.enabled2nd }}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: {{ template "common.names.name" . }}-2nd
+  namespace: {{ template "common.names.namespace" . }}
+  labels: 
+    {{- include "common.labels" . | nindent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+  tls:
+    - hosts:
+        - {{ .Values.keycloak2ndHostname  }}
+  ingressClassName: {{ .Values.ingress.ingressClassName }}
+  rules:
+    - host: {{ .Values.keycloak2ndHostname  }}
+      http:
+        paths:
+          - path: {{ .Values.ingress.path }}
+            pathType: {{ .Values.ingress.pathType }}
+            backend: 
+              service:
+                name: {{ template "common.names.name" . }}
+                port:
+                  number: {{ .Values.service.ports.http }}
+{{- end }}
\ No newline at end of file
diff --git a/charts/dbildungs-iam-keycloak/values.yaml b/charts/dbildungs-iam-keycloak/values.yaml
index b0940de..b726d63 100644
--- a/charts/dbildungs-iam-keycloak/values.yaml
+++ b/charts/dbildungs-iam-keycloak/values.yaml
@@ -57,6 +57,7 @@ restartPolicy: Always
 
 keycloakHostname: ""
 frontendHostname: ""
+keycloak2ndHostname: ""
 
 containerSecurityContext:
   enabled: true
@@ -99,6 +100,8 @@ readinessProbe:
     port: mgmt
 
 ingress:
+  # Only enable if 2nd host name is defined
+  enabled2nd: false
   ingressClassName: nginx
   path: /
   pathType: Prefix

From 9f3d1197d1d9acf852868b89204f9ac4b475db33 Mon Sep 17 00:00:00 2001
From: aimee-889 <93951322+aimee-889@users.noreply.github.com>
Date: Thu, 5 Dec 2024 14:39:21 +0100
Subject: [PATCH 6/7] SPSH-1195-fix servicemonitor (#98)

SPSH-1195-fix servicemonitor (#98)
---
 charts/dbildungs-iam-keycloak/values.yaml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/charts/dbildungs-iam-keycloak/values.yaml b/charts/dbildungs-iam-keycloak/values.yaml
index b726d63..ff04e2a 100644
--- a/charts/dbildungs-iam-keycloak/values.yaml
+++ b/charts/dbildungs-iam-keycloak/values.yaml
@@ -128,8 +128,7 @@ keycloak:
   serviceMonitor:
     enabled: true
     path: "/metrics"
-    endpoints:
-      - port: 'mgmt'
+    port: 'mgmt'
 
 autoscaling:
   enabled: false

From 1a80bd74af79f691a7528307c5a95d5798a15e81 Mon Sep 17 00:00:00 2001
From: M-Schiborr <112689259+M-Schiborr@users.noreply.github.com>
Date: Fri, 6 Dec 2024 10:40:03 +0100
Subject: [PATCH 7/7] Dbp 1157 create pod disruption budget for spsh
 applications (#99)

* Spsh-1496 (#87)

* add error handling if user is found in privcyIDea

* handle: Authentication failed. The user has no tokens assigned

* change text

* DBP-1157-Create-PodDisruptionBudget-for-SPSH-Applications

* DBP-1157-Create-PodDisruptionBudget-for-SPSH-Applications

---------

Co-authored-by: Alexander Ungefug <82446024+AlexanderUngefug@users.noreply.github.com>
---
 .../dbildungs-iam-keycloak/templates/pdb.yaml   | 17 +++++++++++++++++
 charts/dbildungs-iam-keycloak/values.yaml       |  4 ++++
 2 files changed, 21 insertions(+)
 create mode 100644 charts/dbildungs-iam-keycloak/templates/pdb.yaml

diff --git a/charts/dbildungs-iam-keycloak/templates/pdb.yaml b/charts/dbildungs-iam-keycloak/templates/pdb.yaml
new file mode 100644
index 0000000..7bedbc8
--- /dev/null
+++ b/charts/dbildungs-iam-keycloak/templates/pdb.yaml
@@ -0,0 +1,17 @@
+{{- if .Values.podDisruptionBudget.enabled }}
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+  name: {{ template "common.names.name" . }}-pdb
+  namespace: {{ .Release.Namespace }}
+  labels:
+    app.kubernetes.io/name: {{ include "common.names.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
+    app.kubernetes.io/version: {{ .Chart.AppVersion }}
+    app.kubernetes.io/managed-by: {{ .Release.Service }}
+spec:
+  minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: dbildungs-iam-keycloak
+{{- end }}
\ No newline at end of file
diff --git a/charts/dbildungs-iam-keycloak/values.yaml b/charts/dbildungs-iam-keycloak/values.yaml
index ff04e2a..965ee93 100644
--- a/charts/dbildungs-iam-keycloak/values.yaml
+++ b/charts/dbildungs-iam-keycloak/values.yaml
@@ -138,3 +138,7 @@ autoscaling:
 
 status:
   url: "https://status.dev.spsh.dbildungsplattform.de/"
+
+podDisruptionBudget:
+  enabled: true
+  minAvailable: "80%"