From db35dc6c039d5991231effdc0aa28371ffb721b3 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Thu, 2 Nov 2017 11:54:06 -0400 Subject: [PATCH] Add tests to oauth2-core Fixes gh-4298 --- .../spring-security-oauth2-core.gradle | 2 + .../oauth2/core/AbstractOAuth2Token.java | 1 + .../security/oauth2/core/ClaimAccessor.java | 2 +- .../oidc/DefaultAddressStandardClaim.java | 40 +++++ .../core/AuthorizationGrantTypeTests.java | 43 ++++++ .../core/ClientAuthenticationMethodTests.java | 43 ++++++ .../oauth2/core/OAuth2AccessTokenTests.java | 85 +++++++++++ .../oauth2/core/OAuth2ErrorTests.java | 45 ++++++ .../OAuth2AccessTokenResponseTests.java | 68 ++++++--- .../OAuth2AuthorizationExchangeTests.java | 54 +++++++ .../OAuth2AuthorizationRequestTests.java | 136 ++++++++++------- .../OAuth2AuthorizationResponseTests.java | 127 ++++++++++++++++ .../OAuth2AuthorizationResponseTypeTests.java | 38 +++++ .../DefaultAddressStandardClaimTests.java | 85 +++++++++++ .../oauth2/core/oidc/OidcIdTokenTests.java | 121 +++++++++++++++ .../oauth2/core/oidc/OidcUserInfoTests.java | 142 ++++++++++++++++++ .../core/oidc/user/DefaultOidcUserTests.java | 130 ++++++++-------- .../oidc/user/OidcUserAuthorityTests.java | 79 ++++++++++ .../core/user/DefaultOAuth2UserTests.java | 100 +++++------- .../core/user/OAuth2UserAuthorityTests.java | 56 +++++++ 20 files changed, 1187 insertions(+), 210 deletions(-) create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/AuthorizationGrantTypeTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/ClientAuthenticationMethodTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2AccessTokenTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2ErrorTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationExchangeTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTypeTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaimTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcIdTokenTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcUserInfoTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthorityTests.java create mode 100644 oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthorityTests.java diff --git a/oauth2/oauth2-core/spring-security-oauth2-core.gradle b/oauth2/oauth2-core/spring-security-oauth2-core.gradle index 903859942a..0a477bf7c3 100644 --- a/oauth2/oauth2-core/spring-security-oauth2-core.gradle +++ b/oauth2/oauth2-core/spring-security-oauth2-core.gradle @@ -3,4 +3,6 @@ apply plugin: 'io.spring.convention.spring-module' dependencies { compile project(':spring-security-core') compile springCoreDependency + + testCompile powerMock2Dependencies } diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2Token.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2Token.java index 44f181b405..4ce79440d0 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2Token.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2Token.java @@ -37,6 +37,7 @@ public abstract class AbstractOAuth2Token implements Serializable { Assert.hasText(tokenValue, "tokenValue cannot be empty"); Assert.notNull(issuedAt, "issuedAt cannot be null"); Assert.notNull(expiresAt, "expiresAt cannot be null"); + Assert.isTrue(expiresAt.isAfter(issuedAt), "expiresAt must be after issuedAt"); this.tokenValue = tokenValue; this.issuedAt = issuedAt; this.expiresAt = expiresAt; diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClaimAccessor.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClaimAccessor.java index c217a98761..0d106f0eb2 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClaimAccessor.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/ClaimAccessor.java @@ -53,7 +53,7 @@ public interface ClaimAccessor { return null; } try { - return Instant.ofEpochSecond(Long.valueOf(this.getClaimAsString(claim))); + return Instant.ofEpochMilli(Long.valueOf(this.getClaimAsString(claim))); } catch (NumberFormatException ex) { throw new IllegalArgumentException("Unable to convert claim '" + claim + "' to Instant: " + ex.getMessage(), ex); } diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaim.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaim.java index 3b4ab6f373..0a6b36cc98 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaim.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaim.java @@ -65,6 +65,46 @@ public final class DefaultAddressStandardClaim implements AddressStandardClaim { return this.country; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !AddressStandardClaim.class.isAssignableFrom(obj.getClass())) { + return false; + } + + AddressStandardClaim that = (AddressStandardClaim) obj; + + if (this.getFormatted() != null ? !this.getFormatted().equals(that.getFormatted()) : that.getFormatted() != null) { + return false; + } + if (this.getStreetAddress() != null ? !this.getStreetAddress().equals(that.getStreetAddress()) : that.getStreetAddress() != null) { + return false; + } + if (this.getLocality() != null ? !this.getLocality().equals(that.getLocality()) : that.getLocality() != null) { + return false; + } + if (this.getRegion() != null ? !this.getRegion().equals(that.getRegion()) : that.getRegion() != null) { + return false; + } + if (this.getPostalCode() != null ? !this.getPostalCode().equals(that.getPostalCode()) : that.getPostalCode() != null) { + return false; + } + return this.getCountry() != null ? this.getCountry().equals(that.getCountry()) : that.getCountry() == null; + } + + @Override + public int hashCode() { + int result = this.getFormatted() != null ? this.getFormatted().hashCode() : 0; + result = 31 * result + (this.getStreetAddress() != null ? this.getStreetAddress().hashCode() : 0); + result = 31 * result + (this.getLocality() != null ? this.getLocality().hashCode() : 0); + result = 31 * result + (this.getRegion() != null ? this.getRegion().hashCode() : 0); + result = 31 * result + (this.getPostalCode() != null ? this.getPostalCode().hashCode() : 0); + result = 31 * result + (this.getCountry() != null ? this.getCountry().hashCode() : 0); + return result; + } + public static class Builder { private static final String FORMATTED_FIELD_NAME = "formatted"; private static final String STREET_ADDRESS_FIELD_NAME = "street_address"; diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/AuthorizationGrantTypeTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/AuthorizationGrantTypeTests.java new file mode 100644 index 0000000000..dea90e92b1 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/AuthorizationGrantTypeTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AuthorizationGrantType}. + * + * @author Joe Grandja + */ +public class AuthorizationGrantTypeTests { + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenValueIsNullThenThrowIllegalArgumentException() { + new AuthorizationGrantType(null); + } + + @Test + public void getValueWhenAuthorizationCodeGrantTypeThenReturnAuthorizationCode() { + assertThat(AuthorizationGrantType.AUTHORIZATION_CODE.getValue()).isEqualTo("authorization_code"); + } + + @Test + public void getValueWhenImplicitGrantTypeThenReturnImplicit() { + assertThat(AuthorizationGrantType.IMPLICIT.getValue()).isEqualTo("implicit"); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/ClientAuthenticationMethodTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/ClientAuthenticationMethodTests.java new file mode 100644 index 0000000000..c21d4c72c4 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/ClientAuthenticationMethodTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ClientAuthenticationMethod}. + * + * @author Joe Grandja + */ +public class ClientAuthenticationMethodTests { + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenValueIsNullThenThrowIllegalArgumentException() { + new ClientAuthenticationMethod(null); + } + + @Test + public void getValueWhenAuthenticationMethodBasicThenReturnBasic() { + assertThat(ClientAuthenticationMethod.BASIC.getValue()).isEqualTo("basic"); + } + + @Test + public void getValueWhenAuthenticationMethodPostThenReturnPost() { + assertThat(ClientAuthenticationMethod.POST.getValue()).isEqualTo("post"); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2AccessTokenTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2AccessTokenTests.java new file mode 100644 index 0000000000..e79142c3bd --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2AccessTokenTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core; + +import org.junit.Test; + +import java.time.Instant; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OAuth2AccessToken}. + * + * @author Joe Grandja + */ +public class OAuth2AccessTokenTests { + private static final OAuth2AccessToken.TokenType TOKEN_TYPE = OAuth2AccessToken.TokenType.BEARER; + private static final String TOKEN_VALUE = "access-token"; + private static final Instant ISSUED_AT = Instant.now(); + private static final Instant EXPIRES_AT = Instant.from(ISSUED_AT).plusSeconds(60); + private static final Set SCOPES = new LinkedHashSet<>(Arrays.asList("scope1", "scope2")); + + @Test + public void tokenTypeGetValueWhenTokenTypeBearerThenReturnBearer() { + assertThat(OAuth2AccessToken.TokenType.BEARER.getValue()).isEqualTo("Bearer"); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenTokenTypeIsNullThenThrowIllegalArgumentException() { + new OAuth2AccessToken(null, TOKEN_VALUE, ISSUED_AT, EXPIRES_AT); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenTokenValueIsNullThenThrowIllegalArgumentException() { + new OAuth2AccessToken(TOKEN_TYPE, null, ISSUED_AT, EXPIRES_AT); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenIssuedAtIsNullThenThrowIllegalArgumentException() { + new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, null, EXPIRES_AT); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenExpiresAtIsNullThenThrowIllegalArgumentException() { + new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, ISSUED_AT, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenIssuedAtAfterExpiresAtThenThrowIllegalArgumentException() { + new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, Instant.from(EXPIRES_AT).plusSeconds(1), EXPIRES_AT); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenExpiresAtBeforeIssuedAtThenThrowIllegalArgumentException() { + new OAuth2AccessToken(TOKEN_TYPE, TOKEN_VALUE, ISSUED_AT, Instant.from(ISSUED_AT).minusSeconds(1)); + } + + @Test + public void constructorWhenAllParametersProvidedAndValidThenCreated() { + OAuth2AccessToken accessToken = new OAuth2AccessToken( + TOKEN_TYPE, TOKEN_VALUE, ISSUED_AT, EXPIRES_AT, SCOPES); + + assertThat(accessToken.getTokenType()).isEqualTo(TOKEN_TYPE); + assertThat(accessToken.getTokenValue()).isEqualTo(TOKEN_VALUE); + assertThat(accessToken.getIssuedAt()).isEqualTo(ISSUED_AT); + assertThat(accessToken.getExpiresAt()).isEqualTo(EXPIRES_AT); + assertThat(accessToken.getScopes()).isEqualTo(SCOPES); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2ErrorTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2ErrorTests.java new file mode 100644 index 0000000000..4d75bb901e --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/OAuth2ErrorTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OAuth2Error}. + * + * @author Joe Grandja + */ +public class OAuth2ErrorTests { + private static final String ERROR_CODE = "error-code"; + private static final String ERROR_DESCRIPTION = "error-description"; + private static final String ERROR_URI = "error-uri"; + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenErrorCodeIsNullThenThrowIllegalArgumentException() { + new OAuth2Error(null, ERROR_DESCRIPTION, ERROR_URI); + } + + @Test + public void constructorWhenAllParametersProvidedAndValidThenCreated() { + OAuth2Error error = new OAuth2Error(ERROR_CODE, ERROR_DESCRIPTION, ERROR_URI); + + assertThat(error.getErrorCode()).isEqualTo(ERROR_CODE); + assertThat(error.getDescription()).isEqualTo(ERROR_DESCRIPTION); + assertThat(error.getUri()).isEqualTo(ERROR_URI); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AccessTokenResponseTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AccessTokenResponseTests.java index 56c63a1026..7852ec07e8 100644 --- a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AccessTokenResponseTests.java +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AccessTokenResponseTests.java @@ -18,53 +18,71 @@ package org.springframework.security.oauth2.core.endpoint; import org.junit.Test; import org.springframework.security.oauth2.core.OAuth2AccessToken; -import java.util.Collections; +import java.time.Instant; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; /** - * Tests {@link OAuth2AccessTokenResponse} + * Tests for {@link OAuth2AccessTokenResponse}. * * @author Luander Ribeiro + * @author Joe Grandja */ public class OAuth2AccessTokenResponseTests { - - private static final String TOKEN = "token"; - private static final long INVALID_EXPIRES_IN = -1L; - private static final long EXPIRES_IN = System.currentTimeMillis(); + private static final String TOKEN_VALUE = "access-token"; + private static final long EXPIRES_IN = Instant.now().plusSeconds(5).toEpochMilli(); @Test(expected = IllegalArgumentException.class) public void buildWhenTokenValueIsNullThenThrowIllegalArgumentException() { OAuth2AccessTokenResponse.withToken(null) - .expiresIn(EXPIRES_IN) - .additionalParameters(Collections.emptyMap()) - .scopes(Collections.emptySet()) .tokenType(OAuth2AccessToken.TokenType.BEARER) + .expiresIn(EXPIRES_IN) .build(); } @Test(expected = IllegalArgumentException.class) - public void buildWhenExpiresInIsNegativeThenThrowIllegalArgumentException() { - OAuth2AccessTokenResponse.withToken(TOKEN) - .expiresIn(INVALID_EXPIRES_IN) - .additionalParameters(Collections.emptyMap()) - .scopes(Collections.emptySet()) - .tokenType(OAuth2AccessToken.TokenType.BEARER) + public void buildWhenTokenTypeIsNullThenThrowIllegalArgumentException() { + OAuth2AccessTokenResponse.withToken(TOKEN_VALUE) + .tokenType(null) + .expiresIn(EXPIRES_IN) .build(); } @Test(expected = IllegalArgumentException.class) - public void buildWhenTokenTypeIsInvalidThenThrowIllegalArgumentException() { - OAuth2AccessTokenResponse.withToken(TOKEN) - .expiresIn(EXPIRES_IN) - .additionalParameters(Collections.emptyMap()) - .tokenType(null) + public void buildWhenExpiresInIsNegativeThenThrowIllegalArgumentException() { + OAuth2AccessTokenResponse.withToken(TOKEN_VALUE) + .tokenType(OAuth2AccessToken.TokenType.BEARER) + .expiresIn(-1L) .build(); } - @Test(expected = IllegalArgumentException.class) - public void buildWhenTokenTypeNotSetThenThrowIllegalArgumentException() { - OAuth2AccessTokenResponse.withToken(TOKEN) - .expiresIn(EXPIRES_IN) - .additionalParameters(Collections.emptyMap()) + @Test + public void buildWhenAllAttributesProvidedThenAllAttributesAreSet() { + Instant expiresAt = Instant.now().plusSeconds(5); + Set scopes = new LinkedHashSet<>(Arrays.asList("scope1", "scope2")); + Map additionalParameters = new HashMap<>(); + additionalParameters.put("param1", "value1"); + additionalParameters.put("param2", "value2"); + + OAuth2AccessTokenResponse tokenResponse = OAuth2AccessTokenResponse + .withToken(TOKEN_VALUE) + .tokenType(OAuth2AccessToken.TokenType.BEARER) + .expiresIn(expiresAt.toEpochMilli()) + .scopes(scopes) + .additionalParameters(additionalParameters) .build(); + + assertThat(tokenResponse.getAccessToken()).isNotNull(); + assertThat(tokenResponse.getAccessToken().getTokenValue()).isEqualTo(TOKEN_VALUE); + assertThat(tokenResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER); + assertThat(tokenResponse.getAccessToken().getIssuedAt()).isNotNull(); + assertThat(tokenResponse.getAccessToken().getExpiresAt()).isAfterOrEqualTo(expiresAt); + assertThat(tokenResponse.getAccessToken().getScopes()).isEqualTo(scopes); + assertThat(tokenResponse.getAdditionalParameters()).isEqualTo(additionalParameters); } } diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationExchangeTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationExchangeTests.java new file mode 100644 index 0000000000..99c59f50c6 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationExchangeTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.endpoint; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link OAuth2AuthorizationExchange}. + * + * @author Joe Grandja + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({OAuth2AuthorizationExchange.class, OAuth2AuthorizationRequest.class, OAuth2AuthorizationResponse.class}) +public class OAuth2AuthorizationExchangeTests { + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthorizationRequestIsNullThenThrowIllegalArgumentException() { + new OAuth2AuthorizationExchange(null, mock(OAuth2AuthorizationResponse.class)); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthorizationResponseIsNullThenThrowIllegalArgumentException() { + new OAuth2AuthorizationExchange(mock(OAuth2AuthorizationRequest.class), null); + } + + @Test + public void constructorWhenRequiredArgsProvidedThenCreated() { + OAuth2AuthorizationRequest authorizationRequest = mock(OAuth2AuthorizationRequest.class); + OAuth2AuthorizationResponse authorizationResponse = mock(OAuth2AuthorizationResponse.class); + OAuth2AuthorizationExchange authorizationExchange = + new OAuth2AuthorizationExchange(authorizationRequest, authorizationResponse); + assertThat(authorizationExchange.getAuthorizationRequest()).isEqualTo(authorizationRequest); + assertThat(authorizationExchange.getAuthorizationResponse()).isEqualTo(authorizationResponse); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationRequestTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationRequestTests.java index 89b32d4c6b..70ccd4caf1 100644 --- a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationRequestTests.java +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationRequestTests.java @@ -16,24 +16,34 @@ package org.springframework.security.oauth2.core.endpoint; import org.junit.Test; - -import java.util.Collections; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.security.oauth2.core.AuthorizationGrantType; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; /** - * Tests {@link OAuth2AuthorizationRequest} + * Tests for {@link OAuth2AuthorizationRequest}. * * @author Luander Ribeiro + * @author Joe Grandja */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(OAuth2AuthorizationRequest.class) public class OAuth2AuthorizationRequestTests { - private static final String AUTHORIZE_URI = "http://authorize.uri/"; - private static final String CLIENT_ID = "client id"; - private static final String REDIRECT_URI = "http://redirect.uri/"; - private static final Set SCOPE = Collections.singleton("scope"); - private static final String STATE = "xyz"; + private static final String AUTHORIZATION_URI = "https://provider.com/oauth2/authorize"; + private static final String CLIENT_ID = "client-id"; + private static final String REDIRECT_URI = "http://example.com"; + private static final Set SCOPES = new LinkedHashSet<>(Arrays.asList("scope1", "scope2")); + private static final String STATE = "state"; @Test(expected = IllegalArgumentException.class) public void buildWhenAuthorizationUriIsNullThenThrowIllegalArgumentException() { @@ -41,17 +51,7 @@ public class OAuth2AuthorizationRequestTests { .authorizationUri(null) .clientId(CLIENT_ID) .redirectUri(REDIRECT_URI) - .scopes(SCOPE) - .state(STATE) - .build(); - } - - @Test(expected = IllegalArgumentException.class) - public void buildWhenAuthorizeUriNotSetThenThrowIllegalArgumentException() { - OAuth2AuthorizationRequest.authorizationCode() - .clientId(CLIENT_ID) - .redirectUri(REDIRECT_URI) - .scopes(SCOPE) + .scopes(SCOPES) .state(STATE) .build(); } @@ -59,76 +59,94 @@ public class OAuth2AuthorizationRequestTests { @Test(expected = IllegalArgumentException.class) public void buildWhenClientIdIsNullThenThrowIllegalArgumentException() { OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + .authorizationUri(AUTHORIZATION_URI) .clientId(null) .redirectUri(REDIRECT_URI) - .scopes(SCOPE) + .scopes(SCOPES) .state(STATE) .build(); } @Test(expected = IllegalArgumentException.class) - public void buildWhenClientIdNotSetThenThrowIllegalArgumentException() { - OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) - .redirectUri(REDIRECT_URI) - .scopes(SCOPE) + public void buildWhenRedirectUriIsNullForImplicitThenThrowIllegalArgumentException() { + OAuth2AuthorizationRequest.implicit() + .authorizationUri(AUTHORIZATION_URI) + .clientId(CLIENT_ID) + .redirectUri(null) + .scopes(SCOPES) .state(STATE) .build(); } @Test - public void buildWhenGetResponseTypeIsCalledThenReturnCode() { - OAuth2AuthorizationRequest authorizationRequest; - authorizationRequest = OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + public void buildWhenRedirectUriIsNullForAuthorizationCodeThenDoesNotThrowAnyException() { + assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) - .redirectUri(REDIRECT_URI) - .scopes(SCOPE) + .redirectUri(null) + .scopes(SCOPES) .state(STATE) - .build(); - - assertThat(authorizationRequest.getResponseType()).isEqualTo(OAuth2AuthorizationResponseType.CODE); + .build()).doesNotThrowAnyException(); } @Test - public void buildWhenRedirectUriIsNullThenDoesNotThrowAnyException() { - assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + public void buildWhenImplicitThenGrantTypeResponseTypeIsSet() { + OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.implicit() + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) - .redirectUri(null) - .scopes(SCOPE) + .redirectUri(REDIRECT_URI) + .scopes(SCOPES) .state(STATE) - .build()).doesNotThrowAnyException(); + .build(); + assertThat(authorizationRequest.getGrantType()).isEqualTo(AuthorizationGrantType.IMPLICIT); + assertThat(authorizationRequest.getResponseType()).isEqualTo(OAuth2AuthorizationResponseType.TOKEN); } @Test - public void buildWhenRedirectUriNotSetThenDoesNotThrowAnyException() { - assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + public void buildWhenAuthorizationCodeThenGrantTypeResponseTypeIsSet() { + OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode() + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) - .scopes(SCOPE) + .redirectUri(null) + .scopes(SCOPES) .state(STATE) - .build()).doesNotThrowAnyException(); + .build(); + assertThat(authorizationRequest.getGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE); + assertThat(authorizationRequest.getResponseType()).isEqualTo(OAuth2AuthorizationResponseType.CODE); } @Test - public void buildWhenScopesIsNullThenDoesNotThrowAnyException() { - assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + public void buildWhenAllAttributesProvidedThenAllAttributesAreSet() { + Map additionalParameters = new HashMap<>(); + additionalParameters.put("param1", "value1"); + additionalParameters.put("param2", "value2"); + + OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode() + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) .redirectUri(REDIRECT_URI) - .scopes(null) + .scopes(SCOPES) .state(STATE) - .build()).doesNotThrowAnyException(); + .additionalParameters(additionalParameters) + .build(); + + assertThat(authorizationRequest.getAuthorizationUri()).isEqualTo(AUTHORIZATION_URI); + assertThat(authorizationRequest.getGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE); + assertThat(authorizationRequest.getResponseType()).isEqualTo(OAuth2AuthorizationResponseType.CODE); + assertThat(authorizationRequest.getClientId()).isEqualTo(CLIENT_ID); + assertThat(authorizationRequest.getRedirectUri()).isEqualTo(REDIRECT_URI); + assertThat(authorizationRequest.getScopes()).isEqualTo(SCOPES); + assertThat(authorizationRequest.getState()).isEqualTo(STATE); + assertThat(authorizationRequest.getAdditionalParameters()).isEqualTo(additionalParameters); } @Test - public void buildWhenScopesNotSetThenDoesNotThrowAnyException() { + public void buildWhenScopesIsNullThenDoesNotThrowAnyException() { assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) .redirectUri(REDIRECT_URI) + .scopes(null) .state(STATE) .build()).doesNotThrowAnyException(); } @@ -136,21 +154,23 @@ public class OAuth2AuthorizationRequestTests { @Test public void buildWhenStateIsNullThenDoesNotThrowAnyException() { assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) .redirectUri(REDIRECT_URI) - .scopes(SCOPE) + .scopes(SCOPES) .state(null) .build()).doesNotThrowAnyException(); } @Test - public void buildWhenStateNotSetThenDoesNotThrowAnyException() { + public void buildWhenAdditionalParametersIsNullThenDoesNotThrowAnyException() { assertThatCode(() -> OAuth2AuthorizationRequest.authorizationCode() - .authorizationUri(AUTHORIZE_URI) + .authorizationUri(AUTHORIZATION_URI) .clientId(CLIENT_ID) .redirectUri(REDIRECT_URI) - .scopes(SCOPE) + .scopes(SCOPES) + .state(STATE) + .additionalParameters(null) .build()).doesNotThrowAnyException(); } } diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTests.java new file mode 100644 index 0000000000..bef93c0a52 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTests.java @@ -0,0 +1,127 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.endpoint; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +/** + * Tests for {@link OAuth2AuthorizationResponse}. + * + * @author Joe Grandja + */ +public class OAuth2AuthorizationResponseTests { + private static final String AUTH_CODE = "auth-code"; + private static final String REDIRECT_URI = "http://example.com"; + private static final String STATE = "state"; + private static final String ERROR_CODE = "error-code"; + private static final String ERROR_DESCRIPTION = "error-description"; + private static final String ERROR_URI = "error-uri"; + + @Test(expected = IllegalArgumentException.class) + public void buildSuccessResponseWhenAuthCodeIsNullThenThrowIllegalArgumentException() { + OAuth2AuthorizationResponse.success(null) + .redirectUri(REDIRECT_URI) + .state(STATE) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void buildSuccessResponseWhenRedirectUriIsNullThenThrowIllegalArgumentException() { + OAuth2AuthorizationResponse.success(AUTH_CODE) + .redirectUri(null) + .state(STATE) + .build(); + } + + @Test + public void buildSuccessResponseWhenStateIsNullThenDoesNotThrowAnyException() { + assertThatCode(() -> OAuth2AuthorizationResponse.success(AUTH_CODE) + .redirectUri(REDIRECT_URI) + .state(null) + .build()).doesNotThrowAnyException(); + } + + @Test + public void buildSuccessResponseWhenAllAttributesProvidedThenAllAttributesAreSet() { + OAuth2AuthorizationResponse authorizationResponse = OAuth2AuthorizationResponse.success(AUTH_CODE) + .redirectUri(REDIRECT_URI) + .state(STATE) + .build(); + assertThat(authorizationResponse.getCode()).isEqualTo(AUTH_CODE); + assertThat(authorizationResponse.getRedirectUri()).isEqualTo(REDIRECT_URI); + assertThat(authorizationResponse.getState()).isEqualTo(STATE); + } + + @Test(expected = IllegalArgumentException.class) + public void buildSuccessResponseWhenErrorCodeIsSetThenThrowIllegalArgumentException() { + OAuth2AuthorizationResponse.success(AUTH_CODE) + .redirectUri(REDIRECT_URI) + .state(STATE) + .errorCode(ERROR_CODE) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void buildErrorResponseWhenErrorCodeIsNullThenThrowIllegalArgumentException() { + OAuth2AuthorizationResponse.error(null) + .redirectUri(REDIRECT_URI) + .state(STATE) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void buildErrorResponseWhenRedirectUriIsNullThenThrowIllegalArgumentException() { + OAuth2AuthorizationResponse.error(ERROR_CODE) + .redirectUri(null) + .state(STATE) + .build(); + } + + @Test + public void buildErrorResponseWhenStateIsNullThenDoesNotThrowAnyException() { + assertThatCode(() -> OAuth2AuthorizationResponse.error(ERROR_CODE) + .redirectUri(REDIRECT_URI) + .state(null) + .build()).doesNotThrowAnyException(); + } + + @Test + public void buildErrorResponseWhenAllAttributesProvidedThenAllAttributesAreSet() { + OAuth2AuthorizationResponse authorizationResponse = OAuth2AuthorizationResponse.error(ERROR_CODE) + .errorDescription(ERROR_DESCRIPTION) + .errorUri(ERROR_URI) + .redirectUri(REDIRECT_URI) + .state(STATE) + .build(); + assertThat(authorizationResponse.getError().getErrorCode()).isEqualTo(ERROR_CODE); + assertThat(authorizationResponse.getError().getDescription()).isEqualTo(ERROR_DESCRIPTION); + assertThat(authorizationResponse.getError().getUri()).isEqualTo(ERROR_URI); + assertThat(authorizationResponse.getRedirectUri()).isEqualTo(REDIRECT_URI); + assertThat(authorizationResponse.getState()).isEqualTo(STATE); + } + + @Test(expected = IllegalArgumentException.class) + public void buildErrorResponseWhenAuthCodeIsSetThenThrowIllegalArgumentException() { + OAuth2AuthorizationResponse.error(ERROR_CODE) + .redirectUri(REDIRECT_URI) + .state(STATE) + .code(AUTH_CODE) + .build(); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTypeTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTypeTests.java new file mode 100644 index 0000000000..ac5f69e2ff --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponseTypeTests.java @@ -0,0 +1,38 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.endpoint; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OAuth2AuthorizationResponseType}. + * + * @author Joe Grandja + */ +public class OAuth2AuthorizationResponseTypeTests { + + @Test + public void getValueWhenResponseTypeCodeThenReturnCode() { + assertThat(OAuth2AuthorizationResponseType.CODE.getValue()).isEqualTo("code"); + } + + @Test + public void getValueWhenResponseTypeTokenThenReturnToken() { + assertThat(OAuth2AuthorizationResponseType.TOKEN.getValue()).isEqualTo("token"); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaimTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaimTests.java new file mode 100644 index 0000000000..e514b5f41f --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/DefaultAddressStandardClaimTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.oidc; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DefaultAddressStandardClaim}. + * + * @author Joe Grandja + */ +public class DefaultAddressStandardClaimTests { + static final String FORMATTED_FIELD_NAME = "formatted"; + static final String STREET_ADDRESS_FIELD_NAME = "street_address"; + static final String LOCALITY_FIELD_NAME = "locality"; + static final String REGION_FIELD_NAME = "region"; + static final String POSTAL_CODE_FIELD_NAME = "postal_code"; + static final String COUNTRY_FIELD_NAME = "country"; + static final String FORMATTED = "formatted"; + static final String STREET_ADDRESS = "street_address"; + static final String LOCALITY = "locality"; + static final String REGION = "region"; + static final String POSTAL_CODE = "postal_code"; + static final String COUNTRY = "country"; + + @Test + public void buildWhenAllAttributesProvidedThenAllAttributesAreSet() { + AddressStandardClaim addressStandardClaim = + new DefaultAddressStandardClaim.Builder() + .formatted(FORMATTED) + .streetAddress(STREET_ADDRESS) + .locality(LOCALITY) + .region(REGION) + .postalCode(POSTAL_CODE) + .country(COUNTRY) + .build(); + + assertThat(addressStandardClaim.getFormatted()).isEqualTo(FORMATTED); + assertThat(addressStandardClaim.getStreetAddress()).isEqualTo(STREET_ADDRESS); + assertThat(addressStandardClaim.getLocality()).isEqualTo(LOCALITY); + assertThat(addressStandardClaim.getRegion()).isEqualTo(REGION); + assertThat(addressStandardClaim.getPostalCode()).isEqualTo(POSTAL_CODE); + assertThat(addressStandardClaim.getCountry()).isEqualTo(COUNTRY); + } + + @Test + public void buildWhenAllAttributesProvidedToConstructorThenAllAttributesAreSet() { + Map addressFields = new HashMap<>(); + addressFields.put(FORMATTED_FIELD_NAME, FORMATTED); + addressFields.put(STREET_ADDRESS_FIELD_NAME, STREET_ADDRESS); + addressFields.put(LOCALITY_FIELD_NAME, LOCALITY); + addressFields.put(REGION_FIELD_NAME, REGION); + addressFields.put(POSTAL_CODE_FIELD_NAME, POSTAL_CODE); + addressFields.put(COUNTRY_FIELD_NAME, COUNTRY); + + AddressStandardClaim addressStandardClaim = + new DefaultAddressStandardClaim.Builder(addressFields) + .build(); + + assertThat(addressStandardClaim.getFormatted()).isEqualTo(FORMATTED); + assertThat(addressStandardClaim.getStreetAddress()).isEqualTo(STREET_ADDRESS); + assertThat(addressStandardClaim.getLocality()).isEqualTo(LOCALITY); + assertThat(addressStandardClaim.getRegion()).isEqualTo(REGION); + assertThat(addressStandardClaim.getPostalCode()).isEqualTo(POSTAL_CODE); + assertThat(addressStandardClaim.getCountry()).isEqualTo(COUNTRY); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcIdTokenTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcIdTokenTests.java new file mode 100644 index 0000000000..26965b1230 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcIdTokenTests.java @@ -0,0 +1,121 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.oidc; + +import org.junit.Test; + +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OidcIdToken}. + * + * @author Joe Grandja + */ +public class OidcIdTokenTests { + private static final String ISS_CLAIM = "iss"; + private static final String SUB_CLAIM = "sub"; + private static final String AUD_CLAIM = "aud"; + private static final String IAT_CLAIM = "iat"; + private static final String EXP_CLAIM = "exp"; + private static final String AUTH_TIME_CLAIM = "auth_time"; + private static final String NONCE_CLAIM = "nonce"; + private static final String ACR_CLAIM = "acr"; + private static final String AMR_CLAIM = "amr"; + private static final String AZP_CLAIM = "azp"; + private static final String AT_HASH_CLAIM = "at_hash"; + private static final String C_HASH_CLAIM = "c_hash"; + + private static final String ISS_VALUE = "https://provider.com"; + private static final String SUB_VALUE = "subject1"; + private static final List AUD_VALUE = Arrays.asList("aud1", "aud2"); + private static final long IAT_VALUE = Instant.now().toEpochMilli(); + private static final long EXP_VALUE = Instant.now().plusSeconds(60).toEpochMilli(); + private static final long AUTH_TIME_VALUE = Instant.now().minusSeconds(5).toEpochMilli(); + private static final String NONCE_VALUE = "nonce"; + private static final String ACR_VALUE = "acr"; + private static final List AMR_VALUE = Arrays.asList("amr1", "amr2"); + private static final String AZP_VALUE = "azp"; + private static final String AT_HASH_VALUE = "at_hash"; + private static final String C_HASH_VALUE = "c_hash"; + + private static final Map CLAIMS; + private static final String ID_TOKEN_VALUE = "id-token-value"; + + static { + CLAIMS = new HashMap<>(); + CLAIMS.put(ISS_CLAIM, ISS_VALUE); + CLAIMS.put(SUB_CLAIM, SUB_VALUE); + CLAIMS.put(AUD_CLAIM, AUD_VALUE); + CLAIMS.put(IAT_CLAIM, IAT_VALUE); + CLAIMS.put(EXP_CLAIM, EXP_VALUE); + CLAIMS.put(AUTH_TIME_CLAIM, AUTH_TIME_VALUE); + CLAIMS.put(NONCE_CLAIM, NONCE_VALUE); + CLAIMS.put(ACR_CLAIM, ACR_VALUE); + CLAIMS.put(AMR_CLAIM, AMR_VALUE); + CLAIMS.put(AZP_CLAIM, AZP_VALUE); + CLAIMS.put(AT_HASH_CLAIM, AT_HASH_VALUE); + CLAIMS.put(C_HASH_CLAIM, C_HASH_VALUE); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenTokenValueIsNullThenThrowIllegalArgumentException() { + new OidcIdToken(null, Instant.ofEpochMilli(IAT_VALUE), Instant.ofEpochMilli(EXP_VALUE), CLAIMS); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenIssuedAtIsNullThenThrowIllegalArgumentException() { + new OidcIdToken(ID_TOKEN_VALUE, null, Instant.ofEpochMilli(EXP_VALUE), CLAIMS); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenExpiresAtIsNullThenThrowIllegalArgumentException() { + new OidcIdToken(ID_TOKEN_VALUE, Instant.ofEpochMilli(IAT_VALUE), null, CLAIMS); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenClaimsIsEmptyThenThrowIllegalArgumentException() { + new OidcIdToken(ID_TOKEN_VALUE, Instant.ofEpochMilli(IAT_VALUE), + Instant.ofEpochMilli(EXP_VALUE), Collections.emptyMap()); + } + + @Test + public void constructorWhenParametersProvidedAndValidThenCreated() { + OidcIdToken idToken = new OidcIdToken(ID_TOKEN_VALUE, Instant.ofEpochMilli(IAT_VALUE), + Instant.ofEpochMilli(EXP_VALUE), CLAIMS); + + assertThat(idToken.getClaims()).isEqualTo(CLAIMS); + assertThat(idToken.getTokenValue()).isEqualTo(ID_TOKEN_VALUE); + assertThat(idToken.getIssuer().toString()).isEqualTo(ISS_VALUE); + assertThat(idToken.getSubject()).isEqualTo(SUB_VALUE); + assertThat(idToken.getAudience()).isEqualTo(AUD_VALUE); + assertThat(idToken.getIssuedAt().toEpochMilli()).isEqualTo(IAT_VALUE); + assertThat(idToken.getExpiresAt().toEpochMilli()).isEqualTo(EXP_VALUE); + assertThat(idToken.getAuthenticatedAt().toEpochMilli()).isEqualTo(AUTH_TIME_VALUE); + assertThat(idToken.getNonce()).isEqualTo(NONCE_VALUE); + assertThat(idToken.getAuthenticationContextClass()).isEqualTo(ACR_VALUE); + assertThat(idToken.getAuthenticationMethods()).isEqualTo(AMR_VALUE); + assertThat(idToken.getAuthorizedParty()).isEqualTo(AZP_VALUE); + assertThat(idToken.getAccessTokenHash()).isEqualTo(AT_HASH_VALUE); + assertThat(idToken.getAuthorizationCodeHash()).isEqualTo(C_HASH_VALUE); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcUserInfoTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcUserInfoTests.java new file mode 100644 index 0000000000..df37a1b8b6 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/OidcUserInfoTests.java @@ -0,0 +1,142 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.oidc; + +import org.junit.Test; + +import java.time.Instant; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.security.oauth2.core.oidc.DefaultAddressStandardClaimTests.*; + +/** + * Tests for {@link OidcUserInfo}. + * + * @author Joe Grandja + */ +public class OidcUserInfoTests { + private static final String SUB_CLAIM = "sub"; + private static final String NAME_CLAIM = "name"; + private static final String GIVEN_NAME_CLAIM = "given_name"; + private static final String FAMILY_NAME_CLAIM = "family_name"; + private static final String MIDDLE_NAME_CLAIM = "middle_name"; + private static final String NICKNAME_CLAIM = "nickname"; + private static final String PREFERRED_USERNAME_CLAIM = "preferred_username"; + private static final String PROFILE_CLAIM = "profile"; + private static final String PICTURE_CLAIM = "picture"; + private static final String WEBSITE_CLAIM = "website"; + private static final String EMAIL_CLAIM = "email"; + private static final String EMAIL_VERIFIED_CLAIM = "email_verified"; + private static final String GENDER_CLAIM = "gender"; + private static final String BIRTHDATE_CLAIM = "birthdate"; + private static final String ZONEINFO_CLAIM = "zoneinfo"; + private static final String LOCALE_CLAIM = "locale"; + private static final String PHONE_NUMBER_CLAIM = "phone_number"; + private static final String PHONE_NUMBER_VERIFIED_CLAIM = "phone_number_verified"; + private static final String ADDRESS_CLAIM = "address"; + private static final String UPDATED_AT_CLAIM = "updated_at"; + + private static final String SUB_VALUE = "subject1"; + private static final String NAME_VALUE = "full_name"; + private static final String GIVEN_NAME_VALUE = "given_name"; + private static final String FAMILY_NAME_VALUE = "family_name"; + private static final String MIDDLE_NAME_VALUE = "middle_name"; + private static final String NICKNAME_VALUE = "nickname"; + private static final String PREFERRED_USERNAME_VALUE = "preferred_username"; + private static final String PROFILE_VALUE = "profile"; + private static final String PICTURE_VALUE = "picture"; + private static final String WEBSITE_VALUE = "website"; + private static final String EMAIL_VALUE = "email"; + private static final Boolean EMAIL_VERIFIED_VALUE = true; + private static final String GENDER_VALUE = "gender"; + private static final String BIRTHDATE_VALUE = "birthdate"; + private static final String ZONEINFO_VALUE = "zoneinfo"; + private static final String LOCALE_VALUE = "locale"; + private static final String PHONE_NUMBER_VALUE = "phone_number"; + private static final Boolean PHONE_NUMBER_VERIFIED_VALUE = true; + private static final Map ADDRESS_VALUE; + private static final long UPDATED_AT_VALUE = Instant.now().minusSeconds(60).toEpochMilli(); + + private static final Map CLAIMS; + + static { + CLAIMS = new HashMap<>(); + CLAIMS.put(SUB_CLAIM, SUB_VALUE); + CLAIMS.put(NAME_CLAIM, NAME_VALUE); + CLAIMS.put(GIVEN_NAME_CLAIM, GIVEN_NAME_VALUE); + CLAIMS.put(FAMILY_NAME_CLAIM, FAMILY_NAME_VALUE); + CLAIMS.put(MIDDLE_NAME_CLAIM, MIDDLE_NAME_VALUE); + CLAIMS.put(NICKNAME_CLAIM, NICKNAME_VALUE); + CLAIMS.put(PREFERRED_USERNAME_CLAIM, PREFERRED_USERNAME_VALUE); + CLAIMS.put(PROFILE_CLAIM, PROFILE_VALUE); + CLAIMS.put(PICTURE_CLAIM, PICTURE_VALUE); + CLAIMS.put(WEBSITE_CLAIM, WEBSITE_VALUE); + CLAIMS.put(EMAIL_CLAIM, EMAIL_VALUE); + CLAIMS.put(EMAIL_VERIFIED_CLAIM, EMAIL_VERIFIED_VALUE); + CLAIMS.put(GENDER_CLAIM, GENDER_VALUE); + CLAIMS.put(BIRTHDATE_CLAIM, BIRTHDATE_VALUE); + CLAIMS.put(ZONEINFO_CLAIM, ZONEINFO_VALUE); + CLAIMS.put(LOCALE_CLAIM, LOCALE_VALUE); + CLAIMS.put(PHONE_NUMBER_CLAIM, PHONE_NUMBER_VALUE); + CLAIMS.put(PHONE_NUMBER_VERIFIED_CLAIM, PHONE_NUMBER_VERIFIED_VALUE); + + ADDRESS_VALUE = new HashMap<>(); + ADDRESS_VALUE.put(FORMATTED_FIELD_NAME, FORMATTED); + ADDRESS_VALUE.put(STREET_ADDRESS_FIELD_NAME, STREET_ADDRESS); + ADDRESS_VALUE.put(LOCALITY_FIELD_NAME, LOCALITY); + ADDRESS_VALUE.put(REGION_FIELD_NAME, REGION); + ADDRESS_VALUE.put(POSTAL_CODE_FIELD_NAME, POSTAL_CODE); + ADDRESS_VALUE.put(COUNTRY_FIELD_NAME, COUNTRY); + CLAIMS.put(ADDRESS_CLAIM, ADDRESS_VALUE); + + CLAIMS.put(UPDATED_AT_CLAIM, UPDATED_AT_VALUE); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenClaimsIsEmptyThenThrowIllegalArgumentException() { + new OidcUserInfo(Collections.emptyMap()); + } + + @Test + public void constructorWhenParametersProvidedAndValidThenCreated() { + OidcUserInfo userInfo = new OidcUserInfo(CLAIMS); + + assertThat(userInfo.getClaims()).isEqualTo(CLAIMS); + assertThat(userInfo.getSubject()).isEqualTo(SUB_VALUE); + assertThat(userInfo.getFullName()).isEqualTo(NAME_VALUE); + assertThat(userInfo.getGivenName()).isEqualTo(GIVEN_NAME_VALUE); + assertThat(userInfo.getFamilyName()).isEqualTo(FAMILY_NAME_VALUE); + assertThat(userInfo.getMiddleName()).isEqualTo(MIDDLE_NAME_VALUE); + assertThat(userInfo.getNickName()).isEqualTo(NICKNAME_VALUE); + assertThat(userInfo.getPreferredUsername()).isEqualTo(PREFERRED_USERNAME_VALUE); + assertThat(userInfo.getProfile()).isEqualTo(PROFILE_VALUE); + assertThat(userInfo.getPicture()).isEqualTo(PICTURE_VALUE); + assertThat(userInfo.getWebsite()).isEqualTo(WEBSITE_VALUE); + assertThat(userInfo.getEmail()).isEqualTo(EMAIL_VALUE); + assertThat(userInfo.getEmailVerified()).isEqualTo(EMAIL_VERIFIED_VALUE); + assertThat(userInfo.getGender()).isEqualTo(GENDER_VALUE); + assertThat(userInfo.getBirthdate()).isEqualTo(BIRTHDATE_VALUE); + assertThat(userInfo.getZoneInfo()).isEqualTo(ZONEINFO_VALUE); + assertThat(userInfo.getLocale()).isEqualTo(LOCALE_VALUE); + assertThat(userInfo.getPhoneNumber()).isEqualTo(PHONE_NUMBER_VALUE); + assertThat(userInfo.getPhoneNumberVerified()).isEqualTo(PHONE_NUMBER_VERIFIED_VALUE); + assertThat(userInfo.getAddress()).isEqualTo(new DefaultAddressStandardClaim.Builder(ADDRESS_VALUE).build()); + assertThat(userInfo.getUpdatedAt().toEpochMilli()).isEqualTo(UPDATED_AT_VALUE); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/DefaultOidcUserTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/DefaultOidcUserTests.java index 6d06bd55ac..de06936ec5 100644 --- a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/DefaultOidcUserTests.java +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/DefaultOidcUserTests.java @@ -16,107 +16,113 @@ package org.springframework.security.oauth2.core.oidc.user; -import java.time.Instant; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; +import org.springframework.security.oauth2.core.oidc.OidcIdToken; import org.springframework.security.oauth2.core.oidc.OidcUserInfo; import org.springframework.security.oauth2.core.oidc.StandardClaimNames; +import java.time.Instant; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link DefaultOidcUser}. * * @author Vedran Pavic + * @author Joe Grandja */ public class DefaultOidcUserTests { - - private static final SimpleGrantedAuthority TEST_AUTHORITY = new SimpleGrantedAuthority("ROLE_USER"); - - private static final Set TEST_AUTHORITIES = Collections.singleton(TEST_AUTHORITY); - - private static final String TEST_SUBJECT = "test"; - - private static final String TEST_EMAIL = "test@example.com"; - - private static final Map TEST_ID_TOKEN_CLAIMS = new HashMap<>(); + private static final SimpleGrantedAuthority AUTHORITY = new SimpleGrantedAuthority("ROLE_USER"); + private static final Set AUTHORITIES = Collections.singleton(AUTHORITY); + private static final String SUBJECT = "test-subject"; + private static final String EMAIL = "test-subject@example.com"; + private static final String NAME = "test-name"; + private static final Map ID_TOKEN_CLAIMS = new HashMap<>(); + private static final Map USER_INFO_CLAIMS = new HashMap<>(); static { - TEST_ID_TOKEN_CLAIMS.put(IdTokenClaimNames.ISS, "https://example.com"); - TEST_ID_TOKEN_CLAIMS.put(IdTokenClaimNames.SUB, TEST_SUBJECT); + ID_TOKEN_CLAIMS.put(IdTokenClaimNames.ISS, "https://example.com"); + ID_TOKEN_CLAIMS.put(IdTokenClaimNames.SUB, SUBJECT); + USER_INFO_CLAIMS.put(StandardClaimNames.NAME, NAME); + USER_INFO_CLAIMS.put(StandardClaimNames.EMAIL, EMAIL); } - private static final OidcIdToken TEST_ID_TOKEN = new OidcIdToken("value", Instant.EPOCH, Instant.MAX, TEST_ID_TOKEN_CLAIMS); - - private static final OidcUserInfo TEST_USER_INFO = new OidcUserInfo(Collections.singletonMap(StandardClaimNames.EMAIL, TEST_EMAIL)); + private static final OidcIdToken ID_TOKEN = new OidcIdToken("id-token-value", Instant.EPOCH, Instant.MAX, ID_TOKEN_CLAIMS); + private static final OidcUserInfo USER_INFO = new OidcUserInfo(USER_INFO_CLAIMS); - @Rule - public ExpectedException thrown = ExpectedException.none(); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthoritiesIsNullThenThrowIllegalArgumentException() { + new DefaultOidcUser(null, ID_TOKEN); + } - @Test - public void constructorWhenAuthoritiesAndIdTokenThenIsCreated() { - DefaultOidcUser user = new DefaultOidcUser(TEST_AUTHORITIES, TEST_ID_TOKEN); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenIdTokenIsNullThenThrowIllegalArgumentException() { + new DefaultOidcUser(AUTHORITIES, null); + } - assertThat(user.getName()).isEqualTo(TEST_SUBJECT); - assertThat(user.getAuthorities()).hasSize(1); - assertThat(user.getAuthorities().iterator().next()).isEqualTo(TEST_AUTHORITY); - assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenNameAttributeKeyInvalidThenThrowIllegalArgumentException() { + new DefaultOidcUser(AUTHORITIES, ID_TOKEN, "invalid"); } @Test - public void constructorWhenAuthoritiesAndIdTokenAndNameAttributeKeyThenIsCreated() { - DefaultOidcUser user = new DefaultOidcUser(TEST_AUTHORITIES, TEST_ID_TOKEN, IdTokenClaimNames.SUB); + public void constructorWhenAuthoritiesIdTokenProvidedThenCreated() { + DefaultOidcUser user = new DefaultOidcUser(AUTHORITIES, ID_TOKEN); - assertThat(user.getName()).isEqualTo(TEST_SUBJECT); + assertThat(user.getClaims()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB); + assertThat(user.getIdToken()).isEqualTo(ID_TOKEN); + assertThat(user.getName()).isEqualTo(SUBJECT); assertThat(user.getAuthorities()).hasSize(1); - assertThat(user.getAuthorities().iterator().next()).isEqualTo(TEST_AUTHORITY); + assertThat(user.getAuthorities().iterator().next()).isEqualTo(AUTHORITY); assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB); } @Test - public void constructorWhenAuthoritiesAndIdTokenAndUserInfoThenIsCreated() { - DefaultOidcUser user = new DefaultOidcUser(TEST_AUTHORITIES, TEST_ID_TOKEN, TEST_USER_INFO); + public void constructorWhenAuthoritiesIdTokenNameAttributeKeyProvidedThenCreated() { + DefaultOidcUser user = new DefaultOidcUser(AUTHORITIES, ID_TOKEN, IdTokenClaimNames.SUB); - assertThat(user.getName()).isEqualTo(TEST_SUBJECT); + assertThat(user.getClaims()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB); + assertThat(user.getIdToken()).isEqualTo(ID_TOKEN); + assertThat(user.getName()).isEqualTo(SUBJECT); assertThat(user.getAuthorities()).hasSize(1); - assertThat(user.getAuthorities().iterator().next()).isEqualTo(TEST_AUTHORITY); - assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.EMAIL); + assertThat(user.getAuthorities().iterator().next()).isEqualTo(AUTHORITY); + assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB); } @Test - public void constructorWhenAuthoritiesAndIdTokenAndUserInfoAndNameAttributeKeyThenIsCreated() { - DefaultOidcUser user = new DefaultOidcUser(TEST_AUTHORITIES, TEST_ID_TOKEN, TEST_USER_INFO, StandardClaimNames.EMAIL); - - assertThat(user.getName()).isEqualTo(TEST_EMAIL); + public void constructorWhenAuthoritiesIdTokenUserInfoProvidedThenCreated() { + DefaultOidcUser user = new DefaultOidcUser(AUTHORITIES, ID_TOKEN, USER_INFO); + + assertThat(user.getClaims()).containsOnlyKeys( + IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.NAME, StandardClaimNames.EMAIL); + assertThat(user.getIdToken()).isEqualTo(ID_TOKEN); + assertThat(user.getUserInfo()).isEqualTo(USER_INFO); + assertThat(user.getName()).isEqualTo(SUBJECT); assertThat(user.getAuthorities()).hasSize(1); - assertThat(user.getAuthorities().iterator().next()).isEqualTo(TEST_AUTHORITY); - assertThat(user.getAttributes()).containsOnlyKeys(IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.EMAIL); - } - - @Test - public void constructorWhenIdTokenIsNullThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("idToken cannot be null"); - - new DefaultOidcUser(TEST_AUTHORITIES, null); + assertThat(user.getAuthorities().iterator().next()).isEqualTo(AUTHORITY); + assertThat(user.getAttributes()).containsOnlyKeys( + IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.NAME, StandardClaimNames.EMAIL); } @Test - public void constructorWhenNameAttributeKeyClaimIsNotPresentThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("Missing attribute '" + StandardClaimNames.NAME + "' in attributes"); - - new DefaultOidcUser(TEST_AUTHORITIES, TEST_ID_TOKEN, TEST_USER_INFO, StandardClaimNames.NAME); + public void constructorWhenAllParametersProvidedAndValidThenCreated() { + DefaultOidcUser user = new DefaultOidcUser(AUTHORITIES, ID_TOKEN, USER_INFO, StandardClaimNames.EMAIL); + + assertThat(user.getClaims()).containsOnlyKeys( + IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.NAME, StandardClaimNames.EMAIL); + assertThat(user.getIdToken()).isEqualTo(ID_TOKEN); + assertThat(user.getUserInfo()).isEqualTo(USER_INFO); + assertThat(user.getName()).isEqualTo(EMAIL); + assertThat(user.getAuthorities()).hasSize(1); + assertThat(user.getAuthorities().iterator().next()).isEqualTo(AUTHORITY); + assertThat(user.getAttributes()).containsOnlyKeys( + IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.NAME, StandardClaimNames.EMAIL); } - } diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthorityTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthorityTests.java new file mode 100644 index 0000000000..0d6b7f6870 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/oidc/user/OidcUserAuthorityTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.oidc.user; + +import org.junit.Test; +import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; +import org.springframework.security.oauth2.core.oidc.OidcIdToken; +import org.springframework.security.oauth2.core.oidc.OidcUserInfo; +import org.springframework.security.oauth2.core.oidc.StandardClaimNames; + +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +/** + * Tests for {@link OidcUserAuthority}. + * + * @author Joe Grandja + */ +public class OidcUserAuthorityTests { + private static final String AUTHORITY = "ROLE_USER"; + private static final String SUBJECT = "test-subject"; + private static final String EMAIL = "test-subject@example.com"; + private static final String NAME = "test-name"; + private static final Map ID_TOKEN_CLAIMS = new HashMap<>(); + private static final Map USER_INFO_CLAIMS = new HashMap<>(); + + static { + ID_TOKEN_CLAIMS.put(IdTokenClaimNames.ISS, "https://example.com"); + ID_TOKEN_CLAIMS.put(IdTokenClaimNames.SUB, SUBJECT); + USER_INFO_CLAIMS.put(StandardClaimNames.NAME, NAME); + USER_INFO_CLAIMS.put(StandardClaimNames.EMAIL, EMAIL); + } + + private static final OidcIdToken ID_TOKEN = new OidcIdToken("id-token-value", Instant.EPOCH, Instant.MAX, ID_TOKEN_CLAIMS); + private static final OidcUserInfo USER_INFO = new OidcUserInfo(USER_INFO_CLAIMS); + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenIdTokenIsNullThenThrowIllegalArgumentException() { + new OidcUserAuthority(null); + } + + @Test + public void constructorWhenUserInfoIsNullThenDoesNotThrowAnyException() { + assertThatCode(() -> new OidcUserAuthority(ID_TOKEN, null)).doesNotThrowAnyException(); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthorityIsNullThenThrowIllegalArgumentException() { + new OidcUserAuthority(null, ID_TOKEN, USER_INFO); + } + + @Test + public void constructorWhenAllParametersProvidedAndValidThenCreated() { + OidcUserAuthority userAuthority = new OidcUserAuthority(AUTHORITY, ID_TOKEN, USER_INFO); + + assertThat(userAuthority.getIdToken()).isEqualTo(ID_TOKEN); + assertThat(userAuthority.getUserInfo()).isEqualTo(USER_INFO); + assertThat(userAuthority.getAuthority()).isEqualTo(AUTHORITY); + assertThat(userAuthority.getAttributes()).containsOnlyKeys( + IdTokenClaimNames.ISS, IdTokenClaimNames.SUB, StandardClaimNames.NAME, StandardClaimNames.EMAIL); + } +} diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/DefaultOAuth2UserTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/DefaultOAuth2UserTests.java index fbd98e691c..63ceeb65d9 100644 --- a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/DefaultOAuth2UserTests.java +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/DefaultOAuth2UserTests.java @@ -16,95 +16,67 @@ package org.springframework.security.oauth2.core.user; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link DefaultOAuth2User}. * * @author Vedran Pavic + * @author Joe Grandja */ public class DefaultOAuth2UserTests { - - private static final SimpleGrantedAuthority TEST_AUTHORITY = new SimpleGrantedAuthority("ROLE_USER"); - - private static final Set TEST_AUTHORITIES = Collections.singleton(TEST_AUTHORITY); - - private static final String TEST_ATTRIBUTE_NAME_KEY = "username"; - - private static final String TEST_USERNAME = "test"; - - private static final Map TEST_ATTRIBUTES = Collections.singletonMap( - TEST_ATTRIBUTE_NAME_KEY, TEST_USERNAME); - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void constructorWhenParametersAreValidThenIsCreated() { - DefaultOAuth2User user = new DefaultOAuth2User(TEST_AUTHORITIES, TEST_ATTRIBUTES, TEST_ATTRIBUTE_NAME_KEY); - - assertThat(user.getName()).isEqualTo(TEST_USERNAME); - assertThat(user.getAuthorities()).hasSize(1); - assertThat(user.getAuthorities().iterator().next()).isEqualTo(TEST_AUTHORITY); - assertThat(user.getAttributes()).containsOnlyKeys(TEST_ATTRIBUTE_NAME_KEY); + private static final SimpleGrantedAuthority AUTHORITY = new SimpleGrantedAuthority("ROLE_USER"); + private static final Set AUTHORITIES = Collections.singleton(AUTHORITY); + private static final String ATTRIBUTE_NAME_KEY = "username"; + private static final String USERNAME = "test"; + private static final Map ATTRIBUTES = Collections.singletonMap( + ATTRIBUTE_NAME_KEY, USERNAME); + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthoritiesIsNullThenThrowIllegalArgumentException() { + new DefaultOAuth2User(null, ATTRIBUTES, ATTRIBUTE_NAME_KEY); } - @Test - public void constructorWhenAuthoritiesAreNullThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("authorities cannot be empty"); - - new DefaultOAuth2User(null, TEST_ATTRIBUTES, TEST_ATTRIBUTE_NAME_KEY); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthoritiesIsEmptyThenThrowIllegalArgumentException() { + new DefaultOAuth2User(Collections.emptySet(), ATTRIBUTES, ATTRIBUTE_NAME_KEY); } - @Test - public void constructorWhenAuthoritiesAreEmptyThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("authorities cannot be empty"); - - new DefaultOAuth2User(Collections.emptySet(), TEST_ATTRIBUTES, TEST_ATTRIBUTE_NAME_KEY); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAttributesIsNullThenThrowIllegalArgumentException() { + new DefaultOAuth2User(AUTHORITIES, null, ATTRIBUTE_NAME_KEY); } - @Test - public void constructorWhenAttributesAreNullThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("attributes cannot be empty"); - - new DefaultOAuth2User(TEST_AUTHORITIES, null, TEST_ATTRIBUTE_NAME_KEY); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAttributesIsEmptyThenThrowIllegalArgumentException() { + new DefaultOAuth2User(AUTHORITIES, Collections.emptyMap(), ATTRIBUTE_NAME_KEY); } - @Test - public void constructorWhenAttributesAreEmptyThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("attributes cannot be empty"); - - new DefaultOAuth2User(TEST_AUTHORITIES, Collections.emptyMap(), TEST_ATTRIBUTE_NAME_KEY); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenNameAttributeKeyIsNullThenThrowIllegalArgumentException() { + new DefaultOAuth2User(AUTHORITIES, ATTRIBUTES, null); } - @Test - public void constructorWhenNameAttributeKeyIsNullThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("nameAttributeKey cannot be empty"); - - new DefaultOAuth2User(TEST_AUTHORITIES, TEST_ATTRIBUTES, null); + @Test(expected = IllegalArgumentException.class) + public void constructorWhenNameAttributeKeyIsInvalidThenThrowIllegalArgumentException() { + new DefaultOAuth2User(AUTHORITIES, ATTRIBUTES, "invalid"); } @Test - public void constructorWhenNameAttributeKeyIsInvalidThenThrowsException() { - this.thrown.expect(IllegalArgumentException.class); - this.thrown.expectMessage("Missing attribute 'invalid' in attributes"); + public void constructorWhenAllParametersProvidedAndValidThenCreated() { + DefaultOAuth2User user = new DefaultOAuth2User(AUTHORITIES, ATTRIBUTES, ATTRIBUTE_NAME_KEY); - new DefaultOAuth2User(TEST_AUTHORITIES, TEST_ATTRIBUTES, "invalid"); + assertThat(user.getName()).isEqualTo(USERNAME); + assertThat(user.getAuthorities()).hasSize(1); + assertThat(user.getAuthorities().iterator().next()).isEqualTo(AUTHORITY); + assertThat(user.getAttributes()).containsOnlyKeys(ATTRIBUTE_NAME_KEY); } - } diff --git a/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthorityTests.java b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthorityTests.java new file mode 100644 index 0000000000..176ea72464 --- /dev/null +++ b/oauth2/oauth2-core/src/test/java/org/springframework/security/oauth2/core/user/OAuth2UserAuthorityTests.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.core.user; + +import org.junit.Test; + +import java.util.Collections; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OAuth2UserAuthority}. + * + * @author Joe Grandja + */ +public class OAuth2UserAuthorityTests { + private static final String AUTHORITY = "ROLE_USER"; + private static final Map ATTRIBUTES = Collections.singletonMap("username", "test"); + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAuthorityIsNullThenThrowIllegalArgumentException() { + new OAuth2UserAuthority(null, ATTRIBUTES); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAttributesIsNullThenThrowIllegalArgumentException() { + new OAuth2UserAuthority(AUTHORITY, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenAttributesIsEmptyThenThrowIllegalArgumentException() { + new OAuth2UserAuthority(AUTHORITY, Collections.emptyMap()); + } + + @Test + public void constructorWhenAllParametersProvidedAndValidThenCreated() { + OAuth2UserAuthority userAuthority = new OAuth2UserAuthority(AUTHORITY, ATTRIBUTES); + + assertThat(userAuthority.getAuthority()).isEqualTo(AUTHORITY); + assertThat(userAuthority.getAttributes()).isEqualTo(ATTRIBUTES); + } +}