From afbda2a52fa9934df79a29e691a7ce1169b15c25 Mon Sep 17 00:00:00 2001 From: Renovate Date: Wed, 27 May 2026 20:47:03 +0000 Subject: [PATCH 1/9] Update maven plugins --- attribute-endpoints-provider/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/attribute-endpoints-provider/pom.xml b/attribute-endpoints-provider/pom.xml index be1ac28..a6d1663 100644 --- a/attribute-endpoints-provider/pom.xml +++ b/attribute-endpoints-provider/pom.xml @@ -86,7 +86,7 @@ maven-surefire-plugin - 3.5.5 + 3.5.6 maven-jar-plugin @@ -104,7 +104,7 @@ https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --> maven-site-plugin - 3.21.0 + 3.22.0 maven-project-info-reports-plugin From 58ffc634ba820e293ee030316406f1e3ec1c01da Mon Sep 17 00:00:00 2001 From: Renovate Date: Thu, 18 Jun 2026 15:02:15 +0000 Subject: [PATCH 2/9] Update actions/checkout action to v7 --- .forgejo/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index be66b11..533a785 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -7,7 +7,7 @@ jobs: name: Verify runs-on: docker steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Install maven run: | apt update From 1ea041dc7cce2a82dcedda273fd993cc6db183d2 Mon Sep 17 00:00:00 2001 From: Renovate Date: Sat, 18 Jul 2026 12:16:57 +0000 Subject: [PATCH 3/9] Update Keycloak packages to v26.7.0 --- attribute-endpoints-provider/pom.xml | 2 +- testing/compose.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/attribute-endpoints-provider/pom.xml b/attribute-endpoints-provider/pom.xml index be1ac28..61cafbb 100644 --- a/attribute-endpoints-provider/pom.xml +++ b/attribute-endpoints-provider/pom.xml @@ -17,7 +17,7 @@ UTF-8 17 17 - 26.6.0 + 26.7.0 diff --git a/testing/compose.yaml b/testing/compose.yaml index 0311532..ee2a937 100644 --- a/testing/compose.yaml +++ b/testing/compose.yaml @@ -1,6 +1,6 @@ services: keycloak: - image: quay.io/keycloak/keycloak:26.6.0 + image: quay.io/keycloak/keycloak:26.7.0 pull_policy: always command: "start-dev --features=declarative-ui --import-realm" environment: From b292fd802362b56808daaeea0119c70e8bc91dd0 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 15:01:26 +0200 Subject: [PATCH 4/9] Give a meaningful error message when the necessary role is missing --- .../attribute_endpoints/AttributeEndpointsResourceProvider.java | 1 + 1 file changed, 1 insertion(+) diff --git a/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java b/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java index bd98b30..15303dc 100644 --- a/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java +++ b/attribute-endpoints-provider/src/main/java/de/ccc/hamburg/keycloak/attribute_endpoints/AttributeEndpointsResourceProvider.java @@ -109,6 +109,7 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider UserModel authUser = auth.getUser(); if (!authUser.hasRole(authRole)) { + LOG.info("User " + authUser.getUsername() + " does not have required role " + authRole.getName()); throw new ForbiddenException("User does not have required auth role."); } From 5e279f8c711006a9c32da31a945ac181050f65ca Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 15:01:48 +0200 Subject: [PATCH 5/9] Assign roles to service account user, not the client --- testing/import/testing.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testing/import/testing.json b/testing/import/testing.json index a91df6c..3744ff8 100644 --- a/testing/import/testing.json +++ b/testing/import/testing.json @@ -470,7 +470,7 @@ "credentials" : [ ], "disableableCredentialTypes" : [ ], "requiredActions" : [ ], - "realmRoles" : [ "default-roles-testing" ], + "realmRoles" : [ "export-dooris-ssh-keys", "default-roles-testing" ], "notBefore" : 0, "groups" : [ ] }, { @@ -484,7 +484,7 @@ "credentials" : [ ], "disableableCredentialTypes" : [ ], "requiredActions" : [ ], - "realmRoles" : [ "default-roles-testing" ], + "realmRoles" : [ "export-mailing-list-addresses", "default-roles-testing" ], "notBefore" : 0, "groups" : [ ] }, { @@ -1478,7 +1478,7 @@ "subType" : "authenticated", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper" ] } }, { "id" : "a49de9bf-462b-4c61-bb52-0373732f4b1b", @@ -1538,7 +1538,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper" ] + "allowed-protocol-mapper-types" : [ "saml-role-list-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper" ] } }, { "id" : "dd4024e9-f080-4319-aeb7-7f9906c345c5", @@ -1625,8 +1625,8 @@ "subComponents" : { }, "config" : { "match-role" : [ "mailing-list-chaos-member" ], - "attribute-group" : [ "mailing-list-addresses" ], "auth-role" : [ "export-mailing-list-addresses" ], + "attribute-group" : [ "mailing-list-addresses" ], "slug" : [ "mailing-list-addresses-chaos" ] } } ] From f586e5feee99c7e46bfb901e6c8becbfd42b4916 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 15:02:12 +0200 Subject: [PATCH 6/9] Integration test to demonstrate ssh key export --- testing/README.md | 49 ++++++++++++++++++++++++++-- testing/client-test-export-dooris.sh | 20 ++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100755 testing/client-test-export-dooris.sh diff --git a/testing/README.md b/testing/README.md index 86ff971..2c5600e 100644 --- a/testing/README.md +++ b/testing/README.md @@ -23,12 +23,26 @@ The copying of the database is necessary to avoid locking errors. docker compose exec -it keycloak sh -c "cp -rp /opt/keycloak/data/h2 /tmp && env -i -- /opt/keycloak/bin/kc.sh export --db dev-file --db-url 'jdbc:h2:file:/tmp/h2/keycloakdb;NON_KEYWORDS=VALUE' --file /opt/keycloak/data/import/testing.json --realm testing" ``` -## Testing Realm Configuration +## Running Integration Tests + +This directory also contains shell scripts that exercise the attribute endpoint. + +Bring up Keycloak with `docker compose up -d`, then run one of the `client-test-export-`*`.sh` scripts. + +```shell +$ ./client-test-export-dooris.sh +[ + "hacker-ssh-key-1", + "hacker-ssh-key-2" +] +``` + +## Realm `testing` Configuration The realm contains these objects: * Clients: - * `export-dooris-ssh-keys` with secret `export-dooris-ssh-keys-secret` and role `export-dooris-ssh-keys` + * `export-dooris-ssh-keys` with secret `export-dooris-ssh-keys-secret` and user `service-account-export-dooris-ssh-keys` * `export-mailing-list-addresses` with secret `export-mailing-list-addresses-secret` and role `export-mailing-list-addresses` * Realm Roles: * `dooris-authorized` @@ -54,3 +68,34 @@ The realm contains these objects: * Dooris SSH Keys: * SSH Key 1: `hacker-ssh-key-1` * SSH Key 2: `hacker-ssh-key-2` + * `service-account-export-dooris-ssh-keys` + * Role `export-dooris-ssh-keys` + * `service-account-export-mailing-list-addresses` + * Role `export-mailing-list-addresses` +* Realm Settings: + * User Profile: + * Attribute Groups: + * `dooris-ssh-keys` + * `mailing-list-addresses` + * Attributes: + * `mailing-list-address-chaos` + * Attribute Group `mailing-list-addresses` + * `mailing-list-address-intern` + * Attribute Group `mailing-list-intern` + * `ssh-key-1` + * Attribute Group `dooris-ssh-keys` + * `ssh-key-2` + * Attribute Group `dooris-ssh-keys` +* Custom Attributes: + * Slug `dooris-ssh-keys` + * Attribute Group `dooris-ssh-keys` + * Match Role `dooris-authorized` + * Auth Role `export-dooris-ssh-keys` + * Slug `mailing-list-addresses-chaos` + * Attribute Group `mailing-list-addresses` + * Match Role `mailing-list-chaos-member` + * Auth Role `export-mailing-list-addresses` + * Slug `mailing-list-addresses-intern` + * Attribute Group `mailing-list-addresses` + * Match Role `mailing-list-intern-member` + * Auth Role `export-mailing-list-addresses` diff --git a/testing/client-test-export-dooris.sh b/testing/client-test-export-dooris.sh new file mode 100755 index 0000000..b6d4696 --- /dev/null +++ b/testing/client-test-export-dooris.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# +# Use curl to run a test export of Dooris ssh keys +# + +set -e + +ACCESS_TOKEN="$(curl -s --request POST \ + --url http://localhost:8080/realms/testing/protocol/openid-connect/token \ + --header 'content-type: application/x-www-form-urlencoded' \ + --data scope=openid \ + --data client_id=export-dooris-ssh-keys \ + --data client_secret=export-dooris-ssh-keys-secret \ + --data grant_type=client_credentials | jq --raw-output .access_token -)" + +curl -s --request GET \ + --url http://localhost:8080/realms/testing/attribute-endpoints-provider/export/dooris-ssh-keys \ + --header "authorization: Bearer ${ACCESS_TOKEN}" \ + --header "content-type: application/json" | jq . - \ No newline at end of file From 0a84d2ddf90c46eadf7a083eef84f5ac6dc72d66 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 21:38:50 +0200 Subject: [PATCH 7/9] Only build when pushing to main or on a pull request --- .forgejo/workflows/verify.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 533a785..7f8e199 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -1,6 +1,8 @@ on: pull_request: push: + branches: + - main jobs: ansible-lint: From 89ce38f6c1551074926370999108248047d7359a Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 21:40:39 +0200 Subject: [PATCH 8/9] Be less verbose when building --- .forgejo/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 7f8e199..4f33cc9 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -16,4 +16,4 @@ jobs: apt install -y maven - name: Run maven verify run: | - mvn -f attribute-endpoints-provider verify + mvn -f attribute-endpoints-provider --batch --no-transfer-progress verify From 6cd678b4141b1dd4392ab87e97669aae21a9c880 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 18 Jul 2026 21:41:42 +0200 Subject: [PATCH 9/9] Spell option correctly --- .forgejo/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 4f33cc9..9f88d22 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -16,4 +16,4 @@ jobs: apt install -y maven - name: Run maven verify run: | - mvn -f attribute-endpoints-provider --batch --no-transfer-progress verify + mvn -f attribute-endpoints-provider --batch-mode --no-transfer-progress verify