Skip to content

Add Ampeco OAuth2 provider and a generic, reusable OAuth2 mechanism - #1

Open
OxyFlax with Copilot wants to merge 4 commits into
feat/Oauthfrom
copilot/add-ampecco-integration
Open

OxyFlax with Copilot wants to merge 4 commits into
feat/Oauthfrom
copilot/add-ampecco-integration

Conversation

Copilot AI commented Jun 8, 2026

Copy link
Copy Markdown

Adds AMPECO as an OAuth2 login provider and generalizes the OAuth2 layer so any future provider exposing an OpenID Connect userinfo endpoint can be added with minimal or zero code.

Reusable core (fr.iolabs.leaf.authentication.oauth)

  • AbstractUserInfoOAuthTokenVerifier — base verifier that calls a provider's userinfo endpoint with the access token, maps standard OIDC claims (sub, email, given_name, family_name, name, picture) onto OAuthUserInfo, splits a single name claim when first/last are absent, and tolerates a data-wrapped payload. Claim names are overridable.
  • OAuthProviderProperties + ConfigurableUserInfoTokenVerifier — declare any provider purely via leaf.oauth.providers.<name> config, no code required.
  • OAuthProviderRegistry — now merges code-defined verifiers (google/apple/ampeco) with config-declared ones; skips entries missing userInfoUri and won't override built-ins.

Ampeco provider

  • AmpecoTokenVerifier — thin @Component on the base, tenant-configurable via leaf.oauth.ampeco.userInfoUri. Reachable at POST /api/account/oauth/ampeco. Google/Apple ID-token verifiers are untouched.

Config & docs

  • demo application.yml: Ampeco entry + commented providers: example.
  • library/README.md: OAuth2 section covering built-in providers and both extension paths.

Adding a provider via config only

leaf:
  oauth:
    providers:
      myprovider:
        userInfoUri: "https://example.com/oauth/userinfo"
        emailClaim: "email"   # optional claim overrides

For providers needing custom verification (e.g. locally validated ID tokens), implement OAuthTokenVerifier and expose it as a @Component.

Notes for reviewers

  • Existing OAuthTokenVerifier.verify(String) contract is reused; for userinfo-based providers the passed token is the access token (carried by the login action's idToken field).
  • HTTP/JSON uses the already-present Unirest + org.json dependencies; no new dependencies added.

@OxyFlax OxyFlax left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix the comment


@Autowired
private List<OAuthTokenVerifier> verifiers;
private static final Logger logger = LoggerFactory.getLogger(OAuthProviderRegistry.class);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot the indentation in this file is broken. Fix it

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — the file now uses tab indentation consistent with the rest of the codebase in 133cd9a.

Copilot AI commented Jun 8, 2026

Copy link
Copy Markdown
Author

@copilot fix the comment

Fixed the indentation in OAuthProviderRegistry.java (now tab-indented like the rest of the codebase) in 133cd9a.

Copilot AI requested a review from OxyFlax June 8, 2026 09:48
@OxyFlax
OxyFlax marked this pull request as ready for review June 8, 2026 09:51
@OxyFlax
OxyFlax requested a review from Copilot June 8, 2026 09:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds AMPECO as an OAuth2 login provider and introduces a reusable “userinfo endpoint” verification mechanism so additional OAuth2/OIDC providers can be enabled via configuration, without writing new Java code.

Changes:

  • Added a reusable AbstractUserInfoOAuthTokenVerifier base that calls a provider userinfo endpoint and maps standard OIDC claims into OAuthUserInfo.
  • Added configuration-driven provider registration (OAuthProviderProperties + ConfigurableUserInfoTokenVerifier) and updated OAuthProviderRegistry to merge built-in and config-declared providers.
  • Documented OAuth2 usage in library/README.md and updated the demo application.yml with AMPECO and an example config provider.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
library/src/main/java/fr/iolabs/leaf/authentication/oauth/OAuthProviderRegistry.java Registers built-in and config-defined verifiers and normalizes provider lookup.
library/src/main/java/fr/iolabs/leaf/authentication/oauth/OAuthProviderProperties.java Adds leaf.oauth.providers.* configuration model for userinfo-based providers.
library/src/main/java/fr/iolabs/leaf/authentication/oauth/ConfigurableUserInfoTokenVerifier.java Implements a verifier entirely backed by OAuthProviderProperties claim/userinfo config.
library/src/main/java/fr/iolabs/leaf/authentication/oauth/AmpecoTokenVerifier.java Adds AMPECO provider backed by the generic userinfo verifier base.
library/src/main/java/fr/iolabs/leaf/authentication/oauth/AbstractUserInfoOAuthTokenVerifier.java Provides the shared outbound userinfo call + claim mapping logic.
library/README.md Documents OAuth2 endpoint usage, built-in providers, and config-based extension.
demo/src/main/resources/application.yml Adds AMPECO config and a commented example for adding config-only providers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +42 to +53
for (Map.Entry<String, ProviderConfig> entry : this.providerProperties.getProviders().entrySet()) {
String provider = entry.getKey().toLowerCase();
if (Strings.isBlank(entry.getValue().getUserInfoUri())) {
logger.warn("Skipping OAuth provider '{}': missing userInfoUri", provider);
continue;
}
if (this.verifierMap.containsKey(provider)) {
logger.warn("Ignoring configuration for OAuth provider '{}': a built-in verifier already exists", provider);
continue;
}
this.verifierMap.put(provider, new ConfigurableUserInfoTokenVerifier(provider, entry.getValue()));
}
if (Strings.isBlank(provider)) {
throw new BadRequestException("Missing OAuth provider");
}
OAuthTokenVerifier verifier = verifierMap.get(provider.toLowerCase());
Comment on lines +111 to +114
HttpResponse<JsonNode> response = Unirest.get(userInfoUri)
.header("Authorization", "Bearer " + accessToken)
.header("Accept", "application/json")
.asJson();
Comment thread library/README.md
Comment on lines +97 to +101
Leaf provides turnkey OAuth2 login/registration. The frontend obtains a token
from the provider and posts it to:

POST /api/account/oauth/{provider}
{ "idToken": "<provider token>", "name": "<optional display name>" }
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants