14 changed files with 774 additions and 24 deletions
@ -0,0 +1,169 @@
@@ -0,0 +1,169 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.token; |
||||
|
||||
import org.springframework.security.oauth2.server.authorization.Version; |
||||
import org.springframework.util.Assert; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
import java.util.function.Consumer; |
||||
|
||||
/** |
||||
* Holds metadata associated to an OAuth 2.0 Token. |
||||
* |
||||
* @author Joe Grandja |
||||
* @since 0.0.3 |
||||
* @see OAuth2Tokens |
||||
*/ |
||||
public class OAuth2TokenMetadata implements Serializable { |
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID; |
||||
protected static final String TOKEN_METADATA_BASE = "token.metadata."; |
||||
|
||||
/** |
||||
* The name of the metadata that indicates if the token has been invalidated. |
||||
*/ |
||||
public static final String INVALIDATED = TOKEN_METADATA_BASE.concat("invalidated"); |
||||
|
||||
private final Map<String, Object> metadata; |
||||
|
||||
protected OAuth2TokenMetadata(Map<String, Object> metadata) { |
||||
this.metadata = Collections.unmodifiableMap(new HashMap<>(metadata)); |
||||
} |
||||
|
||||
/** |
||||
* Returns {@code true} if the token has been invalidated (e.g. revoked). |
||||
* The default is {@code false}. |
||||
* |
||||
* @return {@code true} if the token has been invalidated, {@code false} otherwise |
||||
*/ |
||||
public boolean isInvalidated() { |
||||
return getMetadata(INVALIDATED); |
||||
} |
||||
|
||||
/** |
||||
* Returns the value of the metadata associated to the token. |
||||
* |
||||
* @param name the name of the metadata |
||||
* @param <T> the type of the metadata |
||||
* @return the value of the metadata, or {@code null} if not available |
||||
*/ |
||||
@SuppressWarnings("unchecked") |
||||
public <T> T getMetadata(String name) { |
||||
Assert.hasText(name, "name cannot be empty"); |
||||
return (T) this.metadata.get(name); |
||||
} |
||||
|
||||
/** |
||||
* Returns the metadata associated to the token. |
||||
* |
||||
* @return a {@code Map} of the metadata |
||||
*/ |
||||
public Map<String, Object> getMetadata() { |
||||
return this.metadata; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null || getClass() != obj.getClass()) { |
||||
return false; |
||||
} |
||||
OAuth2TokenMetadata that = (OAuth2TokenMetadata) obj; |
||||
return Objects.equals(this.metadata, that.metadata); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(this.metadata); |
||||
} |
||||
|
||||
/** |
||||
* Returns a new {@link Builder}. |
||||
* |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public static Builder builder() { |
||||
return new Builder(); |
||||
} |
||||
|
||||
/** |
||||
* A builder for {@link OAuth2TokenMetadata}. |
||||
*/ |
||||
public static class Builder implements Serializable { |
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID; |
||||
private final Map<String, Object> metadata = defaultMetadata(); |
||||
|
||||
protected Builder() { |
||||
} |
||||
|
||||
/** |
||||
* Set the token as invalidated (e.g. revoked). |
||||
* |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder invalidated() { |
||||
metadata(INVALIDATED, true); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Adds a metadata associated to the token. |
||||
* |
||||
* @param name the name of the metadata |
||||
* @param value the value of the metadata |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder metadata(String name, Object value) { |
||||
Assert.hasText(name, "name cannot be empty"); |
||||
Assert.notNull(value, "value cannot be null"); |
||||
this.metadata.put(name, value); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* A {@code Consumer} of the metadata {@code Map} |
||||
* allowing the ability to add, replace, or remove. |
||||
* |
||||
* @param metadataConsumer a {@link Consumer} of the metadata {@code Map} |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder metadata(Consumer<Map<String, Object>> metadataConsumer) { |
||||
metadataConsumer.accept(this.metadata); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Builds a new {@link OAuth2TokenMetadata}. |
||||
* |
||||
* @return the {@link OAuth2TokenMetadata} |
||||
*/ |
||||
public OAuth2TokenMetadata build() { |
||||
return new OAuth2TokenMetadata(this.metadata); |
||||
} |
||||
|
||||
protected static Map<String, Object> defaultMetadata() { |
||||
Map<String, Object> metadata = new HashMap<>(); |
||||
metadata.put(INVALIDATED, false); |
||||
return metadata; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,279 @@
@@ -0,0 +1,279 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.token; |
||||
|
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.security.oauth2.core.AbstractOAuth2Token; |
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken; |
||||
import org.springframework.security.oauth2.core.OAuth2RefreshToken; |
||||
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization; |
||||
import org.springframework.security.oauth2.server.authorization.Version; |
||||
import org.springframework.util.Assert; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
|
||||
/** |
||||
* A container for OAuth 2.0 Tokens. |
||||
* |
||||
* @author Joe Grandja |
||||
* @since 0.0.3 |
||||
* @see OAuth2Authorization |
||||
* @see OAuth2TokenMetadata |
||||
* @see AbstractOAuth2Token |
||||
* @see OAuth2AccessToken |
||||
* @see OAuth2RefreshToken |
||||
*/ |
||||
public class OAuth2Tokens implements Serializable { |
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID; |
||||
private final Map<Class<? extends AbstractOAuth2Token>, OAuth2TokenHolder> tokens; |
||||
|
||||
protected OAuth2Tokens(Map<Class<? extends AbstractOAuth2Token>, OAuth2TokenHolder> tokens) { |
||||
this.tokens = new HashMap<>(tokens); |
||||
} |
||||
|
||||
/** |
||||
* Returns the {@link OAuth2AccessToken access token}. |
||||
* |
||||
* @return the {@link OAuth2AccessToken}, or {@code null} if not available |
||||
*/ |
||||
@Nullable |
||||
public OAuth2AccessToken getAccessToken() { |
||||
return getToken(OAuth2AccessToken.class); |
||||
} |
||||
|
||||
/** |
||||
* Returns the {@link OAuth2RefreshToken refresh token}. |
||||
* |
||||
* @return the {@link OAuth2RefreshToken}, or {@code null} if not available |
||||
*/ |
||||
@Nullable |
||||
public OAuth2RefreshToken getRefreshToken() { |
||||
return getToken(OAuth2RefreshToken.class); |
||||
} |
||||
|
||||
/** |
||||
* Returns the token specified by {@code tokenType}. |
||||
* |
||||
* @param tokenType the token type |
||||
* @param <T> the type of the token |
||||
* @return the token, or {@code null} if not available |
||||
*/ |
||||
@Nullable |
||||
@SuppressWarnings("unchecked") |
||||
public <T extends AbstractOAuth2Token> T getToken(Class<T> tokenType) { |
||||
Assert.notNull(tokenType, "tokenType cannot be null"); |
||||
OAuth2TokenHolder tokenHolder = this.tokens.get(tokenType); |
||||
return tokenHolder != null ? (T) tokenHolder.getToken() : null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the token metadata associated to the provided {@code token}. |
||||
* |
||||
* @param token the token |
||||
* @param <T> the type of the token |
||||
* @return the token metadata, or {@code null} if not available |
||||
*/ |
||||
@Nullable |
||||
public <T extends AbstractOAuth2Token> OAuth2TokenMetadata getTokenMetadata(T token) { |
||||
Assert.notNull(token, "token cannot be null"); |
||||
OAuth2TokenHolder tokenHolder = this.tokens.get(token.getClass()); |
||||
return (tokenHolder != null && tokenHolder.getToken().equals(token)) ? |
||||
tokenHolder.getTokenMetadata() : null; |
||||
} |
||||
|
||||
/** |
||||
* Invalidates all tokens. |
||||
*/ |
||||
public void invalidate() { |
||||
this.tokens.values().forEach(tokenHolder -> invalidate(tokenHolder.getToken())); |
||||
} |
||||
|
||||
/** |
||||
* Invalidates the token matching the provided {@code token}. |
||||
* |
||||
* @param token the token |
||||
* @param <T> the type of the token |
||||
*/ |
||||
public <T extends AbstractOAuth2Token> void invalidate(T token) { |
||||
Assert.notNull(token, "token cannot be null"); |
||||
this.tokens.computeIfPresent(token.getClass(), |
||||
(tokenType, tokenHolder) -> |
||||
new OAuth2TokenHolder( |
||||
tokenHolder.getToken(), |
||||
OAuth2TokenMetadata.builder().invalidated().build()) |
||||
); |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null || getClass() != obj.getClass()) { |
||||
return false; |
||||
} |
||||
OAuth2Tokens that = (OAuth2Tokens) obj; |
||||
return Objects.equals(this.tokens, that.tokens); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(this.tokens); |
||||
} |
||||
|
||||
/** |
||||
* Returns a new {@link Builder}. |
||||
* |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public static Builder builder() { |
||||
return new Builder(); |
||||
} |
||||
|
||||
/** |
||||
* A builder for {@link OAuth2Tokens}. |
||||
*/ |
||||
public static class Builder implements Serializable { |
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID; |
||||
private final Map<Class<? extends AbstractOAuth2Token>, OAuth2TokenHolder> tokens = new HashMap<>(); |
||||
|
||||
protected Builder() { |
||||
} |
||||
|
||||
/** |
||||
* Sets the {@link OAuth2AccessToken access token}. |
||||
* |
||||
* @param accessToken the {@link OAuth2AccessToken} |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder accessToken(OAuth2AccessToken accessToken) { |
||||
return addToken(accessToken, null); |
||||
} |
||||
|
||||
/** |
||||
* Sets the {@link OAuth2AccessToken access token} and associated {@link OAuth2TokenMetadata token metadata}. |
||||
* |
||||
* @param accessToken the {@link OAuth2AccessToken} |
||||
* @param tokenMetadata the {@link OAuth2TokenMetadata} |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder accessToken(OAuth2AccessToken accessToken, OAuth2TokenMetadata tokenMetadata) { |
||||
return addToken(accessToken, tokenMetadata); |
||||
} |
||||
|
||||
/** |
||||
* Sets the {@link OAuth2RefreshToken refresh token}. |
||||
* |
||||
* @param refreshToken the {@link OAuth2RefreshToken} |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder refreshToken(OAuth2RefreshToken refreshToken) { |
||||
return addToken(refreshToken, null); |
||||
} |
||||
|
||||
/** |
||||
* Sets the {@link OAuth2RefreshToken refresh token} and associated {@link OAuth2TokenMetadata token metadata}. |
||||
* |
||||
* @param refreshToken the {@link OAuth2RefreshToken} |
||||
* @param tokenMetadata the {@link OAuth2TokenMetadata} |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public Builder refreshToken(OAuth2RefreshToken refreshToken, OAuth2TokenMetadata tokenMetadata) { |
||||
return addToken(refreshToken, tokenMetadata); |
||||
} |
||||
|
||||
/** |
||||
* Sets the token. |
||||
* |
||||
* @param token the token |
||||
* @param <T> the type of the token |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public <T extends AbstractOAuth2Token> Builder token(T token) { |
||||
return addToken(token, null); |
||||
} |
||||
|
||||
/** |
||||
* Sets the token and associated {@link OAuth2TokenMetadata token metadata}. |
||||
* |
||||
* @param token the token |
||||
* @param tokenMetadata the {@link OAuth2TokenMetadata} |
||||
* @param <T> the type of the token |
||||
* @return the {@link Builder} |
||||
*/ |
||||
public <T extends AbstractOAuth2Token> Builder token(T token, OAuth2TokenMetadata tokenMetadata) { |
||||
return addToken(token, tokenMetadata); |
||||
} |
||||
|
||||
protected Builder addToken(AbstractOAuth2Token token, OAuth2TokenMetadata tokenMetadata) { |
||||
Assert.notNull(token, "token cannot be null"); |
||||
if (tokenMetadata == null) { |
||||
tokenMetadata = OAuth2TokenMetadata.builder().build(); |
||||
} |
||||
this.tokens.put(token.getClass(), new OAuth2TokenHolder(token, tokenMetadata)); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Builds a new {@link OAuth2Tokens}. |
||||
* |
||||
* @return the {@link OAuth2Tokens} |
||||
*/ |
||||
public OAuth2Tokens build() { |
||||
return new OAuth2Tokens(this.tokens); |
||||
} |
||||
} |
||||
|
||||
protected static class OAuth2TokenHolder implements Serializable { |
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID; |
||||
private final AbstractOAuth2Token token; |
||||
private final OAuth2TokenMetadata tokenMetadata; |
||||
|
||||
protected OAuth2TokenHolder(AbstractOAuth2Token token, OAuth2TokenMetadata tokenMetadata) { |
||||
this.token = token; |
||||
this.tokenMetadata = tokenMetadata; |
||||
} |
||||
|
||||
protected AbstractOAuth2Token getToken() { |
||||
return this.token; |
||||
} |
||||
|
||||
protected OAuth2TokenMetadata getTokenMetadata() { |
||||
return this.tokenMetadata; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
if (this == obj) { |
||||
return true; |
||||
} |
||||
if (obj == null || getClass() != obj.getClass()) { |
||||
return false; |
||||
} |
||||
OAuth2TokenHolder that = (OAuth2TokenHolder) obj; |
||||
return Objects.equals(this.token, that.token) && |
||||
Objects.equals(this.tokenMetadata, that.tokenMetadata); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return Objects.hash(this.token, this.tokenMetadata); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.token; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
/** |
||||
* Tests for {@link OAuth2TokenMetadata}. |
||||
* |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class OAuth2TokenMetadataTests { |
||||
|
||||
@Test |
||||
public void metadataWhenNameNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
OAuth2TokenMetadata.builder() |
||||
.metadata(null, "value")) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("name cannot be empty"); |
||||
} |
||||
|
||||
@Test |
||||
public void metadataWhenValueNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> |
||||
OAuth2TokenMetadata.builder() |
||||
.metadata("name", null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("value cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void getMetadataWhenNameNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> OAuth2TokenMetadata.builder().build().getMetadata(null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("name cannot be empty"); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenDefaultThenDefaultsAreSet() { |
||||
OAuth2TokenMetadata tokenMetadata = OAuth2TokenMetadata.builder().build(); |
||||
assertThat(tokenMetadata.getMetadata()).hasSize(1); |
||||
assertThat(tokenMetadata.isInvalidated()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenMetadataProvidedThenMetadataIsSet() { |
||||
OAuth2TokenMetadata tokenMetadata = OAuth2TokenMetadata.builder() |
||||
.invalidated() |
||||
.metadata("name1", "value1") |
||||
.metadata(metadata -> metadata.put("name2", "value2")) |
||||
.build(); |
||||
assertThat(tokenMetadata.getMetadata()).hasSize(3); |
||||
assertThat(tokenMetadata.isInvalidated()).isTrue(); |
||||
assertThat(tokenMetadata.<String>getMetadata("name1")).isEqualTo("value1"); |
||||
assertThat(tokenMetadata.<String>getMetadata("name2")).isEqualTo("value2"); |
||||
} |
||||
} |
||||
@ -0,0 +1,187 @@
@@ -0,0 +1,187 @@
|
||||
/* |
||||
* Copyright 2020 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 |
||||
* |
||||
* https://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.server.authorization.token; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken; |
||||
import org.springframework.security.oauth2.core.OAuth2RefreshToken; |
||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken; |
||||
|
||||
import java.time.Duration; |
||||
import java.time.Instant; |
||||
import java.util.Arrays; |
||||
import java.util.HashSet; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
/** |
||||
* Tests for {@link OAuth2Tokens}. |
||||
* |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class OAuth2TokensTests { |
||||
private OAuth2AccessToken accessToken; |
||||
private OAuth2RefreshToken refreshToken; |
||||
private OidcIdToken idToken; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
Instant issuedAt = Instant.now(); |
||||
this.accessToken = new OAuth2AccessToken( |
||||
OAuth2AccessToken.TokenType.BEARER, |
||||
"access-token", |
||||
issuedAt, |
||||
issuedAt.plus(Duration.ofMinutes(5)), |
||||
new HashSet<>(Arrays.asList("read", "write"))); |
||||
this.refreshToken = new OAuth2RefreshToken( |
||||
"refresh-token", |
||||
issuedAt); |
||||
this.idToken = OidcIdToken.withTokenValue("id-token") |
||||
.issuer("https://provider.com") |
||||
.subject("subject") |
||||
.issuedAt(issuedAt) |
||||
.expiresAt(issuedAt.plus(Duration.ofMinutes(30))) |
||||
.build(); |
||||
} |
||||
|
||||
@Test |
||||
public void accessTokenWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().accessToken(null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("token cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void refreshTokenWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().refreshToken(null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("token cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void tokenWhenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().token(null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("token cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void getTokenWhenTokenTypeNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().build().getToken(null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("tokenType cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void getTokenMetadataWhenTokenNullThenThrowIllegalArgumentException() { |
||||
assertThatThrownBy(() -> OAuth2Tokens.builder().build().getTokenMetadata(null)) |
||||
.isInstanceOf(IllegalArgumentException.class) |
||||
.hasMessage("token cannot be null"); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenTokenMetadataNotProvidedThenDefaultsAreSet() { |
||||
OAuth2Tokens tokens = OAuth2Tokens.builder() |
||||
.accessToken(this.accessToken) |
||||
.refreshToken(this.refreshToken) |
||||
.token(this.idToken) |
||||
.build(); |
||||
|
||||
assertThat(tokens.getAccessToken()).isEqualTo(this.accessToken); |
||||
OAuth2TokenMetadata tokenMetadata = tokens.getTokenMetadata(tokens.getAccessToken()); |
||||
assertThat(tokenMetadata.isInvalidated()).isFalse(); |
||||
|
||||
assertThat(tokens.getRefreshToken()).isEqualTo(this.refreshToken); |
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getRefreshToken()); |
||||
assertThat(tokenMetadata.isInvalidated()).isFalse(); |
||||
|
||||
assertThat(tokens.getToken(OidcIdToken.class)).isEqualTo(this.idToken); |
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class)); |
||||
assertThat(tokenMetadata.isInvalidated()).isFalse(); |
||||
} |
||||
|
||||
@Test |
||||
public void buildWhenTokenMetadataProvidedThenTokenMetadataIsSet() { |
||||
OAuth2TokenMetadata expectedTokenMetadata = OAuth2TokenMetadata.builder().build(); |
||||
OAuth2Tokens tokens = OAuth2Tokens.builder() |
||||
.accessToken(this.accessToken, expectedTokenMetadata) |
||||
.refreshToken(this.refreshToken, expectedTokenMetadata) |
||||
.token(this.idToken, expectedTokenMetadata) |
||||
.build(); |
||||
|
||||
assertThat(tokens.getAccessToken()).isEqualTo(this.accessToken); |
||||
OAuth2TokenMetadata tokenMetadata = tokens.getTokenMetadata(tokens.getAccessToken()); |
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata); |
||||
|
||||
assertThat(tokens.getRefreshToken()).isEqualTo(this.refreshToken); |
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getRefreshToken()); |
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata); |
||||
|
||||
assertThat(tokens.getToken(OidcIdToken.class)).isEqualTo(this.idToken); |
||||
tokenMetadata = tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class)); |
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata); |
||||
} |
||||
|
||||
@Test |
||||
public void getTokenMetadataWhenTokenNotFoundThenNull() { |
||||
OAuth2TokenMetadata expectedTokenMetadata = OAuth2TokenMetadata.builder().build(); |
||||
OAuth2Tokens tokens = OAuth2Tokens.builder() |
||||
.accessToken(this.accessToken, expectedTokenMetadata) |
||||
.build(); |
||||
|
||||
assertThat(tokens.getAccessToken()).isEqualTo(this.accessToken); |
||||
OAuth2TokenMetadata tokenMetadata = tokens.getTokenMetadata(tokens.getAccessToken()); |
||||
assertThat(tokenMetadata).isEqualTo(expectedTokenMetadata); |
||||
|
||||
OAuth2AccessToken otherAccessToken = new OAuth2AccessToken( |
||||
this.accessToken.getTokenType(), |
||||
"other-access-token", |
||||
this.accessToken.getIssuedAt(), |
||||
this.accessToken.getExpiresAt(), |
||||
this.accessToken.getScopes()); |
||||
assertThat(tokens.getTokenMetadata(otherAccessToken)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
public void invalidateWhenAllTokensThenAllInvalidated() { |
||||
OAuth2Tokens tokens = OAuth2Tokens.builder() |
||||
.accessToken(this.accessToken) |
||||
.refreshToken(this.refreshToken) |
||||
.token(this.idToken) |
||||
.build(); |
||||
tokens.invalidate(); |
||||
|
||||
assertThat(tokens.getTokenMetadata(tokens.getAccessToken()).isInvalidated()).isTrue(); |
||||
assertThat(tokens.getTokenMetadata(tokens.getRefreshToken()).isInvalidated()).isTrue(); |
||||
assertThat(tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class)).isInvalidated()).isTrue(); |
||||
} |
||||
|
||||
@Test |
||||
public void invalidateWhenTokenProvidedThenInvalidated() { |
||||
OAuth2Tokens tokens = OAuth2Tokens.builder() |
||||
.accessToken(this.accessToken) |
||||
.refreshToken(this.refreshToken) |
||||
.token(this.idToken) |
||||
.build(); |
||||
tokens.invalidate(this.accessToken); |
||||
|
||||
assertThat(tokens.getTokenMetadata(tokens.getAccessToken()).isInvalidated()).isTrue(); |
||||
assertThat(tokens.getTokenMetadata(tokens.getRefreshToken()).isInvalidated()).isFalse(); |
||||
assertThat(tokens.getTokenMetadata(tokens.getToken(OidcIdToken.class)).isInvalidated()).isFalse(); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue