Merge branch 'master' of https://github.com/Alfresco/alfresco-community-repo into fix/apps-3106_Remove_Character_Java_Doc

This commit is contained in:
Vedant Mehra
2025-01-10 12:07:56 +05:30
26 changed files with 384 additions and 376 deletions

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId> <artifactId>alfresco-community-repo-amps</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<modules> <modules>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId> <artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<modules> <modules>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-automation-community-repo</artifactId> <artifactId>alfresco-governance-services-automation-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<build> <build>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-parent</artifactId> <artifactId>alfresco-governance-services-community-parent</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<modules> <modules>

View File

@@ -8,7 +8,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId> <artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-governance-services-community-repo-parent</artifactId> <artifactId>alfresco-governance-services-community-repo-parent</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<build> <build>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<modules> <modules>

View File

@@ -8,7 +8,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-amps</artifactId> <artifactId>alfresco-community-repo-amps</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -9,6 +9,6 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
</project> </project>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<modules> <modules>

View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<modules> <modules>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId> <artifactId>alfresco-community-repo-tests</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<organization> <organization>

View File

@@ -9,7 +9,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId> <artifactId>alfresco-community-repo-tests</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<developers> <developers>

View File

@@ -9,7 +9,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId> <artifactId>alfresco-community-repo-tests</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<developers> <developers>

View File

@@ -8,7 +8,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId> <artifactId>alfresco-community-repo-tests</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>

View File

@@ -9,7 +9,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-tests</artifactId> <artifactId>alfresco-community-repo-tests</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<developers> <developers>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo-packaging</artifactId> <artifactId>alfresco-community-repo-packaging</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<properties> <properties>

View File

@@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Alfresco Community Repo Parent</name> <name>Alfresco Community Repo Parent</name>
@@ -53,7 +53,7 @@
<dependency.activiti.version>5.23.0</dependency.activiti.version> <dependency.activiti.version>5.23.0</dependency.activiti.version>
<dependency.alfresco-transform-core.version>5.1.5</dependency.alfresco-transform-core.version> <dependency.alfresco-transform-core.version>5.1.5</dependency.alfresco-transform-core.version>
<dependency.alfresco-transform-service.version>4.1.5</dependency.alfresco-transform-service.version> <dependency.alfresco-transform-service.version>4.1.5</dependency.alfresco-transform-service.version>
<dependency.alfresco-greenmail.version>7.0</dependency.alfresco-greenmail.version> <dependency.alfresco-greenmail.version>7.1</dependency.alfresco-greenmail.version>
<dependency.acs-event-model.version>1.0.2</dependency.acs-event-model.version> <dependency.acs-event-model.version>1.0.2</dependency.acs-event-model.version>
<dependency.aspectj.version>1.9.22.1</dependency.aspectj.version> <dependency.aspectj.version>1.9.22.1</dependency.aspectj.version>
@@ -79,7 +79,7 @@
<dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version> <dependency.commons-httpclient.version>3.1-HTTPCLIENT-1265</dependency.commons-httpclient.version>
<dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version> <dependency.xercesImpl.version>2.12.2</dependency.xercesImpl.version>
<dependency.slf4j.version>2.0.16</dependency.slf4j.version> <dependency.slf4j.version>2.0.16</dependency.slf4j.version>
<dependency.log4j.version>2.24.2</dependency.log4j.version> <dependency.log4j.version>2.24.3</dependency.log4j.version>
<dependency.groovy.version>3.0.23</dependency.groovy.version> <dependency.groovy.version>3.0.23</dependency.groovy.version>
<dependency.tika.version>2.9.2</dependency.tika.version> <dependency.tika.version>2.9.2</dependency.tika.version>
<dependency.truezip.version>7.7.10</dependency.truezip.version> <dependency.truezip.version>7.7.10</dependency.truezip.version>
@@ -1089,7 +1089,7 @@
<plugin> <plugin>
<groupId>org.codehaus.cargo</groupId> <groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId> <artifactId>cargo-maven3-plugin</artifactId>
<version>1.10.14</version> <version>1.10.16</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-community-repo</artifactId> <artifactId>alfresco-community-repo</artifactId>
<version>25.1.0.22-SNAPSHOT</version> <version>25.1.0.27-SNAPSHOT</version>
</parent> </parent>
<dependencies> <dependencies>

View File

@@ -191,9 +191,8 @@ public class NodeSizeDetailsServiceImpl implements NodeSizeDetailsService, Initi
} }
Date calculationDate = new Date(System.currentTimeMillis()); Date calculationDate = new Date(System.currentTimeMillis());
NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), totalSizeFromFacet, calculationDate, NodeSizeDetails nodeSizeDetails = new NodeSizeDetails(nodeRef.getId(), totalSizeFromFacet, calculationDate,
results.getNodeRefs() (int) results.getNumberFound(), STATUS.COMPLETED,
.size(), jobId);
STATUS.COMPLETED, jobId);
return nodeSizeDetails; return nodeSizeDetails;
} }
catch (Exception e) catch (Exception e)
@@ -396,5 +395,4 @@ public class NodeSizeDetailsServiceImpl implements NodeSizeDetailsService, Initi
} }
} }
}
}

View File

@@ -1,344 +1,354 @@
/* /*
* #%L * #%L
* Alfresco Repository * Alfresco Repository
* %% * %%
* Copyright (C) 2005 - 2025 Alfresco Software Limited * Copyright (C) 2005 - 2025 Alfresco Software Limited
* %% * %%
* This file is part of the Alfresco software. * This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of * If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is * the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms: * provided under the following open source license terms:
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L% * #L%
*/ */
package org.alfresco.repo.security.authentication.identityservice; package org.alfresco.repo.security.authentication.identityservice;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceMetadataKey.AUDIENCE; import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceMetadataKey.AUDIENCE;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.time.Instant; import java.time.Instant;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.ErrorObject;
import com.nimbusds.oauth2.sdk.token.BearerAccessToken; import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.openid.connect.sdk.UserInfoRequest; import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
import com.nimbusds.openid.connect.sdk.UserInfoResponse; import com.nimbusds.openid.connect.sdk.UserInfoErrorResponse;
import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse; import com.nimbusds.openid.connect.sdk.UserInfoRequest;
import com.nimbusds.openid.connect.sdk.UserInfoResponse;
import org.apache.commons.logging.Log; import com.nimbusds.openid.connect.sdk.UserInfoSuccessResponse;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log;
import org.springframework.core.convert.converter.Converter; import org.apache.commons.logging.LogFactory;
import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequest; import org.springframework.core.convert.converter.Converter;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.AbstractOAuth2AuthorizationGrantRequest;
import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.DefaultPasswordTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequestEntityConverter; import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest;
import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest; import org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequestEntityConverter;
import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest;
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails; import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AbstractOAuth2Token; import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.AbstractOAuth2Token;
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2AccessToken.TokenType; import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthorizationException; import org.springframework.security.oauth2.core.OAuth2AccessToken.TokenType;
import org.springframework.security.oauth2.core.OAuth2RefreshToken; import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.OAuth2RefreshToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.util.MultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestOperations; import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestOperations;
class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
{ class SpringBasedIdentityServiceFacade implements IdentityServiceFacade
private static final Log LOGGER = LogFactory.getLog(SpringBasedIdentityServiceFacade.class); {
private static final Instant SOME_INSIGNIFICANT_DATE_IN_THE_PAST = Instant.MIN.plusSeconds(12345); private static final Log LOGGER = LogFactory.getLog(SpringBasedIdentityServiceFacade.class);
private final Map<AuthorizationGrantType, OAuth2AccessTokenResponseClient> clients; private static final Instant SOME_INSIGNIFICANT_DATE_IN_THE_PAST = Instant.MIN.plusSeconds(12345);
private final ClientRegistration clientRegistration; private final Map<AuthorizationGrantType, OAuth2AccessTokenResponseClient> clients;
private final JwtDecoder jwtDecoder; private final ClientRegistration clientRegistration;
private final JwtDecoder jwtDecoder;
SpringBasedIdentityServiceFacade(RestOperations restOperations, ClientRegistration clientRegistration,
JwtDecoder jwtDecoder) SpringBasedIdentityServiceFacade(RestOperations restOperations, ClientRegistration clientRegistration,
{ JwtDecoder jwtDecoder)
requireNonNull(restOperations); {
this.clientRegistration = requireNonNull(clientRegistration); requireNonNull(restOperations);
this.jwtDecoder = requireNonNull(jwtDecoder); this.clientRegistration = requireNonNull(clientRegistration);
this.clients = Map.of( this.jwtDecoder = requireNonNull(jwtDecoder);
AuthorizationGrantType.AUTHORIZATION_CODE, createAuthorizationCodeClient(restOperations), this.clients = Map.of(
AuthorizationGrantType.REFRESH_TOKEN, createRefreshTokenClient(restOperations), AuthorizationGrantType.AUTHORIZATION_CODE, createAuthorizationCodeClient(restOperations),
AuthorizationGrantType.PASSWORD, createPasswordClient(restOperations, clientRegistration)); AuthorizationGrantType.REFRESH_TOKEN, createRefreshTokenClient(restOperations),
} AuthorizationGrantType.PASSWORD, createPasswordClient(restOperations, clientRegistration));
}
@Override
public AccessTokenAuthorization authorize(AuthorizationGrant authorizationGrant) @Override
{ public AccessTokenAuthorization authorize(AuthorizationGrant authorizationGrant)
final AbstractOAuth2AuthorizationGrantRequest request = createRequest(authorizationGrant); {
final OAuth2AccessTokenResponseClient client = getClient(request); final AbstractOAuth2AuthorizationGrantRequest request = createRequest(authorizationGrant);
final OAuth2AccessTokenResponseClient client = getClient(request);
final OAuth2AccessTokenResponse response;
try final OAuth2AccessTokenResponse response;
{ try
response = client.getTokenResponse(request); {
} response = client.getTokenResponse(request);
catch (OAuth2AuthorizationException e) }
{ catch (OAuth2AuthorizationException e)
LOGGER.debug("Failed to authorize against Authorization Server. Reason: " + e.getError() + "."); {
throw new AuthorizationException("Failed to obtain access token. " + e.getError(), e); LOGGER.debug("Failed to authorize against Authorization Server. Reason: " + e.getError() + ".");
} throw new AuthorizationException("Failed to obtain access token. " + e.getError(), e);
catch (RuntimeException e) }
{ catch (RuntimeException e)
LOGGER.warn("Failed to authorize against Authorization Server. Reason: " + e.getMessage()); {
throw new AuthorizationException("Failed to obtain access token.", e); LOGGER.warn("Failed to authorize against Authorization Server. Reason: " + e.getMessage());
} throw new AuthorizationException("Failed to obtain access token.", e);
}
return new SpringAccessTokenAuthorization(response);
} return new SpringAccessTokenAuthorization(response);
}
@Override
public Optional<OIDCUserInfo> getUserInfo(String tokenParameter, String principalAttribute) @Override
{ public Optional<OIDCUserInfo> getUserInfo(String tokenParameter, String principalAttribute)
return Optional.ofNullable(tokenParameter) {
.filter(Predicate.not(String::isEmpty)) return Optional.ofNullable(tokenParameter)
.flatMap(token -> Optional.ofNullable(clientRegistration) .filter(Predicate.not(String::isEmpty))
.map(ClientRegistration::getProviderDetails) .flatMap(token -> Optional.ofNullable(clientRegistration)
.map(ClientRegistration.ProviderDetails::getUserInfoEndpoint) .map(ClientRegistration::getProviderDetails)
.map(ClientRegistration.ProviderDetails.UserInfoEndpoint::getUri) .map(ClientRegistration.ProviderDetails::getUserInfoEndpoint)
.flatMap(uri -> { .map(ClientRegistration.ProviderDetails.UserInfoEndpoint::getUri)
try .flatMap(uri -> {
{ try
return Optional.of( {
new UserInfoRequest(new URI(uri), new BearerAccessToken(token)).toHTTPRequest().send()); return Optional.of(
} new UserInfoRequest(new URI(uri), new BearerAccessToken(token)).toHTTPRequest().send());
catch (IOException | URISyntaxException e) }
{ catch (IOException | URISyntaxException e)
LOGGER.warn("Failed to get user information. Reason: " + e.getMessage()); {
return Optional.empty(); LOGGER.warn("Failed to get user information. Reason: " + e.getMessage());
} return Optional.empty();
}) }
.flatMap(httpResponse -> { })
try .flatMap(httpResponse -> {
{ try
return Optional.of(UserInfoResponse.parse(httpResponse)); {
} UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse);
catch (ParseException e)
{ if (userInfoResponse instanceof UserInfoErrorResponse userInfoErrorResponse)
LOGGER.warn("Failed to parse user info response. Reason: " + e.getMessage()); {
return Optional.empty(); String errorMessage = Optional.ofNullable(userInfoErrorResponse.getErrorObject())
} .map(ErrorObject::getDescription)
}) .orElse("No error description found");
.map(UserInfoResponse::toSuccessResponse) LOGGER.warn("User Info Request failed: " + errorMessage);
.map(UserInfoSuccessResponse::getUserInfo)) throw new UserInfoException(errorMessage);
.map(userInfo -> new OIDCUserInfo(userInfo.getStringClaim(principalAttribute), userInfo.getGivenName(), }
userInfo.getFamilyName(), userInfo.getEmailAddress())); return Optional.of(userInfoResponse);
} }
catch (ParseException e)
@Override {
public ClientRegistration getClientRegistration() LOGGER.warn("Failed to parse user info response. Reason: " + e.getMessage());
{ return Optional.empty();
return clientRegistration; }
} })
.map(UserInfoResponse::toSuccessResponse)
@Override .map(UserInfoSuccessResponse::getUserInfo))
public DecodedAccessToken decodeToken(String token) .map(userInfo -> new OIDCUserInfo(userInfo.getStringClaim(principalAttribute), userInfo.getGivenName(),
{ userInfo.getFamilyName(), userInfo.getEmailAddress()));
final Jwt validToken; }
try
{ @Override
validToken = jwtDecoder.decode(token); public ClientRegistration getClientRegistration()
} {
catch (RuntimeException e) return clientRegistration;
{ }
throw new TokenDecodingException("Failed to decode token. " + e.getMessage(), e);
} @Override
if (LOGGER.isDebugEnabled()) public DecodedAccessToken decodeToken(String token)
{ {
LOGGER.debug("Bearer token outcome: " + validToken.getClaims()); final Jwt validToken;
} try
return new SpringDecodedAccessToken(validToken); {
} validToken = jwtDecoder.decode(token);
}
private AbstractOAuth2AuthorizationGrantRequest createRequest(AuthorizationGrant grant) catch (RuntimeException e)
{ {
if (grant.isPassword()) throw new TokenDecodingException("Failed to decode token. " + e.getMessage(), e);
{ }
return new OAuth2PasswordGrantRequest(clientRegistration, grant.getUsername(), grant.getPassword()); if (LOGGER.isDebugEnabled())
} {
LOGGER.debug("Bearer token outcome: " + validToken.getClaims());
if (grant.isRefreshToken()) }
{ return new SpringDecodedAccessToken(validToken);
final OAuth2AccessToken expiredAccessToken = new OAuth2AccessToken( }
TokenType.BEARER,
"JUST_FOR_FULFILLING_THE_SPRING_API", private AbstractOAuth2AuthorizationGrantRequest createRequest(AuthorizationGrant grant)
SOME_INSIGNIFICANT_DATE_IN_THE_PAST, {
SOME_INSIGNIFICANT_DATE_IN_THE_PAST.plusSeconds(1)); if (grant.isPassword())
final OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(grant.getRefreshToken(), null); {
return new OAuth2PasswordGrantRequest(clientRegistration, grant.getUsername(), grant.getPassword());
return new OAuth2RefreshTokenGrantRequest(clientRegistration, expiredAccessToken, refreshToken, }
clientRegistration.getScopes());
} if (grant.isRefreshToken())
{
if (grant.isAuthorizationCode()) final OAuth2AccessToken expiredAccessToken = new OAuth2AccessToken(
{ TokenType.BEARER,
final OAuth2AuthorizationExchange authzExchange = new OAuth2AuthorizationExchange( "JUST_FOR_FULFILLING_THE_SPRING_API",
OAuth2AuthorizationRequest.authorizationCode() SOME_INSIGNIFICANT_DATE_IN_THE_PAST,
.clientId(clientRegistration.getClientId()) SOME_INSIGNIFICANT_DATE_IN_THE_PAST.plusSeconds(1));
.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri()) final OAuth2RefreshToken refreshToken = new OAuth2RefreshToken(grant.getRefreshToken(), null);
.redirectUri(grant.getRedirectUri())
.scopes(clientRegistration.getScopes()) return new OAuth2RefreshTokenGrantRequest(clientRegistration, expiredAccessToken, refreshToken,
.build(), clientRegistration.getScopes());
OAuth2AuthorizationResponse.success(grant.getAuthorizationCode()) }
.redirectUri(grant.getRedirectUri())
.build() if (grant.isAuthorizationCode())
); {
return new OAuth2AuthorizationCodeGrantRequest(clientRegistration, authzExchange); final OAuth2AuthorizationExchange authzExchange = new OAuth2AuthorizationExchange(
} OAuth2AuthorizationRequest.authorizationCode()
.clientId(clientRegistration.getClientId())
throw new UnsupportedOperationException("Unsupported grant type."); .authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
} .redirectUri(grant.getRedirectUri())
.scopes(clientRegistration.getScopes())
private OAuth2AccessTokenResponseClient getClient(AbstractOAuth2AuthorizationGrantRequest request) .build(),
{ OAuth2AuthorizationResponse.success(grant.getAuthorizationCode())
final AuthorizationGrantType grantType = request.getGrantType(); .redirectUri(grant.getRedirectUri())
final OAuth2AccessTokenResponseClient client = clients.get(grantType); .build());
if (client == null) return new OAuth2AuthorizationCodeGrantRequest(clientRegistration, authzExchange);
{ }
throw new UnsupportedOperationException("Unsupported grant type `" + grantType + "`.");
} throw new UnsupportedOperationException("Unsupported grant type.");
return client; }
}
private OAuth2AccessTokenResponseClient getClient(AbstractOAuth2AuthorizationGrantRequest request)
private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createAuthorizationCodeClient( {
RestOperations rest) final AuthorizationGrantType grantType = request.getGrantType();
{ final OAuth2AccessTokenResponseClient client = clients.get(grantType);
final DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient(); if (client == null)
client.setRestOperations(rest); {
return client; throw new UnsupportedOperationException("Unsupported grant type `" + grantType + "`.");
} }
return client;
private static OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> createRefreshTokenClient( }
RestOperations rest)
{ private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createAuthorizationCodeClient(
final DefaultRefreshTokenTokenResponseClient client = new DefaultRefreshTokenTokenResponseClient(); RestOperations rest)
client.setRestOperations(rest); {
return client; final DefaultAuthorizationCodeTokenResponseClient client = new DefaultAuthorizationCodeTokenResponseClient();
} client.setRestOperations(rest);
return client;
private static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> createPasswordClient(RestOperations rest, }
ClientRegistration clientRegistration)
{ private static OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> createRefreshTokenClient(
final DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient(); RestOperations rest)
client.setRestOperations(rest); {
Optional.of(clientRegistration) final DefaultRefreshTokenTokenResponseClient client = new DefaultRefreshTokenTokenResponseClient();
.map(ClientRegistration::getProviderDetails) client.setRestOperations(rest);
.map(ProviderDetails::getConfigurationMetadata) return client;
.map(metadata -> metadata.get(AUDIENCE.getValue())) }
.filter(String.class::isInstance)
.map(String.class::cast) private static OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> createPasswordClient(RestOperations rest,
.ifPresent(audienceValue -> { ClientRegistration clientRegistration)
final OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter(); {
requestEntityConverter.addParametersConverter(audienceParameterConverter(audienceValue)); final DefaultPasswordTokenResponseClient client = new DefaultPasswordTokenResponseClient();
client.setRequestEntityConverter(requestEntityConverter); client.setRestOperations(rest);
}); Optional.of(clientRegistration)
return client; .map(ClientRegistration::getProviderDetails)
} .map(ProviderDetails::getConfigurationMetadata)
.map(metadata -> metadata.get(AUDIENCE.getValue()))
private static Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> audienceParameterConverter( .filter(String.class::isInstance)
String audienceValue) .map(String.class::cast)
{ .ifPresent(audienceValue -> {
return (grantRequest) -> { final OAuth2PasswordGrantRequestEntityConverter requestEntityConverter = new OAuth2PasswordGrantRequestEntityConverter();
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); requestEntityConverter.addParametersConverter(audienceParameterConverter(audienceValue));
parameters.set("audience", audienceValue); client.setRequestEntityConverter(requestEntityConverter);
});
return parameters; return client;
}; }
}
private static Converter<OAuth2PasswordGrantRequest, MultiValueMap<String, String>> audienceParameterConverter(
private static class SpringAccessTokenAuthorization implements AccessTokenAuthorization String audienceValue)
{ {
private final OAuth2AccessTokenResponse tokenResponse; return (grantRequest) -> {
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
private SpringAccessTokenAuthorization(OAuth2AccessTokenResponse tokenResponse) parameters.set("audience", audienceValue);
{
this.tokenResponse = requireNonNull(tokenResponse); return parameters;
} };
}
@Override
public AccessToken getAccessToken() private static class SpringAccessTokenAuthorization implements AccessTokenAuthorization
{ {
return new SpringAccessToken(tokenResponse.getAccessToken()); private final OAuth2AccessTokenResponse tokenResponse;
}
private SpringAccessTokenAuthorization(OAuth2AccessTokenResponse tokenResponse)
@Override {
public String getRefreshTokenValue() this.tokenResponse = requireNonNull(tokenResponse);
{ }
return Optional.of(tokenResponse)
.map(OAuth2AccessTokenResponse::getRefreshToken) @Override
.map(AbstractOAuth2Token::getTokenValue) public AccessToken getAccessToken()
.orElse(null); {
} return new SpringAccessToken(tokenResponse.getAccessToken());
} }
private static class SpringAccessToken implements AccessToken @Override
{ public String getRefreshTokenValue()
private final AbstractOAuth2Token token; {
return Optional.of(tokenResponse)
private SpringAccessToken(AbstractOAuth2Token token) .map(OAuth2AccessTokenResponse::getRefreshToken)
{ .map(AbstractOAuth2Token::getTokenValue)
this.token = requireNonNull(token); .orElse(null);
} }
}
@Override
public String getTokenValue() private static class SpringAccessToken implements AccessToken
{ {
return token.getTokenValue(); private final AbstractOAuth2Token token;
}
private SpringAccessToken(AbstractOAuth2Token token)
@Override {
public Instant getExpiresAt() this.token = requireNonNull(token);
{ }
return token.getExpiresAt();
} @Override
} public String getTokenValue()
{
private static class SpringDecodedAccessToken extends SpringAccessToken implements DecodedAccessToken return token.getTokenValue();
{ }
private final Jwt jwt;
@Override
private SpringDecodedAccessToken(Jwt jwt) public Instant getExpiresAt()
{ {
super(jwt); return token.getExpiresAt();
this.jwt = jwt; }
} }
@Override private static class SpringDecodedAccessToken extends SpringAccessToken implements DecodedAccessToken
public Object getClaim(String claim) {
{ private final Jwt jwt;
return jwt.getClaim(claim);
} private SpringDecodedAccessToken(Jwt jwt)
} {
} super(jwt);
this.jwt = jwt;
}
@Override
public Object getClaim(String claim)
{
return jwt.getClaim(claim);
}
}
}