Interface AuthBackend


public interface AuthBackend
CloudForge Manager's Users-page CRUD, abstracted over whichever directory of accounts is currently authoritative — the local H2/Postgres DB, or an AWS Cognito User Pool. AuthService resolves one AuthBackend implementation per call (based on the persisted AuthBackendStore.Config#cognitoEnabled() flag) and delegates its user-management methods (listUsers/createLocalUser/updateUser/revokeSessions/ deleteUser) through it.

Deliberately scoped to exactly this — Users-page CRUD — and nothing else. Caller/session resolution during normal request handling (AuthService.resolveCaller/ ensureOidcUser) branches only on authMode() (the *sign-in* mechanism: none/alb-oidc/ application-oidc) and always resolves through the local manager_user table regardless of which AuthBackend is active for account CRUD — a Cognito-backend-enabled account still signs in via whatever OIDC flow authMode configures, gets upserted into the local table on each successful principal, and its Caller/role come from that local row. Moving caller/session resolution into this interface would be a separate behavior change.

Implementations: LocalH2AuthBackend (wraps UserStore+SessionManager) and CognitoAuthBackend (wraps CognitoUserManagementService), both in cloudforge-manager — this interface and its DTOs (AuthAccount, AuthAccountRequest, AuthAccountUpdate) live in cloudforge-core because they're plain contracts with no Spring/persistence dependency, following the same split as ApplicationSpec/DatabaseSpec.

  • Method Details

    • listAccounts

      List<AuthAccount> listAccounts()
    • listAccounts

      default List<AuthAccount> listAccounts(String search, String role)
      Same as listAccounts(), narrowed by two optional filters: search (matches AuthAccount.username()/AuthAccount.email()/AuthAccount.displayName(), case-insensitive substring) and role (exact match). Both null/blank mean "unfiltered" — equivalent to listAccounts().

      The default implementation filters in Java over listAccounts() — correct for any backend, but only moves the filtering server-side (out of the Angular Users page) without reducing the underlying account-directory calls. LocalH2AuthBackend overrides this with a database-level query. CognitoAuthBackend keeps this default deliberately: Cognito's own ListUsers Filter syntax has no concept of role (role lives in group membership, not a filterable user attribute), so even an override there couldn't push the role filter down — only search could move, with no reduction in Cognito API calls either, the same trade-off CloudFormationInventory#listInstances(String, String)'s search parameter documents for AWS's own ListStacks.

    • createAccount

      AuthAccount createAccount(AuthAccountRequest request)
    • updateAccount

      AuthAccount updateAccount(String accountId, AuthAccountUpdate update)
    • revokeSessions

      AuthAccount revokeSessions(String accountId)
      Invalidates every active session/token for this account without deleting it — the local equivalent of Cognito's AdminUserGlobalSignOut. Returns the (unchanged) account so callers can render an up-to-date view without a second lookup.
    • deleteAccount

      void deleteAccount(String accountId)
    • prepareForIncomingMigration

      default void prepareForIncomingMigration()
      One-time setup a backend needs before it can accept migrated-in accounts (e.g. Cognito's IAM role groups must exist before a migration starts adding users to them). Called once per migration run, before the first createAccount(AuthAccountRequest). No-op by default — LocalH2AuthBackend has nothing to prepare.
    • findAccount

      default Optional<AuthAccount> findAccount(String accountId)
      Finds one account by its AuthAccount.id(), or empty if this backend has no such account. Exists so callers that only have an id — e.g. Access Control's policy-override editor, given whatever id listAccounts() last handed the frontend — can resolve a username/role for display without requiring the account to also exist in Manager's local user table. A Cognito-only account that has never signed in through application-oidc has no local row, so a local-table lookup would report "user not found" for an account listAccounts() just returned.

      Default implementation scans listAccounts() — correct for any backend, just not the cheapest possible lookup; override when a backend can look up a single account more directly (see CognitoAuthBackend).