dotCMS / dotCMS/core

dotAuth: offer to pre-fill Google Workspace group lookup fields after OIDC discovery

Open
#37,371 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dotCMS : Authentication Team : Platform Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

Follow-up to #37195, which added a post-auth groups fetch (groupsUrl + groupsResponsePath) for IdPs that cannot emit group membership in token claims. Google Workspace is the canonical case, and its working configuration is non-obvious: a Cloud Identity searchDirectGroups URL with an {email} placeholder, the response path memberships[].groupKey.id, and an extra OAuth scope.

When an admin runs OIDC discovery in the dotAuth portlet and the returned issuer is https://accounts.google.com, we already know exactly what those three fields should be. The portlet should offer to fill them in.

Behavior

After a successful discovery whose issuer is exactly https://accounts.google.com, show a confirm dialog (PrimeNG ConfirmDialog, not a toast, since it needs a decision):

Google Workspace detected

Google doesn't include group membership in its sign-in tokens. We can set up dotCMS to look up each user's groups from Google after they sign in, so group-to-role mappings work.

This fills in the Groups URL, Groups Response Path, and adds one Google scope. You can review or change these in Advanced Settings before saving.

[ Set up group lookup ] [ Not now ]

Accepting sets, in the draft only (nothing is saved until the admin clicks Save):

Field Value
groupsUrl https://cloudidentity.googleapis.com/v1/groups/-/memberships:searchDirectGroups?query=member_key_id=='{email}'
groupsResponsePath memberships[].groupKey.id
scopes existing scopes plus https://www.googleapis.com/auth/cloud-identity.groups.readonly, appended only if absent

groupsUrl and groupsResponsePath are only written when currently empty, so re-running discovery never clobbers an admin who customized them (e.g. switched to searchTransitiveGroups).

Why a prompt and not a silent pre-fill

The groups fetch fails the login by design when the endpoint errors. Google also needs the Cloud Identity API enabled on the project and the scope added to the OAuth consent screen, neither of which is visible from the discovery document. A silent pre-fill followed by Save would lock every user out until the Google console work is finished. The prompt makes the change explicit, and the help text under Groups URL should name the two Google-side prerequisites.

Scope is frontend only. The discovery proxy already returns issuer; no backend change is needed. Entra is out of scope: its Graph groups endpoint paginates via @odata.nextLink, which the fetcher does not follow.

Acceptance Criteria
  • After successful OIDC discovery with issuer === 'https://accounts.google.com', a confirm dialog with the copy above is shown.
  • Discovery against any other issuer shows no dialog and behaves exactly as today.
  • Accepting sets oidc.groupsUrl and oidc.groupsResponsePath to the Google values when both are empty.
  • Accepting leaves a non-empty oidc.groupsUrl or oidc.groupsResponsePath untouched.
  • Accepting appends the cloud-identity.groups.readonly scope to oidc.scopes when absent, and does not duplicate it when present.
  • Declining leaves all three fields unchanged.
  • The pre-fill only modifies the draft; nothing is persisted until the admin saves.
  • The Groups URL help text mentions that Google requires the Cloud Identity API enabled and the scope added to the OAuth consent screen.
  • All new dialog copy is in Language.properties and rendered through the dm pipe.
  • Mapper unit tests cover: Google issuer detected, non-Google issuer ignored, fill-when-empty, no-clobber, scope append, scope no-duplicate.
Priority

Low

Additional Context

Discovery apply logic lives in applyOidcDiscovery in core-web/libs/portlets/dot-auth/src/lib/dot-auth-config/store/dot-auth-config.mappers.ts. The worked Google configuration is documented in the OAuthGroupsFetcher javadoc.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with applyOidcDiscovery in core-web/libs/portlets/dot-auth/src/lib/dot-auth-config/store/dot-auth-config.mappers.ts and inspect the existing discovery flow and mapper unit tests. Then locate the dotAuth portlet's ConfirmDialog integration, Groups URL help text, and Language.properties entries. Done means the Google-only prompt, guarded draft updates, translated copy, prerequisites help text, and mapper tests for detection, no-clobber, and scope handling are present.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authentication, frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.