CodamAIDocs
Themafertig

Der Speicher-Adapter für Tests und Entwicklung

Ein Identity Provider im Speicher, gegen dieselben Vertragstests geprüft, für Tests und lokale Entwicklung ohne Keycloak.

Ausprägungen
VertragstestTest einer ganzen Anwendunglokale Entwicklung (Profil local)Rolle nicht angelegtPasswort-Link aus dem Speicherfremde Gruppe für einen TestNeustart

Worum es geht

Der Speicher-Adapter (cias-iam-memory) ist ein Identity Provider, der nur im Arbeitsspeicher lebt. Es gibt ihn für zwei Zwecke:

  • Testen ohne Keycloak. Ein Test, der eine Registrierung durchspielt, braucht keinen laufenden Keycloak.
  • Entwickeln ohne Keycloak. Wer an der Registrierung oder der Rollenvergabe baut, kann den ganzen Ablauf auf dem eigenen Rechner ausprobieren.

Ein Vertragstest ist ein Test, der nicht einen Adapter prüft, sondern das Versprechen eines Ports. Er ist einmal geschrieben und läuft gegen jeden Adapter.

Eine Ablage für alle Ports

flowchart LR
    subgraph Ports
      P1["Konten"]
      P2["Organisationen und Mitgliedschaften"]
      P3["Realm- und Client-Rollen"]
      P4["Gruppen"]
      P5["Profil und Claims"]
    end
    P1 --> S
    P2 --> S
    P3 --> S
    P4 --> S
    P5 --> S
    S[("InMemoryIdentityProvider<br/>eine Klasse, eine Ablage")]

Warum eine Klasse und nicht eine je Port? Eine Attrappe, die auf fünf getrennte Ablagen verteilt ist, erlaubt Zustände, die es in Wirklichkeit nicht geben kann: eine Mitgliedschaft für ein Konto, das niemand angelegt hat, oder eine Rolle in einer gelöschten Organisation. Ein Test, der gegen so etwas grün wird, beweist nichts.

Dieselben Tests für beide

flowchart TB
    V["cias-test-support<br/>Vertragstests als abstrakte Klassen"]
    V --> MT["cias-iam-memory<br/>InMemory…Test"]
    V --> KT["cias-iam-keycloak<br/>Keycloak…Test"]
    MT --> M[("Speicher")]
    KT --> K["echter Keycloak<br/>im Container"]

Die Vertragstests liegen im Modul cias-test-support, als abstrakte JUnit-Klassen. Jeder Adapter erbt von ihnen und liefert nur seine Ports und ein paar Hilfen, um Testdaten anzulegen. Die Prüfungen selbst sind dieselben.

VertragssuiteFälleWas sie verspricht, zum Beispiel
IdentityProvisioningContract9neue Konten sind gesperrt und unbestätigt, eine Adresse gibt es nur einmal, Suche ohne Rücksicht auf Groß- und Kleinschreibung, jede Zustandsänderung darf zweimal kommen
OrganizationManagementContract7ein Alias gibt es nur einmal, Mitgliedschaften geben und nehmen, das Konto bleibt
RoleManagementContract10Rollen in einer Organisation erscheinen nie bei den globalen Rollen, „keine Rollen“ heißt nichts erlaubt
ClientRoleManagementContract15dieselbe Rolle auf zwei Clients sind zwei Rollen, eine Client-Rolle ist keine Realm-Rolle
GroupManagementContract26Gruppen ohne Marke cias-managed sind unsichtbar und unveränderbar, Rollen werden gesetzt statt ergänzt, Standardgruppen
UserProfileManagementContract6Attribute werden ergänzt und korrigiert, nie entfernt, fremde Einträge bleiben
ClaimMappingContract3ein Mapper entsteht einmal, eine geänderte Form wird korrigiert

Wichtig ist die Richtung: Muss ein Fall gelockert werden, damit der Speicher-Adapter besteht, ist der Speicher-Adapter falsch, nicht der Vertrag.

Der Keycloak-Adapter läuft außerdem gegen einen echten Keycloak in einem Container (Testcontainers, Keycloak 26.7) oder gegen einen laufenden Server, den -Dcias.test.keycloak.url nennt. Jede Testklasse legt sich dort einen eigenen Realm an. Dazu kommen Fälle, die eine Attrappe gar nicht abbilden kann: ein unbekannter Client, die Rechte an Profilattributen, das, was Keycloak selbst im Profil mitbringt, und der Passwort-Link mit und ohne Erweiterung.

Wann du ihn triffst

Drei Einsatzorte

Wann: Du baust oder änderst einen Adapter oder einen Port.

Die Testklassen in cias-iam-memory erben von den Vertragssuiten. Jeder Test bekommt einen frischen Speicher. Mit defineRole und defineClientRole legst du Rollen an, mit defineForeignGroup eine Gruppe, die CIAS nicht gehört.

Ergebnis: derselbe Maßstab wie für Keycloak

Wann: Ein Test startet das eigenständige CIAS mit seiner ganzen Verdrahtung, etwa um eine Registrierung von Anfang bis Ende durchzuspielen.

Der Test holt sich den InMemoryIdentityProvider als Bean, legt die nötigen Rollen an und prüft danach, was im Speicher steht: welches Konto, welche Organisation, welche Rollen.

Ergebnis: ganzer Ablauf ohne Keycloak

Wann: Du startest das eigenständige CIAS ohne weitere Angaben auf deinem Rechner.

Das Profil local stellt codamai.cias.iam-provider: memory ein, dazu eine H2-Datenbank im Speicher und Mails nur ins Log. Du kannst Registrierungen, Rollen und Gruppen über die API ausprobieren.

Ergebnis: kein Keycloak nötig, aber auch keine Anmeldung mit diesen Konten

Eingeschaltet wird der Speicher-Adapter wie jeder Adapter: Das Jar liegt im Klassenpfad, und codamai.cias.iam-provider ist memory. Er fällt nie von selbst als Ersatz ein. Siehe Ports und Adapter.

Wie er sich verhält

Besonderheiten im Speicher

Wann: Ein Test vergibt eine Rolle, die vorher niemand angelegt hat.

Wie in Keycloak muss eine Rolle erst existieren. Der Speicher-Adapter meldet IamNotFoundException. Ohne diese Regel würde „gibt es die Rolle?“ immer mit Ja antworten, und die Prüfung, ob alle konfigurierten Rollen existieren, wäre wertlos.

Ergebnis: Fehler, wie in Keycloak

Wann: Der Ablauf fragt nach einem Passwort-Link.

Der Speicher-Adapter liefert immer einen Link, damit Mails und Seiten, die ihn anzeigen, getestet werden können. Der Link beginnt mit memory://password-setup/…, damit ihn niemand aus Versehen öffnet und man ihn in einer Mail sofort erkennt. Ohne Angabe gilt er einen Tag. Eine Gültigkeit über 72 Stunden lehnt er ab, genau wie die Keycloak-Erweiterung.

Ergebnis: Link, der nirgendwohin führt

Wann: Ein Test braucht eine Gruppe, die ein Betreiber von Hand angelegt hätte.

defineForeignGroup legt eine Gruppe ohne Marke cias-managed an, auf Wunsch als Standardgruppe, und fillForeignGroup gibt ihr Rollen und Mitglieder. So lässt sich prüfen, dass CIAS fremde Gruppen nicht anfasst und der Import sie übernimmt.

Ergebnis: Grenze zu fremden Gruppen testbar

Wann: Der Prozess endet.

Alles ist weg: Konten, Organisationen, Rollen, Gruppen, Profil. Es gibt nichts, was gespeichert würde.

Ergebnis: leerer Speicher beim nächsten Start

Speicher-Adapter und Keycloak-Adapter im Vergleich

Speicher-Adapter
cias-iam-memory
  • alle Ports in einer Klasse, eine Ablage
  • keine Tokens, keine Anmeldung, keine Passwörter
  • keine Rechte an Profilattributen
  • Passwort-Link immer da, aber memory://
  • nach einem Neustart leer
Keycloak-Adapter
cias-iam-keycloak
  • Ports auf mehrere Klassen verteilt, ein HTTP-Zugang
  • Konten, mit denen man sich anmelden kann
  • Rechte an jedem Profilattribut
  • Passwort-Link nur mit der Erweiterung
  • Daten bleiben in Keycloak

Gleich sind die Versprechen, die die Vertragstests prüfen: eindeutige Adressen und Aliase, getrennte Ebenen für Rollen, Gruppen nur mit Marke, wiederholbare Aufrufe.

Fallen

Weiter

Quellen im Code und in der Wissensdatenbank
  • CIAS/cias-iam-memory – InMemoryIdentityProvider (defineRole, defineClientRole, reset, createPasswordSetupLink, findByEmail, list, ensureAttributes, ensureClaim, defineForeignGroup, fillForeignGroup), CLAUDE.md
  • CIAS/cias-iam-memory – InMemory*Test (ClaimMapping, ClientRoleManagement, GroupManagement, IdentityProvisioning, OrganizationManagement, RoleManagement, UserProfile)
  • CIAS/cias-test-support – ClaimMappingContract, ClientRoleManagementContract, GroupManagementContract, IdentityProvisioningContract, OrganizationManagementContract, RoleManagementContract, UserProfileManagementContract
  • CIAS/cias-iam-keycloak – Keycloak*Test, KeycloakTestEnvironment, KeycloakAdapters
  • CIAS/cias-spring-boot-starter – CiasIamAutoConfiguration.MemoryConfiguration
  • CIAS/cias-runtime – application-local.yml, RegistrationEndToEndTest, AuthorizationEndToEndTest
  • CIAS/cias-iam-api/docs/adr – ADR-004
Suchen