diff --git a/openid-connect-client/pom.xml b/openid-connect-client/pom.xml index fd33196a47..ad7191e176 100644 --- a/openid-connect-client/pom.xml +++ b/openid-connect-client/pom.xml @@ -22,7 +22,7 @@ openid-connect-parent org.mitre - 2.0.0.cnaf-20260603 + 2.1.0.cnaf-20260701 .. openid-connect-client diff --git a/openid-connect-common/pom.xml b/openid-connect-common/pom.xml index 5df3fa4ae2..af8795a9ef 100644 --- a/openid-connect-common/pom.xml +++ b/openid-connect-common/pom.xml @@ -22,7 +22,7 @@ openid-connect-parent org.mitre - 2.0.0.cnaf-20260603 + 2.1.0.cnaf-20260701 .. openid-connect-common diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java index 2695c18a2e..eab1e5fdc3 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2AccessTokenEntity.java @@ -21,10 +21,12 @@ package org.mitre.oauth2.model; import java.nio.charset.StandardCharsets; +import java.text.ParseException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.persistence.Basic; import javax.persistence.CascadeType; @@ -40,8 +42,6 @@ import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Temporal; @@ -62,291 +62,271 @@ * @author jricher * */ +@SuppressWarnings("deprecation") @Entity @Table(name = "access_token") -@NamedQueries({ - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_ALL, query = "select a from OAuth2AccessTokenEntity a"), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_EXPIRED_BY_DATE, query = "select a from OAuth2AccessTokenEntity a where a.expiration <= :" + OAuth2AccessTokenEntity.PARAM_DATE), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_REFRESH_TOKEN, query = "select a from OAuth2AccessTokenEntity a where a.refreshToken = :" + OAuth2AccessTokenEntity.PARAM_REFRESH_TOKEN), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_CLIENT, query = "select a from OAuth2AccessTokenEntity a where a.client = :" + OAuth2AccessTokenEntity.PARAM_CLIENT), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_TOKEN_VALUE_HASH, query = "select a from OAuth2AccessTokenEntity a where a.tokenValueHash = :" + OAuth2AccessTokenEntity.PARAM_TOKEN_VALUE_HASH), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_APPROVED_SITE, query = "select a from OAuth2AccessTokenEntity a where a.approvedSite = :" + OAuth2AccessTokenEntity.PARAM_APPROVED_SITE), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_RESOURCE_SET, query = "select a from OAuth2AccessTokenEntity a join a.permissions p where p.resourceSet.id = :" + OAuth2AccessTokenEntity.PARAM_RESOURCE_SET_ID), - @NamedQuery(name = OAuth2AccessTokenEntity.QUERY_BY_NAME, query = "select r from OAuth2AccessTokenEntity r where r.authenticationHolder.userAuth.name = :" + OAuth2AccessTokenEntity.PARAM_NAME), - @NamedQuery(name = OAuth2AccessTokenEntity.DELETE_BY_REFRESH_TOKEN, query = "delete from OAuth2AccessTokenEntity a where a.refreshToken = :" + OAuth2AccessTokenEntity.PARAM_REFRESH_TOKEN) -}) -@com.fasterxml.jackson.databind.annotation.JsonSerialize(using = OAuth2AccessTokenJackson2Serializer.class) -@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = OAuth2AccessTokenJackson2Deserializer.class) +@com.fasterxml.jackson.databind.annotation.JsonSerialize( + using = OAuth2AccessTokenJackson2Serializer.class) +@com.fasterxml.jackson.databind.annotation.JsonDeserialize( + using = OAuth2AccessTokenJackson2Deserializer.class) public class OAuth2AccessTokenEntity implements OAuth2AccessToken { - public static final String QUERY_BY_APPROVED_SITE = "OAuth2AccessTokenEntity.getByApprovedSite"; - public static final String QUERY_BY_TOKEN_VALUE_HASH = "OAuth2AccessTokenEntity.getByTokenValue"; - public static final String QUERY_BY_CLIENT = "OAuth2AccessTokenEntity.getByClient"; - public static final String QUERY_BY_REFRESH_TOKEN = "OAuth2AccessTokenEntity.getByRefreshToken"; - public static final String QUERY_EXPIRED_BY_DATE = "OAuth2AccessTokenEntity.getAllExpiredByDate"; - public static final String QUERY_ALL = "OAuth2AccessTokenEntity.getAll"; - public static final String QUERY_BY_RESOURCE_SET = "OAuth2AccessTokenEntity.getByResourceSet"; - public static final String QUERY_BY_NAME = "OAuth2AccessTokenEntity.getByName"; - public static final String DELETE_BY_REFRESH_TOKEN = "OAuth2AccessTokenEntity.deleteByRefreshToken"; - - public static final String PARAM_TOKEN_VALUE_HASH = "tokenValueHash"; - public static final String PARAM_CLIENT = "client"; - public static final String PARAM_REFRESH_TOKEN = "refreshToken"; - public static final String PARAM_DATE = "date"; - public static final String PARAM_RESOURCE_SET_ID = "rsid"; - public static final String PARAM_APPROVED_SITE = "approvedSite"; - public static final String PARAM_NAME = "name"; - - public static final String ID_TOKEN_FIELD_NAME = "id_token"; - - private Long id; - - private ClientDetailsEntity client; - - private AuthenticationHolderEntity authenticationHolder; // the authentication that made this access - - private JWT jwtValue; // JWT-encoded access token value - - private String tokenValueHash; // hash of access token value - - private Date expiration; - - private String tokenType = OAuth2AccessToken.BEARER_TYPE; - - private OAuth2RefreshTokenEntity refreshToken; - - private Set scope; - - private Set permissions; - - private ApprovedSite approvedSite; - - private Map additionalInformation = new HashMap<>(); // ephemeral map of items to be added to the OAuth token response - - /** - * Create a new, blank access token - */ - public OAuth2AccessTokenEntity() { - - } - - /** - * @return the id - */ - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - public Long getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } - - /** - * Get all additional information to be sent to the serializer as part of the token response. - * This map is not persisted to the database. - */ - @Override - @Transient - public Map getAdditionalInformation() { - return additionalInformation; - } - - /** - * The authentication in place when this token was created. - * @return the authentication - */ - @ManyToOne - @JoinColumn(name = "auth_holder_id") - public AuthenticationHolderEntity getAuthenticationHolder() { - return authenticationHolder; - } - - /** - * @param authentication the authentication to set - */ - public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { - this.authenticationHolder = authenticationHolder; - } - - /** - * @return the client - */ - @ManyToOne - @JoinColumn(name = "client_id") - public ClientDetailsEntity getClient() { - return client; - } - - /** - * @param client the client to set - */ - public void setClient(ClientDetailsEntity client) { - this.client = client; - } - - /** - * Get the string-encoded value of this access token. - */ - @Override - @Transient - public String getValue() { - return jwtValue.serialize(); - } - - @Override - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - @Column(name = "expiration") - public Date getExpiration() { - return expiration; - } - - public void setExpiration(Date expiration) { - this.expiration = expiration; - } - - @Override - @Basic - @Column(name="token_type") - public String getTokenType() { - return tokenType; - } - - public void setTokenType(String tokenType) { - this.tokenType = tokenType; - } - - @Override - @ManyToOne - @JoinColumn(name="refresh_token_id") - public OAuth2RefreshTokenEntity getRefreshToken() { - return refreshToken; - } - - public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) { - this.refreshToken = refreshToken; - } - - public void setRefreshToken(OAuth2RefreshToken refreshToken) { - if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) { - throw new IllegalArgumentException("Not a storable refresh token entity!"); - } - // force a pass through to the entity version - setRefreshToken((OAuth2RefreshTokenEntity)refreshToken); - } - - @Override - @ElementCollection(fetch=FetchType.EAGER) - @CollectionTable( - joinColumns=@JoinColumn(name="owner_id"), - name="token_scope" - ) - public Set getScope() { - return scope; - } - - public void setScope(Set scope) { - this.scope = scope; - } - - @Override - @Transient - public boolean isExpired() { - return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); - } - - /** - * @return the jwtValue - */ - @Basic - @Column(name="token_value") - @Convert(converter = JWTStringConverter.class) - public JWT getJwt() { - return jwtValue; - } - - /** - * @param jwtValue the jwtValue to set - */ - public void setJwt(JWT jwt) { - this.jwtValue = jwt; - } - - /** - * @return the tokenValueHash - */ - @Basic - @Column(name = "token_value_hash", length = 64) - public String getTokenValueHash() { - return tokenValueHash; - } - - public void setTokenValueHash(String hash) { - this.tokenValueHash = hash; - } - - @Override - @Transient - public int getExpiresIn() { - - if (getExpiration() == null) { - return -1; // no expiration time - } else { - int secondsRemaining = (int) ((getExpiration().getTime() - System.currentTimeMillis()) / 1000); - if (isExpired()) { - return 0; // has an expiration time and expired - } else { // has an expiration time and not expired - return secondsRemaining; - } - } - } - - /** - * @return the permissions - */ - @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @JoinTable( - name = "access_token_permissions", - joinColumns = @JoinColumn(name = "access_token_id"), - inverseJoinColumns = @JoinColumn(name = "permission_id") - ) - public Set getPermissions() { - return permissions; - } - - /** - * @param permissions the permissions to set - */ - public void setPermissions(Set permissions) { - this.permissions = permissions; - } - - @ManyToOne - @JoinColumn(name="approved_site_id") - public ApprovedSite getApprovedSite() { - return approvedSite; - } - - public void setApprovedSite(ApprovedSite approvedSite) { - this.approvedSite = approvedSite; - } - - /** - * Add the ID Token to the additionalInformation map for a token response. - * @param idToken - */ - @Transient - public void setIdToken(JWT idToken) { - if (idToken != null) { - additionalInformation.put(ID_TOKEN_FIELD_NAME, idToken.serialize()); - } - } + public static final String ID_TOKEN_FIELD_NAME = "id_token"; + + private Long id; + + private ClientDetailsEntity client; + + private AuthenticationHolderEntity authenticationHolder; + + private JWT jwtValue; + + private String tokenValueHash; + + private Date expiration; + + private String tokenType = OAuth2AccessToken.BEARER_TYPE; + + private OAuth2RefreshTokenEntity refreshToken; + + private Set scope; + + private Set permissions; + + private ApprovedSite approvedSite; + + private Map additionalInformation = new HashMap<>(); + + /** + * Create a new, blank access token + */ + public OAuth2AccessTokenEntity() { + + } + + /** + * @return the id + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * Get all additional information to be sent to the serializer as part of the token response. This + * map is not persisted to the database. + */ + @Override + @Transient + public Map getAdditionalInformation() { + return additionalInformation; + } + + /** + * The authentication in place when this token was created. + * + * @return the authentication + */ + @ManyToOne + @JoinColumn(name = "auth_holder_id") + public AuthenticationHolderEntity getAuthenticationHolder() { + return authenticationHolder; + } + + /** + * @param authentication the authentication to set + */ + public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { + this.authenticationHolder = authenticationHolder; + } + + /** + * @return the client + */ + @ManyToOne + @JoinColumn(name = "client_id") + public ClientDetailsEntity getClient() { + return client; + } + + /** + * @param client the client to set + */ + public void setClient(ClientDetailsEntity client) { + this.client = client; + } + + /** + * Get the string-encoded value of this access token. + */ + @Override + @Transient + public String getValue() { + return jwtValue.serialize(); + } + + @Override + @Basic + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Column(name = "expiration") + public Date getExpiration() { + return expiration; + } + + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + + @Override + @Basic + @Column(name = "token_type") + public String getTokenType() { + return tokenType; + } + + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } + + @Override + @ManyToOne + @JoinColumn(name = "refresh_token_id") + public OAuth2RefreshTokenEntity getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(OAuth2RefreshTokenEntity refreshToken) { + this.refreshToken = refreshToken; + } + + public void setRefreshToken(OAuth2RefreshToken refreshToken) { + if (!(refreshToken instanceof OAuth2RefreshTokenEntity)) { + throw new IllegalArgumentException("Not a storable refresh token entity!"); + } + // force a pass through to the entity version + setRefreshToken((OAuth2RefreshTokenEntity) refreshToken); + } + + @Override + @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(joinColumns = @JoinColumn(name = "owner_id"), name = "token_scope") + public Set getScope() { + return scope; + } + + public void setScope(Set scope) { + this.scope = scope; + } + + @Override + @Transient + public boolean isExpired() { + return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); + } + + /** + * @return the jwtValue + */ + @Basic + @Column(name = "token_value") + @Convert(converter = JWTStringConverter.class) + public JWT getJwt() { + return jwtValue; + } + + /** + * @param jwtValue the jwtValue to set + */ + public void setJwt(JWT jwt) { + this.jwtValue = jwt; + } + + /** + * @return the tokenValueHash + */ + @Basic + @Column(name = "token_value_hash", length = 64) + public String getTokenValueHash() { + return tokenValueHash; + } + + public void setTokenValueHash(String hash) { + this.tokenValueHash = hash; + } + + @Override + @Transient + public int getExpiresIn() { + + if (getExpiration() == null) { + return -1; // no expiration time + } else { + int secondsRemaining = + (int) ((getExpiration().getTime() - System.currentTimeMillis()) / 1000); + if (isExpired()) { + return 0; // has an expiration time and expired + } else { // has an expiration time and not expired + return secondsRemaining; + } + } + } + + /** + * @return the permissions + */ + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @JoinTable(name = "access_token_permissions", joinColumns = @JoinColumn(name = "access_token_id"), + inverseJoinColumns = @JoinColumn(name = "permission_id")) + public Set getPermissions() { + return permissions; + } + + /** + * @param permissions the permissions to set + */ + public void setPermissions(Set permissions) { + this.permissions = permissions; + } + + @ManyToOne + @JoinColumn(name = "approved_site_id") + public ApprovedSite getApprovedSite() { + return approvedSite; + } + + public void setApprovedSite(ApprovedSite approvedSite) { + this.approvedSite = approvedSite; + } + + /** + * Add the ID Token to the additionalInformation map for a token response. + * + * @param idToken + */ + @Transient + public void setIdToken(JWT idToken) { + if (idToken != null) { + additionalInformation.put(ID_TOKEN_FIELD_NAME, idToken.serialize()); + } + } + + @Transient + public Set getAudiences() { + try { + return jwtValue.getJWTClaimsSet().getAudience().stream().collect(Collectors.toSet()); + } catch (ParseException e) { + return Set.of(); + } + } public void hashMe() { if (jwtValue != null) { diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java index f6c2d2153c..b5813e5618 100644 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java +++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/OAuth2RefreshTokenEntity.java @@ -20,11 +20,10 @@ */ package org.mitre.oauth2.model; +import java.text.ParseException; import java.util.Date; -import javax.persistence.Basic; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; @@ -32,163 +31,91 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.Transient; -import org.mitre.oauth2.model.convert.JWTStringConverter; import org.springframework.security.oauth2.common.OAuth2RefreshToken; -import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.PlainJWT; -/** - * @author jricher - * - */ +@SuppressWarnings("deprecation") @Entity @Table(name = "refresh_token") -@NamedQueries({ - @NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_ALL, query = "select r from OAuth2RefreshTokenEntity r"), - @NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_EXPIRED_BY_DATE, query = "select r from OAuth2RefreshTokenEntity r where r.expiration <= :" + OAuth2RefreshTokenEntity.PARAM_DATE), - @NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_BY_CLIENT, query = "select r from OAuth2RefreshTokenEntity r where r.client = :" + OAuth2RefreshTokenEntity.PARAM_CLIENT), - @NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_BY_TOKEN_VALUE, query = "select r from OAuth2RefreshTokenEntity r where r.jwt = :" + OAuth2RefreshTokenEntity.PARAM_TOKEN_VALUE), - @NamedQuery(name = OAuth2RefreshTokenEntity.QUERY_BY_NAME, query = "select r from OAuth2RefreshTokenEntity r where r.authenticationHolder.userAuth.name = :" + OAuth2RefreshTokenEntity.PARAM_NAME) -}) public class OAuth2RefreshTokenEntity implements OAuth2RefreshToken { - public static final String QUERY_BY_TOKEN_VALUE = "OAuth2RefreshTokenEntity.getByTokenValue"; - public static final String QUERY_BY_CLIENT = "OAuth2RefreshTokenEntity.getByClient"; - public static final String QUERY_EXPIRED_BY_DATE = "OAuth2RefreshTokenEntity.getAllExpiredByDate"; - public static final String QUERY_ALL = "OAuth2RefreshTokenEntity.getAll"; - public static final String QUERY_BY_NAME = "OAuth2RefreshTokenEntity.getByName"; - - public static final String PARAM_TOKEN_VALUE = "tokenValue"; - public static final String PARAM_CLIENT = "client"; - public static final String PARAM_DATE = "date"; - public static final String PARAM_NAME = "name"; - - private Long id; - - private AuthenticationHolderEntity authenticationHolder; - - private ClientDetailsEntity client; - - //JWT-encoded representation of this access token entity - private JWT jwt; - - // our refresh tokens might expire - private Date expiration; - - /** - * - */ - public OAuth2RefreshTokenEntity() { - - } - - /** - * @return the id - */ - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - public Long getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } - - /** - * The authentication in place when the original access token was - * created - * - * @return the authentication - */ - @ManyToOne - @JoinColumn(name = "auth_holder_id") - public AuthenticationHolderEntity getAuthenticationHolder() { - return authenticationHolder; - } - - /** - * @param authentication the authentication to set - */ - public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { - this.authenticationHolder = authenticationHolder; - } - - /** - * Get the JWT-encoded value of this token - */ - @Override - @Transient - public String getValue() { - return jwt.serialize(); - } - - @Basic - @Temporal(javax.persistence.TemporalType.TIMESTAMP) - @Column(name = "expiration") - public Date getExpiration() { - return expiration; - } - - /* (non-Javadoc) - * @see org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken#setExpiration(java.util.Date) - */ - - public void setExpiration(Date expiration) { - this.expiration = expiration; - } - - /** - * Has this token expired? - * @return true if it has a timeout set and the timeout has passed - */ - @Transient - public boolean isExpired() { - return getExpiration() == null ? false : System.currentTimeMillis() > getExpiration().getTime(); - } - - /** - * @return the client - */ - @ManyToOne(fetch = FetchType.EAGER) - @JoinColumn(name = "client_id") - public ClientDetailsEntity getClient() { - return client; - } - - /** - * @param client the client to set - */ - public void setClient(ClientDetailsEntity client) { - this.client = client; - } - - /** - * Get the JWT object directly - * @return the jwt - */ - @Basic - @Column(name="token_value") - @Convert(converter = JWTStringConverter.class) - public JWT getJwt() { - return jwt; - } - - /** - * @param jwt the jwt to set - */ - public void setJwt(JWT jwt) { - this.jwt = jwt; - } + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @ManyToOne + @JoinColumn(name = "auth_holder_id") + private AuthenticationHolderEntity authenticationHolder; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "client_id") + private ClientDetailsEntity client; + + @Column(name = "token_value") + private String value; + + @Temporal(javax.persistence.TemporalType.TIMESTAMP) + @Column(name = "expiration") + private Date expiration; + + public OAuth2RefreshTokenEntity() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public AuthenticationHolderEntity getAuthenticationHolder() { + return authenticationHolder; + } + + public void setAuthenticationHolder(AuthenticationHolderEntity authenticationHolder) { + this.authenticationHolder = authenticationHolder; + } + + @Override + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Date getExpiration() { + return expiration; + } + + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + + public ClientDetailsEntity getClient() { + return client; + } + + public void setClient(ClientDetailsEntity client) { + this.client = client; + } + + @Transient + public PlainJWT getJwt() { + try { + return PlainJWT.parse(value); + } catch (ParseException e) { + return null; + } + } } diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java deleted file mode 100644 index 1b217de3e2..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthenticationHolderRepository.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.repository; - -import java.util.List; - -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.AuthenticationHolderEntity; - -public interface AuthenticationHolderRepository { - public List getAll(); - - public AuthenticationHolderEntity getById(Long id); - - public void remove(AuthenticationHolderEntity a); - - public AuthenticationHolderEntity save(AuthenticationHolderEntity a); - - public List getOrphanedAuthenticationHolders(); - - public List getOrphanedAuthenticationHolders(PageCriteria pageCriteria); -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java deleted file mode 100644 index 11375e7e64..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/AuthorizationCodeRepository.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.repository; - -import java.util.Collection; - -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.AuthorizationCodeEntity; - -/** - * Interface for saving and consuming OAuth2 authorization codes as AuthorizationCodeEntitys. - * - * @author aanganes - * - */ -public interface AuthorizationCodeRepository { - - /** - * Save an AuthorizationCodeEntity to the repository - * - * @param authorizationCode the AuthorizationCodeEntity to save - * @return the saved AuthorizationCodeEntity - */ - public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode); - - /** - * Get an authorization code from the repository by value. - * - * @param code the authorization code value - * @return the authentication associated with the code - */ - public AuthorizationCodeEntity getByCode(String code); - - /** - * Remove an authorization code from the repository - * - * @param authorizationCodeEntity - */ - public void remove(AuthorizationCodeEntity authorizationCodeEntity); - - /** - * @return A collection of all expired codes. - */ - public Collection getExpiredCodes(); - - /** - * @return A collection of all expired codes, limited by the given - * PageCriteria. - */ - public Collection getExpiredCodes(PageCriteria pageCriteria); - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java b/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java deleted file mode 100644 index e71d0a5975..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/repository/OAuth2TokenRepository.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.repository; - -import java.util.List; -import java.util.Set; - -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.uma.model.ResourceSet; - -public interface OAuth2TokenRepository { - - public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity token); - - public OAuth2RefreshTokenEntity getRefreshTokenByValue(String refreshTokenValue); - - public OAuth2RefreshTokenEntity getRefreshTokenById(Long Id); - - public void clearAccessTokensForRefreshToken(OAuth2RefreshTokenEntity refreshToken); - - public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken); - - public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); - - public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue); - - public OAuth2AccessTokenEntity getAccessTokenById(Long id); - - public void removeAccessToken(OAuth2AccessTokenEntity accessToken); - - public void clearTokensForClient(ClientDetailsEntity client); - - public List getAccessTokensForClient(ClientDetailsEntity client); - - public List getRefreshTokensForClient(ClientDetailsEntity client); - - public Set getAccessTokensByUserName(String name); - - public Set getRefreshTokensByUserName(String name); - - public Set getAllAccessTokens(); - - public Set getAllRefreshTokens(); - - public Set getAllExpiredAccessTokens(); - - public Set getAllExpiredAccessTokens(PageCriteria pageCriteria); - - public Set getAllExpiredRefreshTokens(); - - public Set getAllExpiredRefreshTokens(PageCriteria pageCriteria); - - public Set getAccessTokensForResourceSet(ResourceSet rs); - - /** - * removes duplicate access tokens. - * - * @deprecated this method was added to return the remove duplicate access tokens values - * so that {code removeAccessToken(OAuth2AccessTokenEntity o)} would not to fail. the - * removeAccessToken method has been updated so as it will not fail in the event that an - * accessToken has been duplicated, so this method is unnecessary. - * - */ - @Deprecated - public void clearDuplicateAccessTokens(); - - /** - * removes duplicate refresh tokens. - * - * @deprecated this method was added to return the remove duplicate refresh token value - * so that {code removeRefreshToken(OAuth2RefreshTokenEntity o)} would not to fail. the - * removeRefreshToken method has been updated so as it will not fail in the event that - * refreshToken has been duplicated, so this method is unnecessary. - * - */ - @Deprecated - public void clearDuplicateRefreshTokens(); - - public List getAccessTokensForApprovedSite(ApprovedSite approvedSite); - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/AuthenticationHolderEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/AuthenticationHolderEntityService.java deleted file mode 100644 index a33ca0e0b2..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/AuthenticationHolderEntityService.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.mitre.oauth2.service; - -import java.util.List; - -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.springframework.security.oauth2.provider.OAuth2Authentication; - -public interface AuthenticationHolderEntityService { - - AuthenticationHolderEntity create(OAuth2Authentication authn); - - void remove(AuthenticationHolderEntity holder); - - List getOrphanedAuthenticationHolders(); - - List getOrphanedAuthenticationHolders(PageCriteria page); - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java deleted file mode 100644 index 08695c6751..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/ClientDetailsEntityService.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.service; - -import java.util.Collection; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; -import org.springframework.security.oauth2.provider.ClientDetailsService; - -public interface ClientDetailsEntityService extends ClientDetailsService { - - public ClientDetailsEntity saveNewClient(ClientDetailsEntity client); - - public ClientDetailsEntity getClientById(Long id); - - @Override - public ClientDetailsEntity loadClientByClientId(String clientId) throws OAuth2Exception; - - public void deleteClient(ClientDetailsEntity client); - - public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient); - - public Collection getAllClients(); - - public ClientDetailsEntity generateClientId(ClientDetailsEntity client); - - public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client); - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java deleted file mode 100644 index cf0e5169f0..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/OAuth2TokenEntityService.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.service; - -import java.util.List; -import java.util.Set; - -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; -import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; - -@SuppressWarnings("deprecation") -public interface OAuth2TokenEntityService extends AuthorizationServerTokenServices, ResourceServerTokenServices { - - @Override - public OAuth2AccessTokenEntity readAccessToken(String accessTokenValue); - - public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue); - - public void revokeRefreshToken(OAuth2RefreshTokenEntity refreshToken); - - public void revokeAccessToken(OAuth2AccessTokenEntity accessToken); - - public List getAccessTokensForClient(ClientDetailsEntity client); - - public List getRefreshTokensForClient(ClientDetailsEntity client); - - public void clearExpiredTokens(); - - public OAuth2AccessTokenEntity saveAccessToken(OAuth2AccessTokenEntity accessToken); - - public OAuth2RefreshTokenEntity saveRefreshToken(OAuth2RefreshTokenEntity refreshToken); - - @Override - public OAuth2AccessTokenEntity getAccessToken(OAuth2Authentication authentication); - - public OAuth2AccessTokenEntity getAccessTokenById(Long id); - - public OAuth2RefreshTokenEntity getRefreshTokenById(Long id); - - public Set getAllAccessTokensForUser(String name); - - public Set getAllRefreshTokensForUser(String name); - - public OAuth2AccessTokenEntity getRegistrationAccessTokenForClient(ClientDetailsEntity client); - - public OAuth2RefreshTokenEntity createRefreshToken(ClientDetailsEntity client, AuthenticationHolderEntity authHolder); - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultAuthenticationHolderEntityService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultAuthenticationHolderEntityService.java deleted file mode 100644 index 55ab15b71e..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultAuthenticationHolderEntityService.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.mitre.oauth2.service.impl; - -import java.util.List; - -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.service.AuthenticationHolderEntityService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Service; - -@Service("authenticationHolderEntityService") -public class DefaultAuthenticationHolderEntityService implements AuthenticationHolderEntityService { - - private final AuthenticationHolderRepository repo; - - @Autowired - public DefaultAuthenticationHolderEntityService(AuthenticationHolderRepository repo) { - this.repo = repo; - } - - @Override - public AuthenticationHolderEntity create(OAuth2Authentication authn) { - AuthenticationHolderEntity holder = new AuthenticationHolderEntity(); - holder.setAuthentication(authn); - - return repo.save(holder); - } - - @Override - public void remove(AuthenticationHolderEntity holder) { - repo.remove(holder); - } - - @Override - public List getOrphanedAuthenticationHolders() { - - return repo.getOrphanedAuthenticationHolders(); - } - - @Override - public List getOrphanedAuthenticationHolders( - PageCriteria pageCriteria) { - return repo.getOrphanedAuthenticationHolders(pageCriteria); - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java deleted file mode 100644 index da7a177c87..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/DefaultClientUserDetailsService.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.service.impl; - -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Collection; -import java.util.HashSet; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.stereotype.Service; - -import com.google.common.base.Strings; - -/** - * Shim layer to convert a ClientDetails service into a UserDetails service - * - * @author AANGANES - * - */ -@Service("clientUserDetailsService") -public class DefaultClientUserDetailsService implements UserDetailsService { - - private static GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT"); - - @Autowired - private ClientDetailsEntityService clientDetailsService; - - @Autowired - private ConfigurationPropertiesBean config; - - @Override - public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException { - - try { - ClientDetailsEntity client = clientDetailsService.loadClientByClientId(clientId); - - if (client != null) { - - String password = Strings.nullToEmpty(client.getClientSecret()); - - if (config.isHeartMode() || // if we're running HEART mode turn off all client secrets - (client.getTokenEndpointAuthMethod() != null && - (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) || - client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT)))) { - - // Issue a random password each time to prevent password auth from being used (or skipped) - // for private key or shared key clients, see #715 - - password = new BigInteger(512, new SecureRandom()).toString(16); - } - - boolean enabled = true; - boolean accountNonExpired = true; - boolean credentialsNonExpired = true; - boolean accountNonLocked = true; - Collection authorities = new HashSet<>(client.getAuthorities()); - authorities.add(ROLE_CLIENT); - - return new User(clientId, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); - } else { - throw new UsernameNotFoundException("Client not found: " + clientId); - } - } catch (InvalidClientException e) { - throw new UsernameNotFoundException("Client not found: " + clientId); - } - - } - - public ClientDetailsEntityService getClientDetailsService() { - return clientDetailsService; - } - - public void setClientDetailsService(ClientDetailsEntityService clientDetailsService) { - this.clientDetailsService = clientDetailsService; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/UriEncodedClientUserDetailsService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/UriEncodedClientUserDetailsService.java deleted file mode 100644 index 9b8f6f45af..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/impl/UriEncodedClientUserDetailsService.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.oauth2.service.impl; - -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.Collection; -import java.util.HashSet; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.stereotype.Service; -import org.springframework.web.util.UriUtils; - -import com.google.common.base.Strings; - -/** - * Loads client details based on URI encoding as passed in from basic auth. - * - * Should only get called if non-encoded provider fails. - * - * @author AANGANES - * - */ -@Service("uriEncodedClientUserDetailsService") -public class UriEncodedClientUserDetailsService implements UserDetailsService { - - private static GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT"); - - @Autowired - private ClientDetailsEntityService clientDetailsService; - - @Autowired - private ConfigurationPropertiesBean config; - - @Override - public UserDetails loadUserByUsername(String clientId) throws UsernameNotFoundException { - - try { - String decodedClientId = UriUtils.decode(clientId, "UTF-8"); - - ClientDetailsEntity client = clientDetailsService.loadClientByClientId(decodedClientId); - - if (client != null) { - - String encodedPassword = UriUtils.encodePathSegment(Strings.nullToEmpty(client.getClientSecret()), "UTF-8"); - - if (config.isHeartMode() || // if we're running HEART mode turn off all client secrets - (client.getTokenEndpointAuthMethod() != null && - (client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) || - client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT)))) { - - // Issue a random password each time to prevent password auth from being used (or skipped) - // for private key or shared key clients, see #715 - - encodedPassword = new BigInteger(512, new SecureRandom()).toString(16); - } - - boolean enabled = true; - boolean accountNonExpired = true; - boolean credentialsNonExpired = true; - boolean accountNonLocked = true; - Collection authorities = new HashSet<>(client.getAuthorities()); - authorities.add(ROLE_CLIENT); - - return new User(decodedClientId, encodedPassword, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); - } else { - throw new UsernameNotFoundException("Client not found: " + clientId); - } - } catch (InvalidClientException e) { - throw new UsernameNotFoundException("Client not found: " + clientId); - } - - } - - public ClientDetailsEntityService getClientDetailsService() { - return clientDetailsService; - } - - public void setClientDetailsService(ClientDetailsEntityService clientDetailsService) { - this.clientDetailsService = clientDetailsService; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/DynamicClientValidationService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/DynamicClientValidationService.java deleted file mode 100644 index 98754101cb..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/DynamicClientValidationService.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.mitre.openid.connect.service; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.openid.connect.exception.ValidationException; - -public interface DynamicClientValidationService { - - public ClientDetailsEntity validateClient(ClientDetailsEntity client) throws ValidationException; - -} diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java deleted file mode 100644 index 146f6164e4..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service; - -import java.util.Date; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import com.nimbusds.jwt.JWT; - -/** - * Service to create specialty OpenID Connect tokens. - * - * @author Amanda Anganes - * - */ -public interface OIDCTokenService { - - /** - * Create an id token with the information provided. - * - * @param client - * @param request - * @param issueTime - * @param sub - * @param signingAlg - * @param accessToken - * @return - */ - public JWT createIdToken( - ClientDetailsEntity client, OAuth2Request request, Date issueTime, - String sub, OAuth2AccessTokenEntity accessToken); - - /** - * Create a registration access token for the given client. - * - * @param client - * @return - */ - public OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client); - - /** - * Create a resource access token for the given client (protected resource). - * - * @param client - * @return - */ - public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client); - - /** - * Rotate the registration or resource token for a client - * @param client - * @return - */ - public OAuth2AccessTokenEntity rotateRegistrationAccessTokenForClient(ClientDetailsEntity client); - -} \ No newline at end of file diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java deleted file mode 100644 index ac7ab41070..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/web/UserInfoInterceptor.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.web; - -import java.lang.reflect.Type; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.mitre.openid.connect.model.OIDCAuthenticationToken; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.UserInfoService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationTrustResolver; -import org.springframework.security.authentication.AuthenticationTrustResolverImpl; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -/** - * Injects the UserInfo object for the current user into the current model's context, if both exist. Allows JSPs and the like to call "userInfo.name" and other fields. - * - * @author jricher - * - */ -public class UserInfoInterceptor extends HandlerInterceptorAdapter { - - private Gson gson = new GsonBuilder() - .registerTypeHierarchyAdapter(GrantedAuthority.class, new JsonSerializer() { - @Override - public JsonElement serialize(GrantedAuthority src, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(src.getAuthority()); - } - }) - .create(); - - @Autowired (required = false) - private UserInfoService userInfoService; - - private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - - if (auth instanceof Authentication){ - request.setAttribute("userAuthorities", gson.toJson(auth.getAuthorities())); - } - - if (!trustResolver.isAnonymous(auth)) { // skip lookup on anonymous logins - if (auth instanceof OIDCAuthenticationToken) { - // if they're logging into this server from a remote OIDC server, pass through their user info - OIDCAuthenticationToken oidc = (OIDCAuthenticationToken) auth; - if (oidc.getUserInfo() != null) { - request.setAttribute("userInfo", oidc.getUserInfo()); - request.setAttribute("userInfoJson", oidc.getUserInfo().toJson()); - } else { - request.setAttribute("userInfo", null); - request.setAttribute("userInfoJson", "null"); - } - } else { - // don't bother checking if we don't have a principal or a userInfoService to work with - if (auth != null && auth.getName() != null && userInfoService != null) { - - // try to look up a user based on the principal's name - UserInfo user = userInfoService.getByUsername(auth.getName()); - - // if we have one, inject it so views can use it - if (user != null) { - request.setAttribute("userInfo", user); - request.setAttribute("userInfoJson", user.toJson()); - } - } - } - } - - return true; - } - -} diff --git a/openid-connect-common/src/main/java/org/mitre/uma/service/ResourceSetService.java b/openid-connect-common/src/main/java/org/mitre/uma/service/ResourceSetService.java deleted file mode 100644 index 8da2ce017c..0000000000 --- a/openid-connect-common/src/main/java/org/mitre/uma/service/ResourceSetService.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service; - -import java.util.Collection; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.uma.model.ResourceSet; - -/** - * - * Manage registered resource sets at this authorization server. - * - * @author jricher - * - */ -public interface ResourceSetService { - - public ResourceSet saveNew(ResourceSet rs); - - public ResourceSet getById(Long id); - - public ResourceSet update(ResourceSet oldRs, ResourceSet newRs); - - public void remove(ResourceSet rs); - - public Collection getAllForOwner(String owner); - - public Collection getAllForOwnerAndClient(String owner, String authClientId); - - public Collection getAllForClient(ClientDetailsEntity client); - -} diff --git a/openid-connect-server/pom.xml b/openid-connect-server/pom.xml index ada12f5a57..199934f004 100644 --- a/openid-connect-server/pom.xml +++ b/openid-connect-server/pom.xml @@ -23,7 +23,7 @@ org.mitre openid-connect-parent - 2.0.0.cnaf-20260603 + 2.1.0.cnaf-20260701 .. diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java deleted file mode 100644 index 269db62171..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthenticationHolderRepository.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.repository.impl; - -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; - -import org.mitre.data.DefaultPageCriteria; -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.util.jpa.JpaUtil; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -@Repository -@Transactional(value="defaultTransactionManager") -public class JpaAuthenticationHolderRepository implements AuthenticationHolderRepository { - - private static final int MAXEXPIREDRESULTS = 1000; - - @PersistenceContext(unitName="defaultPersistenceUnit") - private EntityManager manager; - - @Override - public List getAll() { - TypedQuery query = manager.createNamedQuery(AuthenticationHolderEntity.QUERY_ALL, AuthenticationHolderEntity.class); - return query.getResultList(); - } - - @Override - public AuthenticationHolderEntity getById(Long id) { - return manager.find(AuthenticationHolderEntity.class, id); - } - - @Override - @Transactional(value="defaultTransactionManager") - public void remove(AuthenticationHolderEntity a) { - AuthenticationHolderEntity found = getById(a.getId()); - if (found != null) { - manager.remove(found); - } else { - throw new IllegalArgumentException("AuthenticationHolderEntity not found: " + a); - } - } - - @Override - @Transactional(value="defaultTransactionManager") - public AuthenticationHolderEntity save(AuthenticationHolderEntity a) { - return JpaUtil.saveOrUpdate(a.getId(), manager, a); - } - - @Override - @Transactional(value="defaultTransactionManager") - public List getOrphanedAuthenticationHolders() { - DefaultPageCriteria pageCriteria = new DefaultPageCriteria(0,MAXEXPIREDRESULTS); - return getOrphanedAuthenticationHolders(pageCriteria); - } - - @Override - @Transactional(value="defaultTransactionManager") - public List getOrphanedAuthenticationHolders(PageCriteria pageCriteria) { - TypedQuery query = manager.createNamedQuery(AuthenticationHolderEntity.QUERY_GET_UNUSED, AuthenticationHolderEntity.class); - return JpaUtil.getResultPage(query, pageCriteria); - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java deleted file mode 100644 index ad7788b6c0..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaAuthorizationCodeRepository.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.repository.impl; - -import java.util.Collection; -import java.util.Date; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; - -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.AuthorizationCodeEntity; -import org.mitre.oauth2.repository.AuthorizationCodeRepository; -import org.mitre.util.jpa.JpaUtil; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -/** - * JPA AuthorizationCodeRepository implementation. - * - * @author aanganes - * - */ -@Repository -@Transactional(value="defaultTransactionManager") -public class JpaAuthorizationCodeRepository implements AuthorizationCodeRepository { - - @PersistenceContext(unitName="defaultPersistenceUnit") - EntityManager manager; - - /* (non-Javadoc) - * @see org.mitre.oauth2.repository.AuthorizationCodeRepository#save(org.mitre.oauth2.model.AuthorizationCodeEntity) - */ - @Override - @Transactional(value="defaultTransactionManager") - public AuthorizationCodeEntity save(AuthorizationCodeEntity authorizationCode) { - - return JpaUtil.saveOrUpdate(authorizationCode.getId(), manager, authorizationCode); - - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.repository.AuthorizationCodeRepository#getByCode(java.lang.String) - */ - @Override - @Transactional(value="defaultTransactionManager") - public AuthorizationCodeEntity getByCode(String code) { - TypedQuery query = manager.createNamedQuery(AuthorizationCodeEntity.QUERY_BY_VALUE, AuthorizationCodeEntity.class); - query.setParameter("code", code); - - AuthorizationCodeEntity result = JpaUtil.getSingleResult(query.getResultList()); - return result; - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.repository.AuthorizationCodeRepository#remove(org.mitre.oauth2.model.AuthorizationCodeEntity) - */ - @Override - public void remove(AuthorizationCodeEntity authorizationCodeEntity) { - AuthorizationCodeEntity found = manager.find(AuthorizationCodeEntity.class, authorizationCodeEntity.getId()); - if (found != null) { - manager.remove(found); - } - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.repository.AuthorizationCodeRepository#getExpiredCodes() - */ - @Override - public Collection getExpiredCodes() { - TypedQuery query = manager.createNamedQuery(AuthorizationCodeEntity.QUERY_EXPIRATION_BY_DATE, AuthorizationCodeEntity.class); - query.setParameter(AuthorizationCodeEntity.PARAM_DATE, new Date()); // this gets anything that's already expired - return query.getResultList(); - } - - - @Override - public Collection getExpiredCodes(PageCriteria pageCriteria) { - TypedQuery query = manager.createNamedQuery(AuthorizationCodeEntity.QUERY_EXPIRATION_BY_DATE, AuthorizationCodeEntity.class); - query.setParameter(AuthorizationCodeEntity.PARAM_DATE, new Date()); // this gets anything that's already expired - return JpaUtil.getResultPage(query, pageCriteria); - } - - - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java b/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java deleted file mode 100644 index becb26710c..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/repository/impl/JpaOAuth2TokenRepository.java +++ /dev/null @@ -1,343 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.repository.impl; - -import java.nio.charset.StandardCharsets; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaDelete; -import javax.persistence.criteria.Root; - -import org.mitre.data.DefaultPageCriteria; -import org.mitre.data.PageCriteria; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.uma.model.ResourceSet; -import org.mitre.util.jpa.JpaUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import com.google.common.hash.Hashing; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTParser; - -@Repository -public class JpaOAuth2TokenRepository implements OAuth2TokenRepository { - - private static final int MAXEXPIREDRESULTS = 1000; - - private static final Logger logger = - LoggerFactory.getLogger(JpaOAuth2TokenRepository.class); - - @PersistenceContext(unitName = "defaultPersistenceUnit") - private EntityManager manager; - - @Override - public Set getAllAccessTokens() { - TypedQuery query = - manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_ALL, - OAuth2AccessTokenEntity.class); - return new LinkedHashSet<>(query.getResultList()); - } - - @Override - public Set getAllRefreshTokens() { - TypedQuery query = - manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_ALL, - OAuth2RefreshTokenEntity.class); - return new LinkedHashSet<>(query.getResultList()); - } - - @Override - public OAuth2AccessTokenEntity getAccessTokenByValue(String accessTokenValue) { - String atHashed = - Hashing.sha256().hashString(accessTokenValue, StandardCharsets.UTF_8).toString(); - TypedQuery query = manager.createNamedQuery( - OAuth2AccessTokenEntity.QUERY_BY_TOKEN_VALUE_HASH, - OAuth2AccessTokenEntity.class); - query.setParameter(OAuth2AccessTokenEntity.PARAM_TOKEN_VALUE_HASH, - atHashed); - return JpaUtil.getSingleResult(query.getResultList()); - } - - @Override - public OAuth2AccessTokenEntity getAccessTokenById(Long id) { - return manager.find(OAuth2AccessTokenEntity.class, id); - } - - @Override - @Transactional(value = "defaultTransactionManager") - public OAuth2AccessTokenEntity saveAccessToken( - OAuth2AccessTokenEntity token) { - return JpaUtil.saveOrUpdate(token.getId(), manager, token); - } - - @Override - @Transactional(value = "defaultTransactionManager") - public void removeAccessToken(OAuth2AccessTokenEntity accessToken) { - OAuth2AccessTokenEntity found = getAccessTokenById(accessToken.getId()); - if (found != null) { - manager.remove(found); - } else { - throw new IllegalArgumentException( - "Access token not found: " + accessToken); - } - } - - @Override - @Transactional(value = "defaultTransactionManager") - public void clearAccessTokensForRefreshToken( - OAuth2RefreshTokenEntity refreshToken) { - TypedQuery query = manager.createNamedQuery( - OAuth2AccessTokenEntity.DELETE_BY_REFRESH_TOKEN, - OAuth2AccessTokenEntity.class); - query.setParameter(OAuth2AccessTokenEntity.PARAM_REFRESH_TOKEN, - refreshToken); - query.executeUpdate(); - } - - @Override - public OAuth2RefreshTokenEntity getRefreshTokenByValue( - String refreshTokenValue) { - try { - JWT jwt = JWTParser.parse(refreshTokenValue); - TypedQuery query = manager - .createNamedQuery(OAuth2RefreshTokenEntity.QUERY_BY_TOKEN_VALUE, - OAuth2RefreshTokenEntity.class); - query.setParameter(OAuth2RefreshTokenEntity.PARAM_TOKEN_VALUE, jwt); - return JpaUtil.getSingleResult(query.getResultList()); - } catch (ParseException e) { - return null; - } - } - - @Override - public OAuth2RefreshTokenEntity getRefreshTokenById(Long id) { - return manager.find(OAuth2RefreshTokenEntity.class, id); - } - - @Override - @Transactional(value = "defaultTransactionManager") - public OAuth2RefreshTokenEntity saveRefreshToken( - OAuth2RefreshTokenEntity refreshToken) { - return JpaUtil.saveOrUpdate(refreshToken.getId(), manager, - refreshToken); - } - - @Override - @Transactional(value = "defaultTransactionManager") - public void removeRefreshToken(OAuth2RefreshTokenEntity refreshToken) { - OAuth2RefreshTokenEntity found = - getRefreshTokenById(refreshToken.getId()); - if (found != null) { - manager.remove(found); - } else { - throw new IllegalArgumentException( - "Refresh token not found: " + refreshToken); - } - } - - @Override - @Transactional(value = "defaultTransactionManager") - public void clearTokensForClient(ClientDetailsEntity client) { - TypedQuery queryA = manager.createNamedQuery( - OAuth2AccessTokenEntity.QUERY_BY_CLIENT, - OAuth2AccessTokenEntity.class); - queryA.setParameter(OAuth2AccessTokenEntity.PARAM_CLIENT, client); - List accessTokens = queryA.getResultList(); - for (OAuth2AccessTokenEntity accessToken : accessTokens) { - removeAccessToken(accessToken); - } - TypedQuery queryR = manager.createNamedQuery( - OAuth2RefreshTokenEntity.QUERY_BY_CLIENT, - OAuth2RefreshTokenEntity.class); - queryR.setParameter(OAuth2RefreshTokenEntity.PARAM_CLIENT, client); - List refreshTokens = queryR.getResultList(); - for (OAuth2RefreshTokenEntity refreshToken : refreshTokens) { - removeRefreshToken(refreshToken); - } - } - - @Override - public List getAccessTokensForClient( - ClientDetailsEntity client) { - TypedQuery queryA = manager.createNamedQuery( - OAuth2AccessTokenEntity.QUERY_BY_CLIENT, - OAuth2AccessTokenEntity.class); - queryA.setParameter(OAuth2AccessTokenEntity.PARAM_CLIENT, client); - List accessTokens = queryA.getResultList(); - return accessTokens; - } - - @Override - public List getRefreshTokensForClient( - ClientDetailsEntity client) { - TypedQuery queryR = manager.createNamedQuery( - OAuth2RefreshTokenEntity.QUERY_BY_CLIENT, - OAuth2RefreshTokenEntity.class); - queryR.setParameter(OAuth2RefreshTokenEntity.PARAM_CLIENT, client); - List refreshTokens = queryR.getResultList(); - return refreshTokens; - } - - @Override - public Set getAccessTokensByUserName(String name) { - TypedQuery query = - manager.createNamedQuery(OAuth2AccessTokenEntity.QUERY_BY_NAME, - OAuth2AccessTokenEntity.class); - query.setParameter(OAuth2AccessTokenEntity.PARAM_NAME, name); - List results = query.getResultList(); - return results != null ? new HashSet<>(results) : new HashSet<>(); - } - - @Override - public Set getRefreshTokensByUserName( - String name) { - TypedQuery query = - manager.createNamedQuery(OAuth2RefreshTokenEntity.QUERY_BY_NAME, - OAuth2RefreshTokenEntity.class); - query.setParameter(OAuth2RefreshTokenEntity.PARAM_NAME, name); - List results = query.getResultList(); - return results != null ? new HashSet<>(results) : new HashSet<>(); - } - - @Override - public Set getAllExpiredAccessTokens() { - DefaultPageCriteria pageCriteria = - new DefaultPageCriteria(0, MAXEXPIREDRESULTS); - return getAllExpiredAccessTokens(pageCriteria); - } - - @Override - public Set getAllExpiredAccessTokens( - PageCriteria pageCriteria) { - TypedQuery query = manager.createNamedQuery( - OAuth2AccessTokenEntity.QUERY_EXPIRED_BY_DATE, - OAuth2AccessTokenEntity.class); - query.setParameter(OAuth2AccessTokenEntity.PARAM_DATE, new Date()); - return new LinkedHashSet<>(JpaUtil.getResultPage(query, pageCriteria)); - } - - @Override - public Set getAllExpiredRefreshTokens() { - DefaultPageCriteria pageCriteria = - new DefaultPageCriteria(0, MAXEXPIREDRESULTS); - return getAllExpiredRefreshTokens(pageCriteria); - } - - @Override - public Set getAllExpiredRefreshTokens( - PageCriteria pageCriteria) { - TypedQuery query = manager.createNamedQuery( - OAuth2RefreshTokenEntity.QUERY_EXPIRED_BY_DATE, - OAuth2RefreshTokenEntity.class); - query.setParameter(OAuth2AccessTokenEntity.PARAM_DATE, new Date()); - return new LinkedHashSet<>(JpaUtil.getResultPage(query, pageCriteria)); - } - - @Override - public Set getAccessTokensForResourceSet( - ResourceSet rs) { - TypedQuery query = manager.createNamedQuery( - OAuth2AccessTokenEntity.QUERY_BY_RESOURCE_SET, - OAuth2AccessTokenEntity.class); - query.setParameter(OAuth2AccessTokenEntity.PARAM_RESOURCE_SET_ID, - rs.getId()); - return new LinkedHashSet<>(query.getResultList()); - } - - @Override - @Transactional(value = "defaultTransactionManager") - public void clearDuplicateAccessTokens() { - Query query = manager.createQuery( - "select a.jwt, count(1) as c from OAuth2AccessTokenEntity a GROUP BY a.jwt HAVING count(1) > 1"); - @SuppressWarnings("unchecked") - List resultList = query.getResultList(); - List values = new ArrayList<>(); - for (Object[] r : resultList) { - logger.warn("Found duplicate access tokens: {}, {}", - ((JWT) r[0]).serialize(), r[1]); - values.add((JWT) r[0]); - } - if (values.size() > 0) { - CriteriaBuilder cb = manager.getCriteriaBuilder(); - CriteriaDelete criteriaDelete = - cb.createCriteriaDelete(OAuth2AccessTokenEntity.class); - Root root = - criteriaDelete.from(OAuth2AccessTokenEntity.class); - criteriaDelete.where(root.get("jwt").in(values)); - int result = manager.createQuery(criteriaDelete).executeUpdate(); - logger.warn("Deleted {} duplicate access tokens", result); - } - } - - @Override - @Transactional(value = "defaultTransactionManager") - public void clearDuplicateRefreshTokens() { - Query query = manager.createQuery( - "select a.jwt, count(1) as c from OAuth2RefreshTokenEntity a GROUP BY a.jwt HAVING count(1) > 1"); - @SuppressWarnings("unchecked") - List resultList = query.getResultList(); - List values = new ArrayList<>(); - for (Object[] r : resultList) { - logger.warn("Found duplicate refresh tokens: {}, {}", - ((JWT) r[0]).serialize(), r[1]); - values.add((JWT) r[0]); - } - if (values.size() > 0) { - CriteriaBuilder cb = manager.getCriteriaBuilder(); - CriteriaDelete criteriaDelete = - cb.createCriteriaDelete(OAuth2RefreshTokenEntity.class); - Root root = - criteriaDelete.from(OAuth2RefreshTokenEntity.class); - criteriaDelete.where(root.get("jwt").in(values)); - int result = manager.createQuery(criteriaDelete).executeUpdate(); - logger.warn("Deleted {} duplicate refresh tokens", result); - } - - } - - @Override - public List getAccessTokensForApprovedSite( - ApprovedSite approvedSite) { - TypedQuery queryA = manager.createNamedQuery( - OAuth2AccessTokenEntity.QUERY_BY_APPROVED_SITE, - OAuth2AccessTokenEntity.class); - queryA.setParameter(OAuth2AccessTokenEntity.PARAM_APPROVED_SITE, - approvedSite); - List accessTokens = queryA.getResultList(); - return accessTokens; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultDeviceCodeService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultDeviceCodeService.java deleted file mode 100644 index 29f4ec8d22..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultDeviceCodeService.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.oauth2.service.impl; - -import java.util.Collection; -import java.util.Date; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.mitre.data.AbstractPageOperationTemplate; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.DeviceCode; -import org.mitre.oauth2.repository.impl.DeviceCodeRepository; -import org.mitre.oauth2.service.DeviceCodeService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author jricher - * - */ -@Service("defaultDeviceCodeService") -public class DefaultDeviceCodeService implements DeviceCodeService { - - @Autowired - private DeviceCodeRepository repository; - - private RandomValueStringGenerator randomGenerator = new RandomValueStringGenerator(); - - /* (non-Javadoc) - * @see org.mitre.oauth2.service.DeviceCodeService#save(org.mitre.oauth2.model.DeviceCode) - */ - @Override - public DeviceCode createNewDeviceCode(Set requestedScopes, ClientDetailsEntity client, Map parameters) { - - // create a device code, should be big and random - String deviceCode = UUID.randomUUID().toString(); - - // create a user code, should be random but small and typable, and always uppercase (lookup is case insensitive) - String userCode = randomGenerator.generate().toUpperCase(); - - DeviceCode dc = new DeviceCode(deviceCode, userCode, requestedScopes, client.getClientId(), parameters); - - if (client.getDeviceCodeValiditySeconds() != null) { - dc.setExpiration(new Date(System.currentTimeMillis() + client.getDeviceCodeValiditySeconds() * 1000L)); - } - - dc.setApproved(false); - - return repository.save(dc); - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.service.DeviceCodeService#lookUpByUserCode(java.lang.String) - */ - @Override - public DeviceCode lookUpByUserCode(String userCode) { - // always up-case the code for lookup - return repository.getByUserCode(userCode.toUpperCase()); - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.service.DeviceCodeService#approveDeviceCode(org.mitre.oauth2.model.DeviceCode) - */ - @Override - public DeviceCode approveDeviceCode(DeviceCode dc, OAuth2Authentication auth) { - DeviceCode found = repository.getById(dc.getId()); - - found.setApproved(true); - - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setAuthentication(auth); - - found.setAuthenticationHolder(authHolder); - - return repository.save(found); - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.service.DeviceCodeService#consumeDeviceCode(java.lang.String, org.springframework.security.oauth2.provider.ClientDetails) - */ - @Override - public DeviceCode findDeviceCode(String deviceCode, ClientDetails client) { - DeviceCode found = repository.getByDeviceCode(deviceCode); - - if (found != null) { - if (found.getClientId().equals(client.getClientId())) { - // make sure the client matches, if so, we're good - return found; - } else { - // if the clients don't match, pretend the code wasn't found - return null; - } - } else { - // didn't find the code, return null - return null; - } - - } - - - - /* (non-Javadoc) - * @see org.mitre.oauth2.service.DeviceCodeService#clearExpiredDeviceCodes() - */ - @Override - @Transactional(value="defaultTransactionManager") - public void clearExpiredDeviceCodes() { - - new AbstractPageOperationTemplate("clearExpiredDeviceCodes"){ - @Override - public Collection fetchPage() { - return repository.getExpiredCodes(); - } - - @Override - protected void doOperation(DeviceCode item) { - repository.remove(item); - } - }.execute(); - } - - /* (non-Javadoc) - * @see org.mitre.oauth2.service.DeviceCodeService#clearDeviceCode(java.lang.String, org.springframework.security.oauth2.provider.ClientDetails) - */ - @Override - public void clearDeviceCode(String deviceCode, ClientDetails client) { - DeviceCode found = findDeviceCode(deviceCode, client); - - if (found != null) { - // make sure it's not used twice - repository.remove(found); - } - - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java deleted file mode 100644 index 8250a56c6d..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2AuthorizationCodeService.java +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.service.impl; - -import java.util.Collection; -import java.util.Date; - -import org.mitre.data.AbstractPageOperationTemplate; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.AuthorizationCodeEntity; -import org.mitre.oauth2.repository.AuthorizationCodeRepository; -import org.mitre.oauth2.service.AuthenticationHolderEntityService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; -import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * Database-backed, random-value authorization code service implementation. - * - * @author aanganes - * - */ -@Service("defaultOAuth2AuthorizationCodeService") -public class DefaultOAuth2AuthorizationCodeService implements AuthorizationCodeServices { - // Logger for this class - private static final Logger logger = LoggerFactory.getLogger(DefaultOAuth2AuthorizationCodeService.class); - - @Autowired - private AuthorizationCodeRepository repository; - - @Autowired - private AuthenticationHolderEntityService authenticationHolderService; - - private int authCodeExpirationSeconds = 60 * 5; // expire in 5 minutes by default - - private RandomValueStringGenerator generator = new RandomValueStringGenerator(22); - - /** - * Generate a random authorization code and create an AuthorizationCodeEntity, - * which will be stored in the repository. - * - * @param authentication the authentication of the current user, to be retrieved when the - * code is consumed - * @return the authorization code - */ - @Override - @Transactional(value="defaultTransactionManager") - public String createAuthorizationCode(OAuth2Authentication authentication) { - String code = generator.generate(); - - // attach the authorization so that we can look it up later - AuthenticationHolderEntity authHolder = authenticationHolderService.create(authentication); - - // set the auth code to expire - Date expiration = new Date(System.currentTimeMillis() + (getAuthCodeExpirationSeconds() * 1000L)); - - AuthorizationCodeEntity entity = new AuthorizationCodeEntity(code, authHolder, expiration); - repository.save(entity); - - return code; - } - - /** - * Consume a given authorization code. - * Match the provided string to an AuthorizationCodeEntity. If one is found, return - * the authentication associated with the code. If one is not found, throw an - * InvalidGrantException. - * - * @param code the authorization code - * @return the authentication that made the original request - * @throws InvalidGrantException, if an AuthorizationCodeEntity is not found with the given value - */ - @Override - public OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException { - - AuthorizationCodeEntity result = repository.getByCode(code); - - if (result == null) { - throw new InvalidGrantException("JpaAuthorizationCodeRepository: no authorization code found for value " + code); - } - - OAuth2Authentication auth = result.getAuthenticationHolder().getAuthentication(); - - repository.remove(result); - - return auth; - } - - /** - * Find and remove all expired auth codes. - */ - @Transactional(value="defaultTransactionManager") - public void clearExpiredAuthorizationCodes() { - - new AbstractPageOperationTemplate("clearExpiredAuthorizationCodes"){ - @Override - public Collection fetchPage() { - return repository.getExpiredCodes(); - } - - @Override - protected void doOperation(AuthorizationCodeEntity item) { - repository.remove(item); - } - }.execute(); - } - - /** - * @return the repository - */ - public AuthorizationCodeRepository getRepository() { - return repository; - } - - /** - * @param repository the repository to set - */ - public void setRepository(AuthorizationCodeRepository repository) { - this.repository = repository; - } - - /** - * @return the authCodeExpirationSeconds - */ - public int getAuthCodeExpirationSeconds() { - return authCodeExpirationSeconds; - } - - /** - * @param authCodeExpirationSeconds the authCodeExpirationSeconds to set - */ - public void setAuthCodeExpirationSeconds(int authCodeExpirationSeconds) { - this.authCodeExpirationSeconds = authCodeExpirationSeconds; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java deleted file mode 100644 index c7ec3ae181..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultOAuth2ClientDetailsEntityService.java +++ /dev/null @@ -1,510 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.service.impl; - -import java.math.BigInteger; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.apache.commons.codec.binary.Base64; -import org.apache.http.client.HttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.service.ApprovedSiteService; -import org.mitre.openid.connect.service.BlacklistedSiteService; -import org.mitre.openid.connect.service.StatsService; -import org.mitre.openid.connect.service.WhitelistedSiteService; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ResourceSetService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -import com.google.common.base.Strings; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.util.concurrent.UncheckedExecutionException; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - -@Service -@Transactional -public class DefaultOAuth2ClientDetailsEntityService implements ClientDetailsEntityService { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(DefaultOAuth2ClientDetailsEntityService.class); - - @Autowired - private OAuth2ClientRepository clientRepository; - - @Autowired - private OAuth2TokenRepository tokenRepository; - - @Autowired - private ApprovedSiteService approvedSiteService; - - @Autowired - private WhitelistedSiteService whitelistedSiteService; - - @Autowired - private BlacklistedSiteService blacklistedSiteService; - - @Autowired - private SystemScopeService scopeService; - - @Autowired - private StatsService statsService; - - @Autowired - private ResourceSetService resourceSetService; - - @Autowired - private ConfigurationPropertiesBean config; - - // map of sector URI -> list of redirect URIs - private LoadingCache> sectorRedirects = CacheBuilder.newBuilder() - .expireAfterAccess(1, TimeUnit.HOURS) - .maximumSize(100) - .build(new SectorIdentifierLoader(HttpClientBuilder.create().useSystemProperties().build())); - - @Override - public ClientDetailsEntity saveNewClient(ClientDetailsEntity client) { - if (client.getId() != null) { // if it's not null, it's already been saved, this is an error - throw new IllegalArgumentException("Tried to save a new client with an existing ID: " + client.getId()); - } - - if (client.getRegisteredRedirectUri() != null) { - for (String uri : client.getRegisteredRedirectUri()) { - if (blacklistedSiteService.isBlacklisted(uri)) { - throw new IllegalArgumentException("Client URI is blacklisted: " + uri); - } - } - } - - // assign a random clientid if it's empty - // NOTE: don't assign a random client secret without asking, since public clients have no secret - if (Strings.isNullOrEmpty(client.getClientId())) { - client = generateClientId(client); - } - - // make sure that clients with the "refresh_token" grant type have the "offline_access" scope, and vice versa - ensureRefreshTokenConsistency(client); - - // make sure we don't have both a JWKS and a JWKS URI - ensureKeyConsistency(client); - - // check consistency when using HEART mode - checkHeartMode(client); - - // timestamp this to right now - client.setCreatedAt(new Date()); - - - // check the sector URI - checkSectorIdentifierUri(client); - - - ensureNoReservedScopes(client); - - ClientDetailsEntity c = clientRepository.saveClient(client); - - statsService.resetCache(); - - return c; - } - - /** - * Make sure the client has only one type of key registered - * @param client - */ - private void ensureKeyConsistency(ClientDetailsEntity client) { - if (client.getJwksUri() != null && client.getJwks() != null) { - // a client can only have one key type or the other, not both - throw new IllegalArgumentException("A client cannot have both JWKS URI and JWKS value"); - } - } - - /** - * Make sure the client doesn't request any system reserved scopes - */ - private void ensureNoReservedScopes(ClientDetailsEntity client) { - // make sure a client doesn't get any special system scopes - Set requestedScope = scopeService.fromStrings(client.getScope()); - requestedScope = requestedScope.stream().filter(s -> !SystemScopeService.reservedValues.contains(s)).collect(Collectors.toSet()); - client.setScope(scopeService.toStrings(requestedScope)); - } - - /** - * Load the sector identifier URI if it exists and check the redirect URIs against it - * @param client - */ - private void checkSectorIdentifierUri(ClientDetailsEntity client) { - if (!Strings.isNullOrEmpty(client.getSectorIdentifierUri())) { - try { - List redirects = sectorRedirects.get(client.getSectorIdentifierUri()); - - if (client.getRegisteredRedirectUri() != null) { - for (String uri : client.getRegisteredRedirectUri()) { - if (!redirects.contains(uri)) { - throw new IllegalArgumentException("Requested Redirect URI " + uri + " is not listed at sector identifier " + redirects); - } - } - } - - } catch (UncheckedExecutionException | ExecutionException e) { - throw new IllegalArgumentException("Unable to load sector identifier URI " + client.getSectorIdentifierUri() + ": " + e.getMessage()); - } - } - } - - /** - * Make sure the client has the appropriate scope and grant type. - * @param client - */ - private void ensureRefreshTokenConsistency(ClientDetailsEntity client) { - if (client.getAuthorizedGrantTypes().contains("refresh_token") - || client.getScope().contains(SystemScopeService.OFFLINE_ACCESS)) { - client.getScope().add(SystemScopeService.OFFLINE_ACCESS); - client.getAuthorizedGrantTypes().add("refresh_token"); - } - } - - /** - * If HEART mode is enabled, make sure the client meets the requirements: - * - Only one of authorization_code, implicit, or client_credentials can be used at a time - * - A redirect_uri must be registered with either authorization_code or implicit - * - A key must be registered - * - A client secret must not be generated - * - authorization_code and client_credentials must use the private_key authorization method - * @param client - */ - private void checkHeartMode(ClientDetailsEntity client) { - if (config.isHeartMode()) { - if (client.getGrantTypes().contains("authorization_code")) { - // make sure we don't have incompatible grant types - if (client.getGrantTypes().contains("implicit") || client.getGrantTypes().contains("client_credentials")) { - throw new IllegalArgumentException("[HEART mode] Incompatible grant types"); - } - - // make sure we've got the right authentication method - if (client.getTokenEndpointAuthMethod() == null || !client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY)) { - throw new IllegalArgumentException("[HEART mode] Authorization code clients must use the private_key authentication method"); - } - - // make sure we've got a redirect URI - if (client.getRedirectUris().isEmpty()) { - throw new IllegalArgumentException("[HEART mode] Authorization code clients must register at least one redirect URI"); - } - } - - if (client.getGrantTypes().contains("implicit")) { - // make sure we don't have incompatible grant types - if (client.getGrantTypes().contains("authorization_code") || client.getGrantTypes().contains("client_credentials") || client.getGrantTypes().contains("refresh_token")) { - throw new IllegalArgumentException("[HEART mode] Incompatible grant types"); - } - - // make sure we've got the right authentication method - if (client.getTokenEndpointAuthMethod() == null || !client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE)) { - throw new IllegalArgumentException("[HEART mode] Implicit clients must use the none authentication method"); - } - - // make sure we've got a redirect URI - if (client.getRedirectUris().isEmpty()) { - throw new IllegalArgumentException("[HEART mode] Implicit clients must register at least one redirect URI"); - } - } - - if (client.getGrantTypes().contains("client_credentials")) { - // make sure we don't have incompatible grant types - if (client.getGrantTypes().contains("authorization_code") || client.getGrantTypes().contains("implicit") || client.getGrantTypes().contains("refresh_token")) { - throw new IllegalArgumentException("[HEART mode] Incompatible grant types"); - } - - // make sure we've got the right authentication method - if (client.getTokenEndpointAuthMethod() == null || !client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY)) { - throw new IllegalArgumentException("[HEART mode] Client credentials clients must use the private_key authentication method"); - } - - // make sure we've got a redirect URI - if (!client.getRedirectUris().isEmpty()) { - throw new IllegalArgumentException("[HEART mode] Client credentials clients must not register a redirect URI"); - } - - } - - if (client.getGrantTypes().contains("password")) { - throw new IllegalArgumentException("[HEART mode] Password grant type is forbidden"); - } - - // make sure we don't have a client secret - if (!Strings.isNullOrEmpty(client.getClientSecret())) { - throw new IllegalArgumentException("[HEART mode] Client secrets are not allowed"); - } - - // make sure we've got a key registered - if (client.getJwks() == null && Strings.isNullOrEmpty(client.getJwksUri())) { - throw new IllegalArgumentException("[HEART mode] All clients must have a key registered"); - } - - // make sure our redirect URIs each fit one of the allowed categories - if (client.getRedirectUris() != null && !client.getRedirectUris().isEmpty()) { - boolean localhost = false; - boolean remoteHttps = false; - boolean customScheme = false; - for (String uri : client.getRedirectUris()) { - UriComponents components = UriComponentsBuilder.fromUriString(uri).build(); - if (components.getScheme() == null) { - // this is a very unknown redirect URI - customScheme = true; - } else if (components.getScheme().equals("http")) { - // http scheme, check for localhost - if (components.getHost().equals("localhost") || components.getHost().equals("127.0.0.1")) { - localhost = true; - } else { - throw new IllegalArgumentException("[HEART mode] Can't have an http redirect URI on non-local host"); - } - } else if (components.getScheme().equals("https")) { - remoteHttps = true; - } else { - customScheme = true; - } - } - - // now we make sure the client has a URI in only one of each of the three categories - if (!((localhost ^ remoteHttps ^ customScheme) - && !(localhost && remoteHttps && customScheme))) { - throw new IllegalArgumentException("[HEART mode] Can't have more than one class of redirect URI"); - } - } - - } - } - - /** - * Get the client by its internal ID - */ - @Override - public ClientDetailsEntity getClientById(Long id) { - ClientDetailsEntity client = clientRepository.getById(id); - - return client; - } - - /** - * Get the client for the given ClientID - */ - @Override - public ClientDetailsEntity loadClientByClientId(String clientId) throws OAuth2Exception, InvalidClientException, IllegalArgumentException { - if (!Strings.isNullOrEmpty(clientId)) { - ClientDetailsEntity client = clientRepository.getClientByClientId(clientId); - if (client == null) { - throw new InvalidClientException("Client with id " + clientId + " was not found"); - } - else { - return client; - } - } - - throw new IllegalArgumentException("Client id must not be empty!"); - } - - /** - * Delete a client and all its associated tokens - */ - @Override - public void deleteClient(ClientDetailsEntity client) throws InvalidClientException { - - if (clientRepository.getById(client.getId()) == null) { - throw new InvalidClientException("Client with id " + client.getClientId() + " was not found"); - } - - // clean out any tokens that this client had issued - tokenRepository.clearTokensForClient(client); - - // clean out any approved sites for this client - approvedSiteService.clearApprovedSitesForClient(client); - - // clear out any whitelisted sites for this client - WhitelistedSite whitelistedSite = whitelistedSiteService.getByClientId(client.getClientId()); - if (whitelistedSite != null) { - whitelistedSiteService.remove(whitelistedSite); - } - - // clear out resource sets registered for this client - Collection resourceSets = resourceSetService.getAllForClient(client); - for (ResourceSet rs : resourceSets) { - resourceSetService.remove(rs); - } - - // take care of the client itself - clientRepository.deleteClient(client); - - statsService.resetCache(); - - } - - /** - * Update the oldClient with information from the newClient. The - * id from oldClient is retained. - * - * Checks to make sure the refresh grant type and - * the scopes are set appropriately. - * - * Checks to make sure the redirect URIs aren't blacklisted. - * - * Attempts to load the redirect URI (possibly cached) to check the - * sector identifier against the contents there. - * - * - */ - @Override - public ClientDetailsEntity updateClient(ClientDetailsEntity oldClient, ClientDetailsEntity newClient) throws IllegalArgumentException { - if (oldClient != null && newClient != null) { - - for (String uri : newClient.getRegisteredRedirectUri()) { - if (blacklistedSiteService.isBlacklisted(uri)) { - throw new IllegalArgumentException("Client URI is blacklisted: " + uri); - } - } - - // if the client is flagged to allow for refresh tokens, make sure it's got the right scope - ensureRefreshTokenConsistency(newClient); - - // make sure we don't have both a JWKS and a JWKS URI - ensureKeyConsistency(newClient); - - // check consistency when using HEART mode - checkHeartMode(newClient); - - // check the sector URI - checkSectorIdentifierUri(newClient); - - // make sure a client doesn't get any special system scopes - ensureNoReservedScopes(newClient); - - return clientRepository.updateClient(oldClient.getId(), newClient); - } - throw new IllegalArgumentException("Neither old client or new client can be null!"); - } - - /** - * Get all clients in the system - */ - @Override - public Collection getAllClients() { - return clientRepository.getAllClients(); - } - - /** - * Generates a clientId for the given client and sets it to the client's clientId field. Returns the client that was passed in, now with id set. - */ - @Override - public ClientDetailsEntity generateClientId(ClientDetailsEntity client) { - client.setClientId(UUID.randomUUID().toString()); - return client; - } - - /** - * Generates a new clientSecret for the given client and sets it to the client's clientSecret field. Returns the client that was passed in, now with secret set. - */ - @Override - public ClientDetailsEntity generateClientSecret(ClientDetailsEntity client) { - if (config.isHeartMode()) { - logger.error("[HEART mode] Can't generate a client secret, skipping step; client won't be saved due to invalid configuration"); - client.setClientSecret(null); - } else { - client.setClientSecret(Base64.encodeBase64URLSafeString(new BigInteger(512, new SecureRandom()).toByteArray()).replace("=", "")); - } - return client; - } - - /** - * Utility class to load a sector identifier's set of authorized redirect URIs. - * - * @author jricher - * - */ - private class SectorIdentifierLoader extends CacheLoader> { - private HttpComponentsClientHttpRequestFactory httpFactory; - private RestTemplate restTemplate; - private JsonParser parser = new JsonParser(); - - SectorIdentifierLoader(HttpClient httpClient) { - this.httpFactory = new HttpComponentsClientHttpRequestFactory(httpClient); - this.restTemplate = new RestTemplate(httpFactory); - } - - @Override - public List load(String key) throws Exception { - - if (!key.startsWith("https")) { - if (config.isForceHttps()) { - throw new IllegalArgumentException("Sector identifier must start with https: " + key); - } - logger.error("Sector identifier doesn't start with https, loading anyway..."); - } - - // key is the sector URI - String jsonString = restTemplate.getForObject(key, String.class); - JsonElement json = parser.parse(jsonString); - - if (json.isJsonArray()) { - List redirectUris = new ArrayList<>(); - for (JsonElement el : json.getAsJsonArray()) { - redirectUris.add(el.getAsString()); - } - - logger.info("Found " + redirectUris + " for sector " + key); - - return redirectUris; - } else { - throw new IllegalArgumentException("JSON Format Error"); - } - - } - - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java deleted file mode 100644 index c53596f26b..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/ChainedTokenGranter.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.token; - -import java.util.HashSet; -import java.util.Set; - -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.common.exceptions.InvalidScopeException; -import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2RequestFactory; -import org.springframework.security.oauth2.provider.TokenRequest; -import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; -import org.springframework.stereotype.Component; - -import com.google.common.collect.Sets; - -/** - * @author jricher - * - */ -@Component("chainedTokenGranter") -public class ChainedTokenGranter extends AbstractTokenGranter { - - public static final String GRANT_TYPE = "urn:ietf:params:oauth:grant_type:redelegate"; - - // keep down-cast versions so we can get to the right queries - private OAuth2TokenEntityService tokenServices; - - /** - * @param tokenServices - * @param clientDetailsService - * @param GRANT_TYPE - */ - @Autowired - public ChainedTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); - this.tokenServices = tokenServices; - } - - /* (non-Javadoc) - * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) - */ - @Override - protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { - // read and load up the existing token - String incomingTokenValue = tokenRequest.getRequestParameters().get("token"); - OAuth2AccessTokenEntity incomingToken = tokenServices.readAccessToken(incomingTokenValue); - - // check for scoping in the request, can't up-scope with a chained request - Set approvedScopes = incomingToken.getScope(); - Set requestedScopes = tokenRequest.getScope(); - - if (requestedScopes == null) { - requestedScopes = new HashSet<>(); - } - - // do a check on the requested scopes -- if they exactly match the client scopes, they were probably shadowed by the token granter - if (client.getScope().equals(requestedScopes)) { - requestedScopes = new HashSet<>(); - } - - // if our scopes are a valid subset of what's allowed, we can continue - if (approvedScopes.containsAll(requestedScopes)) { - - if (requestedScopes.isEmpty()) { - // if there are no scopes, inherit the original scopes from the token - tokenRequest.setScope(approvedScopes); - } else { - // if scopes were asked for, give only the subset of scopes requested - // this allows safe downscoping - tokenRequest.setScope(Sets.intersection(requestedScopes, approvedScopes)); - } - - // NOTE: don't revoke the existing access token - - // create a new access token - OAuth2Authentication authentication = new OAuth2Authentication(getRequestFactory().createOAuth2Request(client, tokenRequest), incomingToken.getAuthenticationHolder().getAuthentication().getUserAuthentication()); - - return authentication; - - } else { - throw new InvalidScopeException("Invalid scope requested in chained request", approvedScopes); - } - - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/JWTAssertionTokenGranter.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/JWTAssertionTokenGranter.java deleted file mode 100644 index 02217fc48e..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/JWTAssertionTokenGranter.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.token; - -import java.text.ParseException; - -import org.mitre.jwt.assertion.AssertionValidator; -import org.mitre.oauth2.assertion.AssertionOAuth2RequestFactory; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.openid.connect.assertion.JWTBearerAssertionAuthenticationToken; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2RequestFactory; -import org.springframework.security.oauth2.provider.TokenRequest; -import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; -import org.springframework.stereotype.Component; - -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTParser; - -/** - * @author jricher - * - */ -@Component("jwtAssertionTokenGranter") -public class JWTAssertionTokenGranter extends AbstractTokenGranter { - - private static final String grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"; - - @Autowired - @Qualifier("jwtAssertionValidator") - private AssertionValidator validator; - - @Autowired - private AssertionOAuth2RequestFactory assertionFactory; - - @Autowired - public JWTAssertionTokenGranter(OAuth2TokenEntityService tokenServices, ClientDetailsEntityService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, grantType); - } - - /* (non-Javadoc) - * @see org.springframework.security.oauth2.provider.token.AbstractTokenGranter#getOAuth2Authentication(org.springframework.security.oauth2.provider.AuthorizationRequest) - */ - @Override - protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) throws AuthenticationException, InvalidTokenException { - // read and load up the existing token - try { - String incomingAssertionValue = tokenRequest.getRequestParameters().get("assertion"); - JWT assertion = JWTParser.parse(incomingAssertionValue); - - if (validator.isValid(assertion)) { - - // our validator says it's OK, time to make a token from it - // the real work happens in the assertion factory and the token services - return new OAuth2Authentication(assertionFactory.createOAuth2Request(client, tokenRequest, assertion), - new JWTBearerAssertionAuthenticationToken(assertion, client.getAuthorities())); - - } else { - logger.warn("Incoming assertion did not pass validator, rejecting"); - return null; - } - - } catch (ParseException e) { - logger.warn("Unable to parse incoming assertion"); - } - - // if we had made a token, we'd have returned it by now, so return null here to close out with no created token - return null; - - } - - - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java deleted file mode 100644 index 7725a54030..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/IntrospectionEndpoint.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.web; - -import static org.mitre.oauth2.web.AuthenticationUtilities.ensureOAuthScope; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.IntrospectionResultAssembler; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.UserInfoService; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ResourceSetService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; - -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; - -@Controller -public class IntrospectionEndpoint { - - /** - * - */ - public static final String URL = "introspect"; - - @Autowired - private OAuth2TokenEntityService tokenServices; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private IntrospectionResultAssembler introspectionResultAssembler; - - @Autowired - private UserInfoService userInfoService; - - @Autowired - private ResourceSetService resourceSetService; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(IntrospectionEndpoint.class); - - public IntrospectionEndpoint() { - - } - - public IntrospectionEndpoint(OAuth2TokenEntityService tokenServices) { - this.tokenServices = tokenServices; - } - - @RequestMapping("/" + URL) - public String verify(@RequestParam("token") String tokenValue, - @RequestParam(value = "token_type_hint", required = false) String tokenType, - Authentication auth, Model model) { - - ClientDetailsEntity authClient = null; - Set authScopes = new HashSet<>(); - - if (auth instanceof OAuth2Authentication) { - // the client authenticated with OAuth, do our UMA checks - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - // get out the client that was issued the access token (not the token being introspected) - OAuth2Authentication o2a = (OAuth2Authentication) auth; - - String authClientId = o2a.getOAuth2Request().getClientId(); - authClient = clientService.loadClientByClientId(authClientId); - - // the owner is the user who authorized the token in the first place - String ownerId = o2a.getUserAuthentication().getName(); - - authScopes.addAll(authClient.getScope()); - - // UMA style clients also get a subset of scopes of all the resource sets they've registered - Collection resourceSets = resourceSetService.getAllForOwnerAndClient(ownerId, authClientId); - - // collect all the scopes - for (ResourceSet rs : resourceSets) { - authScopes.addAll(rs.getScopes()); - } - - } else { - // the client authenticated directly, make sure it's got the right access - - String authClientId = auth.getName(); // direct authentication puts the client_id into the authentication's name field - authClient = clientService.loadClientByClientId(authClientId); - - // directly authenticated clients get a subset of any scopes that they've registered for - authScopes.addAll(authClient.getScope()); - - if (!AuthenticationUtilities.hasRole(auth, "ROLE_CLIENT") - || !authClient.isAllowIntrospection()) { - - // this client isn't allowed to do direct introspection - - logger.error("Client " + authClient.getClientId() + " is not allowed to call introspection endpoint"); - model.addAttribute("code", HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - - } - - } - - // by here we're allowed to introspect, now we need to look up the token in our token stores - - // first make sure the token is there - if (Strings.isNullOrEmpty(tokenValue)) { - logger.error("Verify failed; token value is null"); - Map entity = ImmutableMap.of("active", Boolean.FALSE); - model.addAttribute(JsonEntityView.ENTITY, entity); - return JsonEntityView.VIEWNAME; - } - - OAuth2AccessTokenEntity accessToken = null; - OAuth2RefreshTokenEntity refreshToken = null; - ClientDetailsEntity tokenClient; - UserInfo user; - - try { - - // check access tokens first (includes ID tokens) - accessToken = tokenServices.readAccessToken(tokenValue); - - tokenClient = accessToken.getClient(); - - // get the user information of the user that authorized this token in the first place - String userName = accessToken.getAuthenticationHolder().getAuthentication().getName(); - user = userInfoService.getByUsernameAndClientId(userName, tokenClient.getClientId()); - - } catch (InvalidTokenException e) { - logger.info("Invalid access token. Checking refresh token."); - try { - - // check refresh tokens next - refreshToken = tokenServices.getRefreshToken(tokenValue); - - tokenClient = refreshToken.getClient(); - - // get the user information of the user that authorized this token in the first place - String userName = refreshToken.getAuthenticationHolder().getAuthentication().getName(); - user = userInfoService.getByUsernameAndClientId(userName, tokenClient.getClientId()); - - } catch (InvalidTokenException e2) { - logger.error("Invalid refresh token"); - Map entity = ImmutableMap.of(IntrospectionResultAssembler.ACTIVE, Boolean.FALSE); - model.addAttribute(JsonEntityView.ENTITY, entity); - return JsonEntityView.VIEWNAME; - } - } - - // if it's a valid token, we'll print out information on it - - if (accessToken != null) { - Map entity = introspectionResultAssembler.assembleFrom(accessToken, user, authScopes); - model.addAttribute(JsonEntityView.ENTITY, entity); - } else if (refreshToken != null) { - Map entity = introspectionResultAssembler.assembleFrom(refreshToken, user, authScopes); - model.addAttribute(JsonEntityView.ENTITY, entity); - } else { - // no tokens were found (we shouldn't get here) - logger.error("Verify failed; Invalid access/refresh token"); - Map entity = ImmutableMap.of(IntrospectionResultAssembler.ACTIVE, Boolean.FALSE); - model.addAttribute(JsonEntityView.ENTITY, entity); - return JsonEntityView.VIEWNAME; - } - - return JsonEntityView.VIEWNAME; - - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java deleted file mode 100644 index 29c9a1419e..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/OAuthConfirmationController.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.web; - -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_SEPARATOR; - -import java.net.URISyntaxException; -import java.security.Principal; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.http.client.utils.URIBuilder; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.ScopeClaimTranslationService; -import org.mitre.openid.connect.service.StatsService; -import org.mitre.openid.connect.service.UserInfoService; -import org.mitre.openid.connect.view.HttpCodeView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; -import org.springframework.security.oauth2.provider.AuthorizationRequest; -import org.springframework.security.oauth2.provider.endpoint.RedirectResolver; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.SessionAttributes; - -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Sets; -import com.google.gson.JsonObject; - -/** - * @author jricher - * - */ -@Controller -@SessionAttributes("authorizationRequest") -public class OAuthConfirmationController { - - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private SystemScopeService scopeService; - - @Autowired - private ScopeClaimTranslationService scopeClaimTranslationService; - - @Autowired - private UserInfoService userInfoService; - - @Autowired - private StatsService statsService; - - @Autowired - private RedirectResolver redirectResolver; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(OAuthConfirmationController.class); - - public OAuthConfirmationController() { - - } - - public OAuthConfirmationController(ClientDetailsEntityService clientService) { - this.clientService = clientService; - } - - @PreAuthorize("hasRole('ROLE_USER')") - @RequestMapping("/oauth/confirm_access") - public String confirmAccess(Map model, Principal p) { - - AuthorizationRequest authRequest = (AuthorizationRequest) model.get("authorizationRequest"); - // Check the "prompt" parameter to see if we need to do special processing - - String prompt = (String)authRequest.getExtensions().get(PROMPT); - List prompts = Splitter.on(PROMPT_SEPARATOR).splitToList(Strings.nullToEmpty(prompt)); - ClientDetailsEntity client = null; - - try { - client = clientService.loadClientByClientId(authRequest.getClientId()); - } catch (OAuth2Exception e) { - logger.error("confirmAccess: OAuth2Exception was thrown when attempting to load client", e); - model.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - return HttpCodeView.VIEWNAME; - } catch (IllegalArgumentException e) { - logger.error("confirmAccess: IllegalArgumentException was thrown when attempting to load client", e); - model.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - return HttpCodeView.VIEWNAME; - } - - if (client == null) { - logger.error("confirmAccess: could not find client " + authRequest.getClientId()); - model.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (prompts.contains("none")) { - // if we've got a redirect URI then we'll send it - - String url = redirectResolver.resolveRedirect(authRequest.getRedirectUri(), client); - - try { - URIBuilder uriBuilder = new URIBuilder(url); - - uriBuilder.addParameter("error", "interaction_required"); - if (!Strings.isNullOrEmpty(authRequest.getState())) { - uriBuilder.addParameter("state", authRequest.getState()); // copy the state parameter if one was given - } - - return "redirect:" + uriBuilder.toString(); - - } catch (URISyntaxException e) { - logger.error("Can't build redirect URI for prompt=none, sending error instead", e); - model.put("code", HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - } - - model.put("auth_request", authRequest); - model.put("client", client); - - String redirect_uri = authRequest.getRedirectUri(); - - model.put("redirect_uri", redirect_uri); - - - // pre-process the scopes - Set scopes = scopeService.fromStrings(authRequest.getScope()); - - Set sortedScopes = new LinkedHashSet<>(scopes.size()); - Set systemScopes = scopeService.getAll(); - - // sort scopes for display based on the inherent order of system scopes - for (SystemScope s : systemScopes) { - if (scopes.contains(s)) { - sortedScopes.add(s); - } - } - - // add in any scopes that aren't system scopes to the end of the list - sortedScopes.addAll(Sets.difference(scopes, systemScopes)); - - model.put("scopes", sortedScopes); - - // get the userinfo claims for each scope - UserInfo user = userInfoService.getByUsername(p.getName()); - Map> claimsForScopes = new HashMap<>(); - if (user != null) { - JsonObject userJson = user.toJson(); - - for (SystemScope systemScope : sortedScopes) { - Map claimValues = new HashMap<>(); - - Set claims = scopeClaimTranslationService.getClaimsForScope(systemScope.getValue()); - for (String claim : claims) { - if (userJson.has(claim) && userJson.get(claim).isJsonPrimitive()) { - // TODO: this skips the address claim - claimValues.put(claim, userJson.get(claim).getAsString()); - } - } - - claimsForScopes.put(systemScope.getValue(), claimValues); - } - } - - model.put("claims", claimsForScopes); - - // client stats - Integer count = statsService.getCountForClientId(client.getClientId()).getApprovedSiteCount(); - model.put("count", count); - - - // contacts - if (client.getContacts() != null) { - String contacts = Joiner.on(", ").join(client.getContacts()); - model.put("contacts", contacts); - } - - // if the client is over a week old and has more than one registration, don't give such a big warning - // instead, tag as "Generally Recognized As Safe" (gras) - Date lastWeek = new Date(System.currentTimeMillis() - (60 * 60 * 24 * 7 * 1000)); - if (count > 1 && client.getCreatedAt() != null && client.getCreatedAt().before(lastWeek)) { - model.put("gras", true); - } else { - model.put("gras", false); - } - - return "approve"; - } - - /** - * @return the clientService - */ - public ClientDetailsEntityService getClientService() { - return clientService; - } - - /** - * @param clientService the clientService to set - */ - public void setClientService(ClientDetailsEntityService clientService) { - this.clientService = clientService; - } - - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java deleted file mode 100644 index dd202fe9f7..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/RevocationEndpoint.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.web; - -import static org.mitre.oauth2.web.AuthenticationUtilities.ensureOAuthScope; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.view.HttpCodeView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; - -@Controller -public class RevocationEndpoint { - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private OAuth2TokenEntityService tokenServices; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(RevocationEndpoint.class); - - public static final String URL = "revoke"; - - @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") - @RequestMapping("/" + URL) - public String revoke(@RequestParam("token") String tokenValue, @RequestParam(value = "token_type_hint", required = false) String tokenType, Authentication auth, Model model) { - - // This is the token as passed in from OAuth (in case we need it some day) - //OAuth2AccessTokenEntity tok = tokenServices.getAccessToken((OAuth2Authentication) principal); - - ClientDetailsEntity authClient = null; - - if (auth instanceof OAuth2Authentication) { - // the client authenticated with OAuth, do our UMA checks - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - // get out the client that was issued the access token (not the token being revoked) - OAuth2Authentication o2a = (OAuth2Authentication) auth; - - String authClientId = o2a.getOAuth2Request().getClientId(); - authClient = clientService.loadClientByClientId(authClientId); - - // the owner is the user who authorized the token in the first place - String ownerId = o2a.getUserAuthentication().getName(); - - } else { - // the client authenticated directly, make sure it's got the right access - - String authClientId = auth.getName(); // direct authentication puts the client_id into the authentication's name field - authClient = clientService.loadClientByClientId(authClientId); - - } - - try { - // check and handle access tokens first - - OAuth2AccessTokenEntity accessToken = tokenServices.readAccessToken(tokenValue); - - // client acting on its own, make sure it owns the token - if (!accessToken.getClient().getClientId().equals(authClient.getClientId())) { - // trying to revoke a token we don't own, throw a 403 - - logger.info("Client " + authClient.getClientId() + " tried to revoke a token owned by " + accessToken.getClient().getClientId()); - - model.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - // if we got this far, we're allowed to do this - tokenServices.revokeAccessToken(accessToken); - - logger.debug("Client " + authClient.getClientId() + " revoked access token " + tokenValue); - - model.addAttribute(HttpCodeView.CODE, HttpStatus.OK); - return HttpCodeView.VIEWNAME; - - } catch (InvalidTokenException e) { - - // access token wasn't found, check the refresh token - - try { - OAuth2RefreshTokenEntity refreshToken = tokenServices.getRefreshToken(tokenValue); - // client acting on its own, make sure it owns the token - if (!refreshToken.getClient().getClientId().equals(authClient.getClientId())) { - // trying to revoke a token we don't own, throw a 403 - - logger.info("Client " + authClient.getClientId() + " tried to revoke a token owned by " + refreshToken.getClient().getClientId()); - - model.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - // if we got this far, we're allowed to do this - tokenServices.revokeRefreshToken(refreshToken); - - logger.debug("Client " + authClient.getClientId() + " revoked access token " + tokenValue); - - model.addAttribute(HttpCodeView.CODE, HttpStatus.OK); - return HttpCodeView.VIEWNAME; - - } catch (InvalidTokenException e1) { - - // neither token type was found, simply say "OK" and be on our way. - - logger.debug("Failed to revoke token " + tokenValue); - - model.addAttribute(HttpCodeView.CODE, HttpStatus.OK); - return HttpCodeView.VIEWNAME; - } - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java deleted file mode 100644 index 73fa472b47..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java +++ /dev/null @@ -1,246 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.web; - -import java.security.Principal; -import java.util.List; -import java.util.Set; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.oauth2.view.TokenApiView; -import org.mitre.openid.connect.service.OIDCTokenService; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.mitre.openid.connect.web.RootController; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * REST-ish API for managing access tokens (GET/DELETE only) - * @author Amanda Anganes - * - */ -@Controller -@RequestMapping("/" + TokenAPI.URL) -@PreAuthorize("hasRole('ROLE_USER')") -public class TokenAPI { - - public static final String URL = RootController.API_URL + "/tokens"; - - @Autowired - private OAuth2TokenEntityService tokenService; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private OIDCTokenService oidcTokenService; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(TokenAPI.class); - - @RequestMapping(value = "/access", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String getAllAccessTokens(ModelMap m, Principal p) { - - Set allTokens = tokenService.getAllAccessTokensForUser(p.getName()); - m.put(JsonEntityView.ENTITY, allTokens); - return TokenApiView.VIEWNAME; - } - - @RequestMapping(value = "/access/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String getAccessTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) { - - OAuth2AccessTokenEntity token = tokenService.getAccessTokenById(id); - - if (token == null) { - logger.error("getToken failed; token not found: " + id); - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found."); - return JsonErrorView.VIEWNAME; - } else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) { - logger.error("getToken failed; token does not belong to principal " + p.getName()); - m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token"); - return JsonErrorView.VIEWNAME; - } else { - m.put(JsonEntityView.ENTITY, token); - return TokenApiView.VIEWNAME; - } - } - - @RequestMapping(value = "/access/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE) - public String deleteAccessTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) { - - OAuth2AccessTokenEntity token = tokenService.getAccessTokenById(id); - - if (token == null) { - logger.error("getToken failed; token not found: " + id); - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found."); - return JsonErrorView.VIEWNAME; - } else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) { - logger.error("getToken failed; token does not belong to principal " + p.getName()); - m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token"); - return JsonErrorView.VIEWNAME; - } else { - tokenService.revokeAccessToken(token); - - return HttpCodeView.VIEWNAME; - } - } - - @PreAuthorize("hasRole('ROLE_ADMIN')") - @RequestMapping(value = "/client/{clientId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String getAccessTokensByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) { - - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - if (client != null) { - List tokens = tokenService.getAccessTokensForClient(client); - m.put(JsonEntityView.ENTITY, tokens); - return TokenApiView.VIEWNAME; - } else { - // client not found - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + clientId + " could not be found."); - return JsonErrorView.VIEWNAME; - } - - } - - @PreAuthorize("hasRole('ROLE_ADMIN')") - @RequestMapping(value = "/registration/{clientId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String getRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) { - - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - if (client != null) { - OAuth2AccessTokenEntity token = tokenService.getRegistrationAccessTokenForClient(client); - if (token != null) { - m.put(JsonEntityView.ENTITY, token); - return TokenApiView.VIEWNAME; - } else { - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "No registration token could be found."); - return JsonErrorView.VIEWNAME; - } - } else { - // client not found - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + clientId + " could not be found."); - return JsonErrorView.VIEWNAME; - } - - } - - @PreAuthorize("hasRole('ROLE_ADMIN')") - @RequestMapping(value = "/registration/{clientId}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) - public String rotateRegistrationTokenByClientId(@PathVariable("clientId") String clientId, ModelMap m, Principal p) { - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - if (client != null) { - OAuth2AccessTokenEntity token = oidcTokenService.rotateRegistrationAccessTokenForClient(client); - token = tokenService.saveAccessToken(token); - - if (token != null) { - m.put(JsonEntityView.ENTITY, token); - return TokenApiView.VIEWNAME; - } else { - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "No registration token could be found."); - return JsonErrorView.VIEWNAME; - } - } else { - // client not found - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested client with id " + clientId + " could not be found."); - return JsonErrorView.VIEWNAME; - } - - } - - @RequestMapping(value = "/refresh", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String getAllRefreshTokens(ModelMap m, Principal p) { - - Set allTokens = tokenService.getAllRefreshTokensForUser(p.getName()); - m.put(JsonEntityView.ENTITY, allTokens); - return TokenApiView.VIEWNAME; - - - } - - @RequestMapping(value = "/refresh/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String getRefreshTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) { - - OAuth2RefreshTokenEntity token = tokenService.getRefreshTokenById(id); - - if (token == null) { - logger.error("refresh token not found: " + id); - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found."); - return JsonErrorView.VIEWNAME; - } else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) { - logger.error("refresh token " + id + " does not belong to principal " + p.getName()); - m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token"); - return JsonErrorView.VIEWNAME; - } else { - m.put(JsonEntityView.ENTITY, token); - return TokenApiView.VIEWNAME; - } - } - - @RequestMapping(value = "/refresh/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE) - public String deleteRefreshTokenById(@PathVariable("id") Long id, ModelMap m, Principal p) { - - OAuth2RefreshTokenEntity token = tokenService.getRefreshTokenById(id); - - if (token == null) { - logger.error("refresh token not found: " + id); - m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.put(JsonErrorView.ERROR_MESSAGE, "The requested token with id " + id + " could not be found."); - return JsonErrorView.VIEWNAME; - } else if (!token.getAuthenticationHolder().getAuthentication().getName().equals(p.getName())) { - logger.error("refresh token " + id + " does not belong to principal " + p.getName()); - m.put(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - m.put(JsonErrorView.ERROR_MESSAGE, "You do not have permission to view this token"); - return JsonErrorView.VIEWNAME; - } else { - tokenService.revokeRefreshToken(token); - - return HttpCodeView.VIEWNAME; - } - } -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerAssertionAuthenticationToken.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerAssertionAuthenticationToken.java deleted file mode 100644 index bc4f9abcde..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerAssertionAuthenticationToken.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.assertion; - -import java.text.ParseException; -import java.util.Collection; - -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.GrantedAuthority; - -import com.nimbusds.jwt.JWT; - -/** - * @author jricher - * - */ -public class JWTBearerAssertionAuthenticationToken extends AbstractAuthenticationToken { - - /** - * - */ - private static final long serialVersionUID = -3138213539914074617L; - private String subject; - private JWT jwt; - - /** - * Create an unauthenticated token with the given subject and jwt - * @param subject - * @param jwt - */ - public JWTBearerAssertionAuthenticationToken(JWT jwt) { - super(null); - try { - // save the subject of the JWT in case the credentials get erased later - this.subject = jwt.getJWTClaimsSet().getSubject(); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.jwt = jwt; - setAuthenticated(false); - } - - /** - * Create an authenticated token with the given clientID, jwt, and authorities set - * @param subject - * @param jwt - * @param authorities - */ - public JWTBearerAssertionAuthenticationToken(JWT jwt, Collection authorities) { - super(authorities); - try { - // save the subject of the JWT in case the credentials get erased later - this.subject = jwt.getJWTClaimsSet().getSubject(); - } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.jwt = jwt; - setAuthenticated(true); - } - - /* (non-Javadoc) - * @see org.springframework.security.core.Authentication#getCredentials() - */ - @Override - public Object getCredentials() { - return jwt; - } - - /* (non-Javadoc) - * @see org.springframework.security.core.Authentication#getPrincipal() - */ - @Override - public Object getPrincipal() { - return subject; - } - - /** - * @return the jwt - */ - public JWT getJwt() { - return jwt; - } - - /** - * @param jwt the jwt to set - */ - public void setJwt(JWT jwt) { - this.jwt = jwt; - } - - /** - * Clear out the JWT that this token holds. - */ - @Override - public void eraseCredentials() { - super.eraseCredentials(); - setJwt(null); - } - - - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerAuthenticationProvider.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerAuthenticationProvider.java deleted file mode 100644 index 749a8edddc..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerAuthenticationProvider.java +++ /dev/null @@ -1,218 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.assertion; - -import java.text.ParseException; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.jwt.signer.service.impl.ClientKeyCacheService; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; - -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; - -/** - * @author jricher - * - */ -public class JWTBearerAuthenticationProvider implements AuthenticationProvider { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(JWTBearerAuthenticationProvider.class); - - private static final GrantedAuthority ROLE_CLIENT = new SimpleGrantedAuthority("ROLE_CLIENT"); - - // map of verifiers, load keys for clients - @Autowired - private ClientKeyCacheService validators; - - // Allow for time sync issues by having a window of X seconds. - private int timeSkewAllowance = 300; - - // to load clients - @Autowired - private ClientDetailsEntityService clientService; - - // to get our server's issuer url - @Autowired - private ConfigurationPropertiesBean config; - - /** - * Try to validate the client credentials by parsing and validating the JWT. - */ - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - - JWTBearerAssertionAuthenticationToken jwtAuth = (JWTBearerAssertionAuthenticationToken)authentication; - - - try { - ClientDetailsEntity client = clientService.loadClientByClientId(jwtAuth.getName()); - - JWT jwt = jwtAuth.getJwt(); - JWTClaimsSet jwtClaims = jwt.getJWTClaimsSet(); - - if (!(jwt instanceof SignedJWT)) { - throw new AuthenticationServiceException("Unsupported JWT type: " + jwt.getClass().getName()); - } - - // check the signature with nimbus - SignedJWT jws = (SignedJWT) jwt; - - JWSAlgorithm alg = jws.getHeader().getAlgorithm(); - - if (client.getTokenEndpointAuthSigningAlg() != null && - !client.getTokenEndpointAuthSigningAlg().equals(alg)) { - throw new AuthenticationServiceException("Client's registered token endpoint signing algorithm (" + client.getTokenEndpointAuthSigningAlg() - + ") does not match token's actual algorithm (" + alg.getName() + ")"); - } - - if (client.getTokenEndpointAuthMethod() == null || - client.getTokenEndpointAuthMethod().equals(AuthMethod.NONE) || - client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_BASIC) || - client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_POST)) { - - // this client doesn't support this type of authentication - throw new AuthenticationServiceException("Client does not support this authentication method."); - - } else if ((client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY) && - (alg.equals(JWSAlgorithm.RS256) - || alg.equals(JWSAlgorithm.RS384) - || alg.equals(JWSAlgorithm.RS512) - || alg.equals(JWSAlgorithm.ES256) - || alg.equals(JWSAlgorithm.ES384) - || alg.equals(JWSAlgorithm.ES512) - || alg.equals(JWSAlgorithm.PS256) - || alg.equals(JWSAlgorithm.PS384) - || alg.equals(JWSAlgorithm.PS512))) - || (client.getTokenEndpointAuthMethod().equals(AuthMethod.SECRET_JWT) && - (alg.equals(JWSAlgorithm.HS256) - || alg.equals(JWSAlgorithm.HS384) - || alg.equals(JWSAlgorithm.HS512)))) { - - // double-check the method is asymmetrical if we're in HEART mode - if (config.isHeartMode() && !client.getTokenEndpointAuthMethod().equals(AuthMethod.PRIVATE_KEY)) { - throw new AuthenticationServiceException("[HEART mode] Invalid authentication method"); - } - - JWTSigningAndValidationService validator = validators.getValidator(client, alg); - - if (validator == null) { - throw new AuthenticationServiceException("Unable to create signature validator for client " + client + " and algorithm " + alg); - } - - if (!validator.validateSignature(jws)) { - throw new AuthenticationServiceException("Signature did not validate for presented JWT authentication."); - } - } else { - throw new AuthenticationServiceException("Unable to create signature validator for method " + client.getTokenEndpointAuthMethod() + " and algorithm " + alg); - } - - // check the issuer - if (jwtClaims.getIssuer() == null) { - throw new AuthenticationServiceException("Assertion Token Issuer is null"); - } else if (!jwtClaims.getIssuer().equals(client.getClientId())){ - throw new AuthenticationServiceException("Issuers do not match, expected " + client.getClientId() + " got " + jwtClaims.getIssuer()); - } - - // check expiration - if (jwtClaims.getExpirationTime() == null) { - throw new AuthenticationServiceException("Assertion Token does not have required expiration claim"); - } else { - // it's not null, see if it's expired - Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000)); - if (now.after(jwtClaims.getExpirationTime())) { - throw new AuthenticationServiceException("Assertion Token is expired: " + jwtClaims.getExpirationTime()); - } - } - - // check not before - if (jwtClaims.getNotBeforeTime() != null) { - Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); - if (now.before(jwtClaims.getNotBeforeTime())){ - throw new AuthenticationServiceException("Assertion Token not valid untill: " + jwtClaims.getNotBeforeTime()); - } - } - - // check issued at - if (jwtClaims.getIssueTime() != null) { - // since it's not null, see if it was issued in the future - Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000)); - if (now.before(jwtClaims.getIssueTime())) { - throw new AuthenticationServiceException("Assertion Token was issued in the future: " + jwtClaims.getIssueTime()); - } - } - - // check audience - if (jwtClaims.getAudience() == null) { - throw new AuthenticationServiceException("Assertion token audience is null"); - } else if (!(jwtClaims.getAudience().contains(config.getIssuer()) || jwtClaims.getAudience().contains(config.getIssuer() + "token"))) { - throw new AuthenticationServiceException("Audience does not match, expected " + config.getIssuer() + " or " + (config.getIssuer() + "token") + " got " + jwtClaims.getAudience()); - } - - // IFF we managed to get all the way down here, the token is valid - - // add in the ROLE_CLIENT authority - Set authorities = new HashSet<>(client.getAuthorities()); - authorities.add(ROLE_CLIENT); - - return new JWTBearerAssertionAuthenticationToken(jwt, authorities); - - } catch (InvalidClientException e) { - throw new UsernameNotFoundException("Could not find client: " + jwtAuth.getName()); - } catch (ParseException e) { - - logger.error("Failure during authentication, error was: ", e); - - throw new AuthenticationServiceException("Invalid JWT format"); - } - } - - /** - * We support {@link JWTBearerAssertionAuthenticationToken}s only. - */ - @Override - public boolean supports(Class authentication) { - return (JWTBearerAssertionAuthenticationToken.class.isAssignableFrom(authentication)); - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerClientAssertionTokenEndpointFilter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerClientAssertionTokenEndpointFilter.java deleted file mode 100644 index e1e5ca9060..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/assertion/JWTBearerClientAssertionTokenEndpointFilter.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.assertion; - -import java.io.IOException; -import java.text.ParseException; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.oauth2.common.exceptions.BadClientCredentialsException; -import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.util.matcher.RequestMatcher; - -import com.google.common.base.Strings; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTParser; - -/** - * Filter to check client authentication via JWT Bearer assertions. - * - * @author jricher - * - */ -public class JWTBearerClientAssertionTokenEndpointFilter extends AbstractAuthenticationProcessingFilter { - - private AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); - - public JWTBearerClientAssertionTokenEndpointFilter(RequestMatcher additionalMatcher) { - super(new ClientAssertionRequestMatcher(additionalMatcher)); - // If authentication fails the type is "Form" - ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).setTypeName("Form"); - } - - @Override - public void afterPropertiesSet() { - super.afterPropertiesSet(); - setAuthenticationFailureHandler(new AuthenticationFailureHandler() { - @Override - public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, - AuthenticationException exception) throws IOException, ServletException { - if (exception instanceof BadCredentialsException) { - exception = new BadCredentialsException(exception.getMessage(), new BadClientCredentialsException()); - } - authenticationEntryPoint.commence(request, response, exception); - } - }); - setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() { - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) throws IOException, ServletException { - // no-op - just allow filter chain to continue to token endpoint - } - }); - } - - /** - * Pull the assertion out of the request and send it up to the auth manager for processing. - */ - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { - - // check for appropriate parameters - String assertionType = request.getParameter("client_assertion_type"); - String assertion = request.getParameter("client_assertion"); - - try { - JWT jwt = JWTParser.parse(assertion); - - String clientId = jwt.getJWTClaimsSet().getSubject(); - - Authentication authRequest = new JWTBearerAssertionAuthenticationToken(jwt); - - return this.getAuthenticationManager().authenticate(authRequest); - } catch (ParseException e) { - throw new BadCredentialsException("Invalid JWT credential: " + assertion); - } - } - - @Override - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, - FilterChain chain, Authentication authResult) throws IOException, ServletException { - super.successfulAuthentication(request, response, chain, authResult); - chain.doFilter(request, response); - } - - private static class ClientAssertionRequestMatcher implements RequestMatcher { - - private RequestMatcher additionalMatcher; - - public ClientAssertionRequestMatcher(RequestMatcher additionalMatcher) { - this.additionalMatcher = additionalMatcher; - } - - @Override - public boolean matches(HttpServletRequest request) { - // check for appropriate parameters - String assertionType = request.getParameter("client_assertion_type"); - String assertion = request.getParameter("client_assertion"); - - if (Strings.isNullOrEmpty(assertionType) || Strings.isNullOrEmpty(assertion)) { - return false; - } else if (!assertionType.equals("urn:ietf:params:oauth:client-assertion-type:jwt-bearer")) { - return false; - } - - return additionalMatcher.matches(request); - } - - } - - - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java deleted file mode 100644 index 31755cc673..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/filter/AuthorizationRequestFilter.java +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.filter; - -import static org.mitre.openid.connect.request.ConnectRequestParameters.CLIENT_ID; -import static org.mitre.openid.connect.request.ConnectRequestParameters.ERROR; -import static org.mitre.openid.connect.request.ConnectRequestParameters.LOGIN_HINT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.LOGIN_REQUIRED; -import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_LOGIN; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_NONE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_SEPARATOR; -import static org.mitre.openid.connect.request.ConnectRequestParameters.REDIRECT_URI; -import static org.mitre.openid.connect.request.ConnectRequestParameters.STATE; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.http.client.utils.URIBuilder; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.service.LoginHintExtracter; -import org.mitre.openid.connect.service.impl.RemoveLoginHintsWithHTTP; -import org.mitre.openid.connect.web.AuthenticationTimeStamper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.provider.endpoint.RedirectResolver; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.GenericFilterBean; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; - -/** - * @author jricher - * - */ -@Component("authRequestFilter") -public class AuthorizationRequestFilter extends GenericFilterBean { - - private static final Logger logger = LoggerFactory.getLogger(AuthorizationRequestFilter.class); - - public final static String PROMPTED = "PROMPT_FILTER_PROMPTED"; - public final static String PROMPT_REQUESTED = "PROMPT_FILTER_REQUESTED"; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private RedirectResolver redirectResolver; - - @Autowired(required = false) - private LoginHintExtracter loginHintExtracter = new RemoveLoginHintsWithHTTP(); - - private RequestMatcher requestMatcher = new AntPathRequestMatcher("/authorize"); - - @Override - public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) - throws IOException, ServletException { - - HttpServletRequest request = (HttpServletRequest) req; - HttpServletResponse response = (HttpServletResponse) res; - HttpSession session = request.getSession(); - - // skip everything that's not an authorize URL - if (!requestMatcher.matches(request)) { - chain.doFilter(req, res); - return; - } - - Map params = createRequestMap(request.getParameterMap()); - - ClientDetailsEntity client = null; - - if (params.get(CLIENT_ID) != null) { - client = clientService.loadClientByClientId(params.get(CLIENT_ID)); - } - - // save the login hint to the session - // but first check to see if the login hint makes any sense - String loginHint = loginHintExtracter.extractHint(params.get(LOGIN_HINT)); - if (!Strings.isNullOrEmpty(loginHint)) { - session.setAttribute(LOGIN_HINT, loginHint); - } else { - session.removeAttribute(LOGIN_HINT); - } - - if (params.get(PROMPT) != null) { - // we have a "prompt" parameter - String prompt = params.get(PROMPT); - List prompts = Splitter.on(PROMPT_SEPARATOR).splitToList(Strings.nullToEmpty(prompt)); - - if (prompts.contains(PROMPT_NONE)) { - // see if the user's logged in - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - - if (auth != null) { - // user's been logged in already (by session management) - // we're OK, continue without prompting - chain.doFilter(req, res); - } else { - logger.info("Client requested no prompt"); - // user hasn't been logged in, we need to "return an error" - if (client != null && params.get(REDIRECT_URI) != null) { - - // if we've got a redirect URI then we'll send it - String url = redirectResolver.resolveRedirect(params.get(REDIRECT_URI), client); - - try { - URIBuilder uriBuilder = new URIBuilder(url); - - uriBuilder.addParameter(ERROR, LOGIN_REQUIRED); - if (!Strings.isNullOrEmpty(params.get(STATE))) { - uriBuilder.addParameter(STATE, params.get(STATE)); - } - - response.sendRedirect(uriBuilder.toString()); - return; - - } catch (URISyntaxException e) { - logger.error("Can't build redirect URI for prompt=none, sending error instead", e); - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); - return; - } - } - - response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); - return; - } - } else if (prompts.contains(PROMPT_LOGIN)) { - - // first see if the user's already been prompted in this session - if (session.getAttribute(PROMPTED) == null) { - // user hasn't been PROMPTED yet, we need to check - - session.setAttribute(PROMPT_REQUESTED, Boolean.TRUE); - - // see if the user's logged in - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth != null) { - // user's been logged in already (by session management) - // log them out and continue - SecurityContextHolder.getContext().setAuthentication(null); - chain.doFilter(req, res); - } else { - // user hasn't been logged in yet, we can keep going since we'll get there - chain.doFilter(req, res); - } - } else { - // user has been PROMPTED, we're fine - - // but first, undo the prompt tag - session.removeAttribute(PROMPTED); - chain.doFilter(req, res); - } - } else { - // prompt parameter is a value we don't care about, not our business - chain.doFilter(req, res); - } - - } else if (params.get(MAX_AGE) != null - || (client != null && client.getDefaultMaxAge() != null)) { - - // default to the client's stored value, check the string parameter - Integer max = (client != null ? client.getDefaultMaxAge() : null); - String maxAge = params.get(MAX_AGE); - if (maxAge != null) { - max = Integer.parseInt(maxAge); - } - - if (max != null) { - - Date authTime = (Date) session.getAttribute(AuthenticationTimeStamper.AUTH_TIMESTAMP); - - Date now = new Date(); - if (authTime != null) { - long seconds = (now.getTime() - authTime.getTime()) / 1000; - if (seconds > max) { - // session is too old, log the user out and continue - SecurityContextHolder.getContext().setAuthentication(null); - } - } - } - chain.doFilter(req, res); - } else { - // no prompt parameter, not our business - chain.doFilter(req, res); - } - - - } - - /** - * @param parameterMap - * @return - */ - private Map createRequestMap(Map parameterMap) { - Map requestMap = new HashMap<>(); - for (String key : parameterMap.keySet()) { - String[] val = parameterMap.get(key); - if (val != null && val.length > 0) { - requestMap.put(key, val[0]); // add the first value only (which is what Spring seems to do) - } - } - - return requestMap; - } - - /** - * @return the requestMatcher - */ - public RequestMatcher getRequestMatcher() { - return requestMatcher; - } - - /** - * @param requestMatcher the requestMatcher to set - */ - public void setRequestMatcher(RequestMatcher requestMatcher) { - this.requestMatcher = requestMatcher; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/request/ConnectOAuth2RequestFactory.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/request/ConnectOAuth2RequestFactory.java deleted file mode 100644 index d957f31a4f..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/request/ConnectOAuth2RequestFactory.java +++ /dev/null @@ -1,377 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.request; - - -import static org.mitre.openid.connect.request.ConnectRequestParameters.AUD; -import static org.mitre.openid.connect.request.ConnectRequestParameters.CLAIMS; -import static org.mitre.openid.connect.request.ConnectRequestParameters.CLIENT_ID; -import static org.mitre.openid.connect.request.ConnectRequestParameters.CODE_CHALLENGE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.CODE_CHALLENGE_METHOD; -import static org.mitre.openid.connect.request.ConnectRequestParameters.DISPLAY; -import static org.mitre.openid.connect.request.ConnectRequestParameters.LOGIN_HINT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.NONCE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.REDIRECT_URI; -import static org.mitre.openid.connect.request.ConnectRequestParameters.REQUEST; -import static org.mitre.openid.connect.request.ConnectRequestParameters.RESPONSE_TYPE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.SCOPE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.STATE; - -import java.io.Serializable; -import java.text.ParseException; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import org.mitre.jwt.encryption.service.JWTEncryptionAndDecryptionService; -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.jwt.signer.service.impl.ClientKeyCacheService; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.PKCEAlgorithm; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; -import org.springframework.security.oauth2.common.util.OAuth2Utils; -import org.springframework.security.oauth2.provider.AuthorizationRequest; -import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; -import org.springframework.stereotype.Component; - -import com.google.common.base.Strings; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.nimbusds.jose.Algorithm; -import com.nimbusds.jose.JWEObject.State; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jwt.EncryptedJWT; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.JWTParser; -import com.nimbusds.jwt.PlainJWT; -import com.nimbusds.jwt.SignedJWT; - -@Component("connectOAuth2RequestFactory") -public class ConnectOAuth2RequestFactory extends DefaultOAuth2RequestFactory { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(ConnectOAuth2RequestFactory.class); - - private ClientDetailsEntityService clientDetailsService; - - @Autowired - private ClientKeyCacheService validators; - - @Autowired - private JWTEncryptionAndDecryptionService encryptionService; - - private JsonParser parser = new JsonParser(); - - /** - * Constructor with arguments - * - * @param clientDetailsService - */ - @Autowired - public ConnectOAuth2RequestFactory(ClientDetailsEntityService clientDetailsService) { - super(clientDetailsService); - this.clientDetailsService = clientDetailsService; - } - - @Override - public AuthorizationRequest createAuthorizationRequest(Map inputParams) { - - - AuthorizationRequest request = new AuthorizationRequest(inputParams, Collections. emptyMap(), - inputParams.get(OAuth2Utils.CLIENT_ID), - OAuth2Utils.parseParameterList(inputParams.get(OAuth2Utils.SCOPE)), null, - null, false, inputParams.get(OAuth2Utils.STATE), - inputParams.get(OAuth2Utils.REDIRECT_URI), - OAuth2Utils.parseParameterList(inputParams.get(OAuth2Utils.RESPONSE_TYPE))); - - //Add extension parameters to the 'extensions' map - - if (inputParams.containsKey(PROMPT)) { - request.getExtensions().put(PROMPT, inputParams.get(PROMPT)); - } - if (inputParams.containsKey(NONCE)) { - request.getExtensions().put(NONCE, inputParams.get(NONCE)); - } - - if (inputParams.containsKey(CLAIMS)) { - JsonObject claimsRequest = parseClaimRequest(inputParams.get(CLAIMS)); - if (claimsRequest != null) { - request.getExtensions().put(CLAIMS, claimsRequest.toString()); - } - } - - if (inputParams.containsKey(MAX_AGE)) { - request.getExtensions().put(MAX_AGE, inputParams.get(MAX_AGE)); - } - - if (inputParams.containsKey(LOGIN_HINT)) { - request.getExtensions().put(LOGIN_HINT, inputParams.get(LOGIN_HINT)); - } - - if (inputParams.containsKey(AUD)) { - request.getExtensions().put(AUD, inputParams.get(AUD)); - } - - if (inputParams.containsKey(CODE_CHALLENGE)) { - request.getExtensions().put(CODE_CHALLENGE, inputParams.get(CODE_CHALLENGE)); - if (inputParams.containsKey(CODE_CHALLENGE_METHOD)) { - request.getExtensions().put(CODE_CHALLENGE_METHOD, inputParams.get(CODE_CHALLENGE_METHOD)); - } else { - // if the client doesn't specify a code challenge transformation method, it's "plain" - request.getExtensions().put(CODE_CHALLENGE_METHOD, PKCEAlgorithm.plain.getName()); - } - - } - - if (inputParams.containsKey(REQUEST)) { - request.getExtensions().put(REQUEST, inputParams.get(REQUEST)); - processRequestObject(inputParams.get(REQUEST), request); - } - - if (request.getClientId() != null) { - try { - ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId()); - - if ((request.getScope() == null || request.getScope().isEmpty())) { - Set clientScopes = client.getScope(); - request.setScope(clientScopes); - } - - if (request.getExtensions().get(MAX_AGE) == null && client.getDefaultMaxAge() != null) { - request.getExtensions().put(MAX_AGE, client.getDefaultMaxAge().toString()); - } - } catch (OAuth2Exception e) { - logger.error("Caught OAuth2 exception trying to test client scopes and max age:", e); - } - } - - return request; - } - - /** - * - * @param jwtString - * @param request - */ - private void processRequestObject(String jwtString, AuthorizationRequest request) { - - // parse the request object - try { - JWT jwt = JWTParser.parse(jwtString); - - if (jwt instanceof SignedJWT) { - // it's a signed JWT, check the signature - - SignedJWT signedJwt = (SignedJWT)jwt; - - // need to check clientId first so that we can load the client to check other fields - if (request.getClientId() == null) { - request.setClientId(signedJwt.getJWTClaimsSet().getStringClaim(CLIENT_ID)); - } - - ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId()); - - if (client == null) { - throw new InvalidClientException("Client not found: " + request.getClientId()); - } - - - JWSAlgorithm alg = signedJwt.getHeader().getAlgorithm(); - - if (client.getRequestObjectSigningAlg() == null || - !client.getRequestObjectSigningAlg().equals(alg)) { - throw new InvalidClientException("Client's registered request object signing algorithm (" + client.getRequestObjectSigningAlg() + ") does not match request object's actual algorithm (" + alg.getName() + ")"); - } - - JWTSigningAndValidationService validator = validators.getValidator(client, alg); - - if (validator == null) { - throw new InvalidClientException("Unable to create signature validator for client " + client + " and algorithm " + alg); - } - - if (!validator.validateSignature(signedJwt)) { - throw new InvalidClientException("Signature did not validate for presented JWT request object."); - } - - } else if (jwt instanceof PlainJWT) { - PlainJWT plainJwt = (PlainJWT)jwt; - - // need to check clientId first so that we can load the client to check other fields - if (request.getClientId() == null) { - request.setClientId(plainJwt.getJWTClaimsSet().getStringClaim(CLIENT_ID)); - } - - ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId()); - - if (client == null) { - throw new InvalidClientException("Client not found: " + request.getClientId()); - } - - if (client.getRequestObjectSigningAlg() == null) { - throw new InvalidClientException("Client is not registered for unsigned request objects (no request_object_signing_alg registered)"); - } else if (!client.getRequestObjectSigningAlg().equals(Algorithm.NONE)) { - throw new InvalidClientException("Client is not registered for unsigned request objects (request_object_signing_alg is " + client.getRequestObjectSigningAlg() +")"); - } - - // if we got here, we're OK, keep processing - - } else if (jwt instanceof EncryptedJWT) { - - EncryptedJWT encryptedJWT = (EncryptedJWT)jwt; - - // decrypt the jwt if we can - - encryptionService.decryptJwt(encryptedJWT); - - // TODO: what if the content is a signed JWT? (#525) - - if (!encryptedJWT.getState().equals(State.DECRYPTED)) { - throw new InvalidClientException("Unable to decrypt the request object"); - } - - // need to check clientId first so that we can load the client to check other fields - if (request.getClientId() == null) { - request.setClientId(encryptedJWT.getJWTClaimsSet().getStringClaim(CLIENT_ID)); - } - - ClientDetailsEntity client = clientDetailsService.loadClientByClientId(request.getClientId()); - - if (client == null) { - throw new InvalidClientException("Client not found: " + request.getClientId()); - } - - - } - - - /* - * NOTE: Claims inside the request object always take precedence over those in the parameter map. - */ - - // now that we've got the JWT, and it's been parsed, validated, and/or decrypted, we can process the claims - - JWTClaimsSet claims = jwt.getJWTClaimsSet(); - - Set responseTypes = OAuth2Utils.parseParameterList(claims.getStringClaim(RESPONSE_TYPE)); - if (!responseTypes.isEmpty()) { - if (!responseTypes.equals(request.getResponseTypes())) { - logger.info("Mismatch between request object and regular parameter for response_type, using request object"); - } - request.setResponseTypes(responseTypes); - } - - String redirectUri = claims.getStringClaim(REDIRECT_URI); - if (redirectUri != null) { - if (!redirectUri.equals(request.getRedirectUri())) { - logger.info("Mismatch between request object and regular parameter for redirect_uri, using request object"); - } - request.setRedirectUri(redirectUri); - } - - String state = claims.getStringClaim(STATE); - if(state != null) { - if (!state.equals(request.getState())) { - logger.info("Mismatch between request object and regular parameter for state, using request object"); - } - request.setState(state); - } - - String nonce = claims.getStringClaim(NONCE); - if(nonce != null) { - if (!nonce.equals(request.getExtensions().get(NONCE))) { - logger.info("Mismatch between request object and regular parameter for nonce, using request object"); - } - request.getExtensions().put(NONCE, nonce); - } - - String display = claims.getStringClaim(DISPLAY); - if (display != null) { - if (!display.equals(request.getExtensions().get(DISPLAY))) { - logger.info("Mismatch between request object and regular parameter for display, using request object"); - } - request.getExtensions().put(DISPLAY, display); - } - - String prompt = claims.getStringClaim(PROMPT); - if (prompt != null) { - if (!prompt.equals(request.getExtensions().get(PROMPT))) { - logger.info("Mismatch between request object and regular parameter for prompt, using request object"); - } - request.getExtensions().put(PROMPT, prompt); - } - - Set scope = OAuth2Utils.parseParameterList(claims.getStringClaim(SCOPE)); - if (!scope.isEmpty()) { - if (!scope.equals(request.getScope())) { - logger.info("Mismatch between request object and regular parameter for scope, using request object"); - } - request.setScope(scope); - } - - JsonObject claimRequest = parseClaimRequest(claims.getStringClaim(CLAIMS)); - if (claimRequest != null) { - Serializable claimExtension = request.getExtensions().get(CLAIMS); - if (claimExtension == null || !claimRequest.equals(parseClaimRequest(claimExtension.toString()))) { - logger.info("Mismatch between request object and regular parameter for claims, using request object"); - } - // we save the string because the object might not be a Java Serializable, and we can parse it easily enough anyway - request.getExtensions().put(CLAIMS, claimRequest.toString()); - } - - String loginHint = claims.getStringClaim(LOGIN_HINT); - if (loginHint != null) { - if (!loginHint.equals(request.getExtensions().get(LOGIN_HINT))) { - logger.info("Mistmatch between request object and regular parameter for login_hint, using requst object"); - } - request.getExtensions().put(LOGIN_HINT, loginHint); - } - - } catch (ParseException e) { - logger.error("ParseException while parsing RequestObject:", e); - } - } - - /** - * @param claimRequestString - * @return - */ - private JsonObject parseClaimRequest(String claimRequestString) { - if (Strings.isNullOrEmpty(claimRequestString)) { - return null; - } else { - JsonElement el = parser.parse(claimRequestString); - if (el != null && el.isJsonObject()) { - return el.getAsJsonObject(); - } else { - return null; - } - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java deleted file mode 100644 index 4382a7c2bb..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultApprovedSiteService.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Set; - -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.service.ApprovedSiteService; -import org.mitre.openid.connect.service.StatsService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; - -/** - * Implementation of the ApprovedSiteService - * - * @author Michael Joseph Walsh, aanganes - * - */ -@Service("defaultApprovedSiteService") -public class DefaultApprovedSiteService implements ApprovedSiteService { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(DefaultApprovedSiteService.class); - - @Autowired - private ApprovedSiteRepository approvedSiteRepository; - - @Autowired - private OAuth2TokenRepository tokenRepository; - - @Autowired - private StatsService statsService; - - @Override - public Collection getAll() { - return approvedSiteRepository.getAll(); - } - - @Override - @Transactional(value="defaultTransactionManager") - public ApprovedSite save(ApprovedSite approvedSite) { - ApprovedSite a = approvedSiteRepository.save(approvedSite); - statsService.resetCache(); - return a; - } - - @Override - public ApprovedSite getById(Long id) { - return approvedSiteRepository.getById(id); - } - - @Override - @Transactional(value="defaultTransactionManager") - public void remove(ApprovedSite approvedSite) { - - //Remove any associated access and refresh tokens - List accessTokens = getApprovedAccessTokens(approvedSite); - - for (OAuth2AccessTokenEntity token : accessTokens) { - if (token.getRefreshToken() != null) { - tokenRepository.removeRefreshToken(token.getRefreshToken()); - } - tokenRepository.removeAccessToken(token); - } - - approvedSiteRepository.remove(approvedSite); - - statsService.resetCache(); - } - - @Override - @Transactional(value="defaultTransactionManager") - public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set allowedScopes) { - - ApprovedSite as = new ApprovedSite(); - - Date now = new Date(); - as.setCreationDate(now); - as.setAccessDate(now); - as.setClientId(clientId); - as.setUserId(userId); - as.setTimeoutDate(timeoutDate); - as.setAllowedScopes(allowedScopes); - - return save(as); - - } - - @Override - public Collection getByClientIdAndUserId(String clientId, String userId) { - - return approvedSiteRepository.getByClientIdAndUserId(clientId, userId); - - } - - /** - * @param userId - * @return - * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByUserId(java.lang.String) - */ - @Override - public Collection getByUserId(String userId) { - return approvedSiteRepository.getByUserId(userId); - } - - /** - * @param clientId - * @return - * @see org.mitre.openid.connect.repository.ApprovedSiteRepository#getByClientId(java.lang.String) - */ - @Override - public Collection getByClientId(String clientId) { - return approvedSiteRepository.getByClientId(clientId); - } - - - @Override - public void clearApprovedSitesForClient(ClientDetails client) { - Collection approvedSites = approvedSiteRepository.getByClientId(client.getClientId()); - if (approvedSites != null) { - for (ApprovedSite approvedSite : approvedSites) { - remove(approvedSite); - } - } - } - - @Override - public void clearExpiredSites() { - - logger.debug("Clearing expired approved sites"); - - Collection expiredSites = getExpired(); - if (expiredSites.size() > 0) { - logger.info("Found " + expiredSites.size() + " expired approved sites."); - } - if (expiredSites != null) { - for (ApprovedSite expired : expiredSites) { - remove(expired); - } - } - - } - - private Predicate isExpired = new Predicate() { - @Override - public boolean apply(ApprovedSite input) { - return (input != null && input.isExpired()); - } - }; - - private Collection getExpired() { - return Collections2.filter(approvedSiteRepository.getAll(), isExpired); - } - - @Override - public List getApprovedAccessTokens( - ApprovedSite approvedSite) { - return tokenRepository.getAccessTokensForApprovedSite(approvedSite); - - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultDynamicClientValidationService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultDynamicClientValidationService.java deleted file mode 100644 index 1599c35a95..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultDynamicClientValidationService.java +++ /dev/null @@ -1,493 +0,0 @@ -package org.mitre.openid.connect.service.impl; - -import static org.mitre.oauth2.model.RegisteredClientFields.APPLICATION_TYPE; -import static org.mitre.oauth2.model.RegisteredClientFields.CLAIMS_REDIRECT_URIS; -import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_ID; -import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_ID_ISSUED_AT; -import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_NAME; -import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_SECRET; -import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_SECRET_EXPIRES_AT; -import static org.mitre.oauth2.model.RegisteredClientFields.CLIENT_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.CONTACTS; -import static org.mitre.oauth2.model.RegisteredClientFields.DEFAULT_ACR_VALUES; -import static org.mitre.oauth2.model.RegisteredClientFields.DEFAULT_MAX_AGE; -import static org.mitre.oauth2.model.RegisteredClientFields.GRANT_TYPES; -import static org.mitre.oauth2.model.RegisteredClientFields.ID_TOKEN_ENCRYPTED_RESPONSE_ALG; -import static org.mitre.oauth2.model.RegisteredClientFields.ID_TOKEN_ENCRYPTED_RESPONSE_ENC; -import static org.mitre.oauth2.model.RegisteredClientFields.ID_TOKEN_SIGNED_RESPONSE_ALG; -import static org.mitre.oauth2.model.RegisteredClientFields.INITIATE_LOGIN_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.JWKS; -import static org.mitre.oauth2.model.RegisteredClientFields.JWKS_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.LOGO_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.POLICY_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.POST_LOGOUT_REDIRECT_URIS; -import static org.mitre.oauth2.model.RegisteredClientFields.REDIRECT_URIS; -import static org.mitre.oauth2.model.RegisteredClientFields.REGISTRATION_ACCESS_TOKEN; -import static org.mitre.oauth2.model.RegisteredClientFields.REGISTRATION_CLIENT_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.REQUEST_OBJECT_SIGNING_ALG; -import static org.mitre.oauth2.model.RegisteredClientFields.REQUEST_URIS; -import static org.mitre.oauth2.model.RegisteredClientFields.REQUIRE_AUTH_TIME; -import static org.mitre.oauth2.model.RegisteredClientFields.RESPONSE_TYPES; -import static org.mitre.oauth2.model.RegisteredClientFields.SCOPE; -import static org.mitre.oauth2.model.RegisteredClientFields.SECTOR_IDENTIFIER_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.SOFTWARE_STATEMENT; -import static org.mitre.oauth2.model.RegisteredClientFields.SUBJECT_TYPE; -import static org.mitre.oauth2.model.RegisteredClientFields.TOKEN_ENDPOINT_AUTH_METHOD; -import static org.mitre.oauth2.model.RegisteredClientFields.TOKEN_ENDPOINT_AUTH_SIGNING_ALG; -import static org.mitre.oauth2.model.RegisteredClientFields.TOS_URI; -import static org.mitre.oauth2.model.RegisteredClientFields.USERINFO_ENCRYPTED_RESPONSE_ALG; -import static org.mitre.oauth2.model.RegisteredClientFields.USERINFO_ENCRYPTED_RESPONSE_ENC; -import static org.mitre.oauth2.model.RegisteredClientFields.USERINFO_SIGNED_RESPONSE_ALG; - -import java.text.ParseException; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -import org.mitre.jwt.assertion.AssertionValidator; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AppType; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.exception.ValidationException; -import org.mitre.openid.connect.service.BlacklistedSiteService; -import org.mitre.openid.connect.service.DynamicClientValidationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.http.HttpStatus; -import org.springframework.security.oauth2.common.util.OAuth2Utils; -import org.springframework.stereotype.Service; - -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jwt.JWTClaimsSet; - -@Service -public class DefaultDynamicClientValidationService implements DynamicClientValidationService { - public static final Logger LOG = - LoggerFactory.getLogger(DefaultDynamicClientValidationService.class); - - - protected final SystemScopeService scopeService; - - protected final AssertionValidator assertionValidator; - - protected final BlacklistedSiteService blacklistService; - - protected final ConfigurationPropertiesBean config; - - protected final ClientDetailsEntityService clientService; - - @Autowired - public DefaultDynamicClientValidationService(SystemScopeService scopeService, - @Qualifier("clientAssertionValidator") AssertionValidator assertionValidator, - BlacklistedSiteService blacklistService, ConfigurationPropertiesBean config, - ClientDetailsEntityService clientService) { - this.scopeService = scopeService; - this.assertionValidator = assertionValidator; - this.blacklistService = blacklistService; - this.config = config; - this.clientService = clientService; - } - - public static final ImmutableSet ALLOWED_GRANT_TYPES = - ImmutableSet.of("authorization_code", "implicit", "client_credentials", "refresh_token", - "urn:ietf:params:oauth:grant_type:redelegate", - "urn:ietf:params:oauth:grant-type:device_code"); - - @Override - public ClientDetailsEntity validateClient(ClientDetailsEntity client) throws ValidationException { - - client = validateSoftwareStatement(client); - client = validateScopes(client); - client = validateResponseTypes(client); - client = validateGrantTypes(client); - client = validateRedirectUris(client); - client = validateAuth(client); - - return client; - } - - protected ClientDetailsEntity validateScopes(ClientDetailsEntity newClient) - throws ValidationException { - // scopes that the client is asking for - Set requestedScopes = scopeService.fromStrings(newClient.getScope()); - - // the scopes that the client can have must be a subset of the dynamically allowed scopes - Set allowedScopes = requestedScopes.stream() - .filter(s -> !s.isRestricted() && !SystemScopeService.reservedValues.contains(s.getValue())) - .collect(Collectors.toSet()); - - // if the client didn't ask for any, give them the defaults - if (allowedScopes == null || allowedScopes.isEmpty()) { - allowedScopes = scopeService.getDefaults(); - } - - newClient.setScope(scopeService.toStrings(allowedScopes)); - - return newClient; - } - - protected ClientDetailsEntity validateResponseTypes(ClientDetailsEntity newClient) - throws ValidationException { - if (newClient.getResponseTypes() == null) { - newClient.setResponseTypes(new HashSet()); - } - return newClient; - } - - protected ClientDetailsEntity validateGrantTypes(ClientDetailsEntity newClient) - throws ValidationException { - // set default grant types if needed - if (newClient.getGrantTypes() == null || newClient.getGrantTypes().isEmpty()) { - if (newClient.getScope().contains("offline_access")) { // client asked for offline access - newClient.setGrantTypes(Sets.newHashSet("authorization_code", "refresh_token")); // allow - // authorization - // code and - // refresh - // token - // grant - // types by - // default - } else { - newClient.setGrantTypes(Sets.newHashSet("authorization_code")); // allow authorization code - // grant type by default - } - if (config.isDualClient()) { - Set extendedGrandTypes = newClient.getGrantTypes(); - extendedGrandTypes.add("client_credentials"); - newClient.setGrantTypes(extendedGrandTypes); - } - } - - // don't allow "password" grant type for dynamic registration - if (newClient.getGrantTypes().contains("password")) { - // return an error, you can't dynamically register for the password grant - throw new ValidationException("invalid_client_metadata", - "The password grant type is not allowed in dynamic registration on this server.", - HttpStatus.BAD_REQUEST); - } - - // don't allow clients to have multiple incompatible grant types and scopes - if (newClient.getGrantTypes().contains("authorization_code")) { - - // check for incompatible grants - if (newClient.getGrantTypes().contains("implicit") - || (!config.isDualClient() && newClient.getGrantTypes().contains("client_credentials"))) { - // return an error, you can't have these grant types together - throw new ValidationException("invalid_client_metadata", - "Incompatible grant types requested: " + newClient.getGrantTypes(), - HttpStatus.BAD_REQUEST); - } - - if (newClient.getResponseTypes().contains("token")) { - // return an error, you can't have this grant type and response type together - throw new ValidationException( - "invalid_client_metadata", "Incompatible response types requested: " - + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), - HttpStatus.BAD_REQUEST); - } - - newClient.getResponseTypes().add("code"); - } - - if (newClient.getGrantTypes().contains("implicit")) { - - // check for incompatible grants - if (newClient.getGrantTypes().contains("authorization_code") - || (!config.isDualClient() && newClient.getGrantTypes().contains("client_credentials"))) { - // return an error, you can't have these grant types together - throw new ValidationException("invalid_client_metadata", - "Incompatible grant types requested: " + newClient.getGrantTypes(), - HttpStatus.BAD_REQUEST); - } - - if (newClient.getResponseTypes().contains("code")) { - // return an error, you can't have this grant type and response type together - throw new ValidationException( - "invalid_client_metadata", "Incompatible response types requested: " - + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), - HttpStatus.BAD_REQUEST); - } - - newClient.getResponseTypes().add("token"); - - // don't allow refresh tokens in implicit clients - newClient.getGrantTypes().remove("refresh_token"); - newClient.getScope().remove(SystemScopeService.OFFLINE_ACCESS); - } - - if (newClient.getGrantTypes().contains("client_credentials")) { - - // check for incompatible grants - if (!config.isDualClient() && (newClient.getGrantTypes().contains("authorization_code") - || newClient.getGrantTypes().contains("implicit"))) { - // return an error, you can't have these grant types together - throw new ValidationException("invalid_client_metadata", - "Incompatible grant types requested: " + newClient.getGrantTypes(), - HttpStatus.BAD_REQUEST); - } - - if (!newClient.getResponseTypes().isEmpty()) { - // return an error, you can't have this grant type and response type together - throw new ValidationException( - "invalid_client_metadata", "Incompatible response types requested: " - + newClient.getGrantTypes() + " / " + newClient.getResponseTypes(), - HttpStatus.BAD_REQUEST); - } - - // don't allow refresh tokens or id tokens in client_credentials clients - newClient.getGrantTypes().remove("refresh_token"); - newClient.getScope().remove(SystemScopeService.OFFLINE_ACCESS); - newClient.getScope().remove(SystemScopeService.OPENID_SCOPE); - } - - if (newClient.getGrantTypes().isEmpty()) { - // return an error, you need at least one grant type selected - throw new ValidationException("invalid_client_metadata", - "Clients must register at least one grant type.", HttpStatus.BAD_REQUEST); - } - return newClient; - } - - protected ClientDetailsEntity validateRedirectUris(ClientDetailsEntity newClient) - throws ValidationException { - // check to make sure this client registered a redirect URI if using a redirect flow - if (newClient.getGrantTypes().contains("authorization_code") - || newClient.getGrantTypes().contains("implicit")) { - if (newClient.getRedirectUris() == null || newClient.getRedirectUris().isEmpty()) { - // return an error - throw new ValidationException("invalid_redirect_uri", - "Clients using a redirect-based grant type must register at least one redirect URI.", - HttpStatus.BAD_REQUEST); - } - - for (String uri : newClient.getRedirectUris()) { - if (blacklistService.isBlacklisted(uri)) { - // return an error - throw new ValidationException("invalid_redirect_uri", - "Redirect URI is not allowed: " + uri, HttpStatus.BAD_REQUEST); - } - - if (uri.contains("#")) { - // if it contains the hash symbol then it has a fragment, which isn't allowed - throw new ValidationException("invalid_redirect_uri", - "Redirect URI can not have a fragment", HttpStatus.BAD_REQUEST); - } - } - } - - return newClient; - } - - protected ClientDetailsEntity validateAuth(ClientDetailsEntity newClient) - throws ValidationException { - if (newClient.getTokenEndpointAuthMethod() == null) { - newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC); - } - - if (newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_BASIC - || newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_JWT - || newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_POST) { - - if (Strings.isNullOrEmpty(newClient.getClientSecret())) { - // no secret yet, we need to generate a secret - newClient = clientService.generateClientSecret(newClient); - } - } else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.PRIVATE_KEY) { - if (Strings.isNullOrEmpty(newClient.getJwksUri()) && newClient.getJwks() == null) { - throw new ValidationException("invalid_client_metadata", - "JWK Set URI required when using private key authentication", HttpStatus.BAD_REQUEST); - } - - newClient.setClientSecret(null); - } else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.NONE) { - newClient.setClientSecret(null); - } else { - throw new ValidationException("invalid_client_metadata", "Unknown authentication method", - HttpStatus.BAD_REQUEST); - } - return newClient; - } - - - /** - * @param newClient - * @return - * @throws ValidationException - */ - protected ClientDetailsEntity validateSoftwareStatement(ClientDetailsEntity newClient) - throws ValidationException { - if (newClient.getSoftwareStatement() != null) { - if (assertionValidator.isValid(newClient.getSoftwareStatement())) { - // we have a software statement and its envelope passed all the checks from our validator - - // swap out all of the client's fields for the associated parts of the software statement - try { - JWTClaimsSet claimSet = newClient.getSoftwareStatement().getJWTClaimsSet(); - for (String claim : claimSet.getClaims().keySet()) { - switch (claim) { - case SOFTWARE_STATEMENT: - throw new ValidationException("invalid_client_metadata", - "Software statement can't include another software statement", - HttpStatus.BAD_REQUEST); - case CLAIMS_REDIRECT_URIS: - newClient - .setClaimsRedirectUris(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case CLIENT_SECRET_EXPIRES_AT: - throw new ValidationException("invalid_client_metadata", - "Software statement can't include a client secret expiration time", - HttpStatus.BAD_REQUEST); - case CLIENT_ID_ISSUED_AT: - throw new ValidationException("invalid_client_metadata", - "Software statement can't include a client ID issuance time", - HttpStatus.BAD_REQUEST); - case REGISTRATION_CLIENT_URI: - throw new ValidationException("invalid_client_metadata", - "Software statement can't include a client configuration endpoint", - HttpStatus.BAD_REQUEST); - case REGISTRATION_ACCESS_TOKEN: - throw new ValidationException("invalid_client_metadata", - "Software statement can't include a client registration access token", - HttpStatus.BAD_REQUEST); - case REQUEST_URIS: - newClient.setRequestUris(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case POST_LOGOUT_REDIRECT_URIS: - newClient - .setPostLogoutRedirectUris(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case INITIATE_LOGIN_URI: - newClient.setInitiateLoginUri(claimSet.getStringClaim(claim)); - break; - case DEFAULT_ACR_VALUES: - newClient.setDefaultACRvalues(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case REQUIRE_AUTH_TIME: - newClient.setRequireAuthTime(claimSet.getBooleanClaim(claim)); - break; - case DEFAULT_MAX_AGE: - newClient.setDefaultMaxAge(claimSet.getIntegerClaim(claim)); - break; - case TOKEN_ENDPOINT_AUTH_SIGNING_ALG: - newClient.setTokenEndpointAuthSigningAlg( - JWSAlgorithm.parse(claimSet.getStringClaim(claim))); - break; - case ID_TOKEN_ENCRYPTED_RESPONSE_ENC: - newClient.setIdTokenEncryptedResponseEnc( - EncryptionMethod.parse(claimSet.getStringClaim(claim))); - break; - case ID_TOKEN_ENCRYPTED_RESPONSE_ALG: - newClient.setIdTokenEncryptedResponseAlg( - JWEAlgorithm.parse(claimSet.getStringClaim(claim))); - break; - case ID_TOKEN_SIGNED_RESPONSE_ALG: - newClient - .setIdTokenSignedResponseAlg(JWSAlgorithm.parse(claimSet.getStringClaim(claim))); - break; - case USERINFO_ENCRYPTED_RESPONSE_ENC: - newClient.setUserInfoEncryptedResponseEnc( - EncryptionMethod.parse(claimSet.getStringClaim(claim))); - break; - case USERINFO_ENCRYPTED_RESPONSE_ALG: - newClient.setUserInfoEncryptedResponseAlg( - JWEAlgorithm.parse(claimSet.getStringClaim(claim))); - break; - case USERINFO_SIGNED_RESPONSE_ALG: - newClient - .setUserInfoSignedResponseAlg(JWSAlgorithm.parse(claimSet.getStringClaim(claim))); - break; - case REQUEST_OBJECT_SIGNING_ALG: - newClient - .setRequestObjectSigningAlg(JWSAlgorithm.parse(claimSet.getStringClaim(claim))); - break; - case SUBJECT_TYPE: - newClient.setSubjectType(SubjectType.getByValue(claimSet.getStringClaim(claim))); - break; - case SECTOR_IDENTIFIER_URI: - newClient.setSectorIdentifierUri(claimSet.getStringClaim(claim)); - break; - case APPLICATION_TYPE: - newClient.setApplicationType(AppType.getByValue(claimSet.getStringClaim(claim))); - break; - case JWKS_URI: - newClient.setJwksUri(claimSet.getStringClaim(claim)); - break; - case JWKS: - newClient.setJwks(JWKSet.parse(claimSet.getJSONObjectClaim(claim).toJSONString())); - break; - case POLICY_URI: - newClient.setPolicyUri(claimSet.getStringClaim(claim)); - break; - case RESPONSE_TYPES: - newClient.setResponseTypes(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case GRANT_TYPES: - newClient.setGrantTypes(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case SCOPE: - newClient.setScope(OAuth2Utils.parseParameterList(claimSet.getStringClaim(claim))); - break; - case TOKEN_ENDPOINT_AUTH_METHOD: - newClient.setTokenEndpointAuthMethod( - AuthMethod.getByValue(claimSet.getStringClaim(claim))); - break; - case TOS_URI: - newClient.setTosUri(claimSet.getStringClaim(claim)); - break; - case CONTACTS: - newClient.setContacts(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case LOGO_URI: - newClient.setLogoUri(claimSet.getStringClaim(claim)); - break; - case CLIENT_URI: - newClient.setClientUri(claimSet.getStringClaim(claim)); - break; - case CLIENT_NAME: - newClient.setClientName(claimSet.getStringClaim(claim)); - break; - case REDIRECT_URIS: - newClient.setRedirectUris(Sets.newHashSet(claimSet.getStringListClaim(claim))); - break; - case CLIENT_SECRET: - throw new ValidationException("invalid_client_metadata", - "Software statement can't contain client secret", HttpStatus.BAD_REQUEST); - case CLIENT_ID: - throw new ValidationException("invalid_client_metadata", - "Software statement can't contain client ID", HttpStatus.BAD_REQUEST); - - default: - LOG.warn("Software statement contained unknown field: " + claim + " with value " - + claimSet.getClaim(claim)); - break; - } - } - - return newClient; - } catch (ParseException e) { - throw new ValidationException("invalid_client_metadata", - "Software statement claims didn't parse", HttpStatus.BAD_REQUEST); - } - } else { - throw new ValidationException("invalid_client_metadata", - "Software statement rejected by validator", HttpStatus.BAD_REQUEST); - } - } else { - // nothing to see here, carry on - return newClient; - } - } -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java deleted file mode 100644 index 218e40fb35..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java +++ /dev/null @@ -1,353 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import static org.mitre.openid.connect.request.ConnectRequestParameters.MAX_AGE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.NONCE; - -import java.util.Date; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.mitre.jwt.encryption.service.JWTEncryptionAndDecryptionService; -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.jwt.signer.service.impl.ClientKeyCacheService; -import org.mitre.jwt.signer.service.impl.SymmetricKeyJWTValidatorCacheService; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.service.OIDCTokenService; -import org.mitre.openid.connect.util.IdTokenHashUtils; -import org.mitre.openid.connect.web.AuthenticationTimeStamper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.stereotype.Service; - -import com.google.common.base.Strings; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.nimbusds.jose.Algorithm; -import com.nimbusds.jose.JWEHeader; -import com.nimbusds.jose.JWEObject; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.util.Base64URL; -import com.nimbusds.jwt.EncryptedJWT; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.PlainJWT; -import com.nimbusds.jwt.SignedJWT; -/** - * Default implementation of service to create specialty OpenID Connect tokens. - * - * @author Amanda Anganes - * - */ -@Service -public class DefaultOIDCTokenService implements OIDCTokenService { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(DefaultOIDCTokenService.class); - - @Autowired - private JWTSigningAndValidationService jwtService; - - @Autowired - private AuthenticationHolderRepository authenticationHolderRepository; - - @Autowired - private ConfigurationPropertiesBean configBean; - - @Autowired - private ClientKeyCacheService encrypters; - - @Autowired - private SymmetricKeyJWTValidatorCacheService symmetricCacheService; - - @Autowired - private OAuth2TokenEntityService tokenService; - - @Override - public JWT createIdToken(ClientDetailsEntity client, OAuth2Request request, Date issueTime, String sub, OAuth2AccessTokenEntity accessToken) { - - JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); - - if (client.getIdTokenSignedResponseAlg() != null) { - signingAlg = client.getIdTokenSignedResponseAlg(); - } - - - JWT idToken = null; - - JWTClaimsSet.Builder idClaims = new JWTClaimsSet.Builder(); - - // if the auth time claim was explicitly requested OR if the client always wants the auth time, put it in - if (request.getExtensions().containsKey(MAX_AGE) - || (request.getExtensions().containsKey("idtoken")) // TODO: parse the ID Token claims (#473) -- for now assume it could be in there - || (client.getRequireAuthTime() != null && client.getRequireAuthTime())) { - - if (request.getExtensions().get(AuthenticationTimeStamper.AUTH_TIMESTAMP) != null) { - - Long authTimestamp = Long.parseLong((String) request.getExtensions().get(AuthenticationTimeStamper.AUTH_TIMESTAMP)); - if (authTimestamp != null) { - idClaims.claim("auth_time", authTimestamp / 1000L); - } - } else { - // we couldn't find the timestamp! - logger.warn("Unable to find authentication timestamp! There is likely something wrong with the configuration."); - } - } - - idClaims.issueTime(issueTime); - - if (client.getIdTokenValiditySeconds() != null) { - Date expiration = new Date(System.currentTimeMillis() + (client.getIdTokenValiditySeconds() * 1000L)); - idClaims.expirationTime(expiration); - } - - idClaims.issuer(configBean.getIssuer()); - idClaims.subject(sub); - idClaims.audience(Lists.newArrayList(client.getClientId())); - idClaims.jwtID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it - - String nonce = (String)request.getExtensions().get(NONCE); - if (!Strings.isNullOrEmpty(nonce)) { - idClaims.claim("nonce", nonce); - } - - Set responseTypes = request.getResponseTypes(); - - if (responseTypes.contains("token")) { - // calculate the token hash - Base64URL at_hash = IdTokenHashUtils.getAccessTokenHash(signingAlg, accessToken); - idClaims.claim("at_hash", at_hash); - } - - addCustomIdTokenClaims(idClaims, client, request, sub, accessToken); - - if (client.getIdTokenEncryptedResponseAlg() != null && !client.getIdTokenEncryptedResponseAlg().equals(Algorithm.NONE) - && client.getIdTokenEncryptedResponseEnc() != null && !client.getIdTokenEncryptedResponseEnc().equals(Algorithm.NONE) - && (!Strings.isNullOrEmpty(client.getJwksUri()) || client.getJwks() != null)) { - - JWTEncryptionAndDecryptionService encrypter = encrypters.getEncrypter(client); - - if (encrypter != null) { - - idToken = new EncryptedJWT(new JWEHeader(client.getIdTokenEncryptedResponseAlg(), client.getIdTokenEncryptedResponseEnc()), idClaims.build()); - - encrypter.encryptJwt((JWEObject) idToken); - - } else { - logger.error("Couldn't find encrypter for client: " + client.getClientId()); - } - - } else { - - if (signingAlg.equals(Algorithm.NONE)) { - // unsigned ID token - idToken = new PlainJWT(idClaims.build()); - - } else { - - // signed ID token - - if (signingAlg.equals(JWSAlgorithm.HS256) - || signingAlg.equals(JWSAlgorithm.HS384) - || signingAlg.equals(JWSAlgorithm.HS512)) { - - JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, - jwtService.getDefaultSignerKeyId(), - null, null); - idToken = new SignedJWT(header, idClaims.build()); - - JWTSigningAndValidationService signer = symmetricCacheService.getSymmetricValidtor(client); - - // sign it with the client's secret - signer.signJwt((SignedJWT) idToken); - } else { - idClaims.claim("kid", jwtService.getDefaultSignerKeyId()); - - JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, - jwtService.getDefaultSignerKeyId(), - null, null); - - idToken = new SignedJWT(header, idClaims.build()); - - // sign it with the server's key - jwtService.signJwt((SignedJWT) idToken); - } - } - - } - - return idToken; - } - - /** - * @param client - * @return - * @throws AuthenticationException - */ - @Override - public OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) { - - return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.REGISTRATION_TOKEN_SCOPE)); - - } - - /** - * @param client - * @return - */ - @Override - public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client) { - - return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.RESOURCE_TOKEN_SCOPE)); - - } - - @Override - public OAuth2AccessTokenEntity rotateRegistrationAccessTokenForClient(ClientDetailsEntity client) { - // revoke any previous tokens - OAuth2AccessTokenEntity oldToken = tokenService.getRegistrationAccessTokenForClient(client); - if (oldToken != null) { - Set scope = oldToken.getScope(); - tokenService.revokeAccessToken(oldToken); - return createAssociatedToken(client, scope); - } else { - return null; - } - - } - - private OAuth2AccessTokenEntity createAssociatedToken(ClientDetailsEntity client, Set scope) { - - // revoke any previous tokens that might exist, just to be sure - OAuth2AccessTokenEntity oldToken = tokenService.getRegistrationAccessTokenForClient(client); - if (oldToken != null) { - tokenService.revokeAccessToken(oldToken); - } - - // create a new token - - Map authorizationParameters = Maps.newHashMap(); - OAuth2Request clientAuth = new OAuth2Request(authorizationParameters, client.getClientId(), - Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true, - scope, null, null, null, null); - OAuth2Authentication authentication = new OAuth2Authentication(clientAuth, null); - - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - token.setClient(client); - token.setScope(scope); - - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setAuthentication(authentication); - authHolder = authenticationHolderRepository.save(authHolder); - token.setAuthenticationHolder(authHolder); - - JWTClaimsSet claims = new JWTClaimsSet.Builder() - .audience(Lists.newArrayList(client.getClientId())) - .issuer(configBean.getIssuer()) - .issueTime(new Date()) - .expirationTime(token.getExpiration()) - .jwtID(UUID.randomUUID().toString()) // set a random NONCE in the middle of it - .build(); - - JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); - JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, - jwtService.getDefaultSignerKeyId(), - null, null); - SignedJWT signed = new SignedJWT(header, claims); - - jwtService.signJwt(signed); - - token.setJwt(signed); - - return token; - } - - /** - * @return the configBean - */ - public ConfigurationPropertiesBean getConfigBean() { - return configBean; - } - - /** - * @param configBean the configBean to set - */ - public void setConfigBean(ConfigurationPropertiesBean configBean) { - this.configBean = configBean; - } - - /** - * @return the jwtService - */ - public JWTSigningAndValidationService getJwtService() { - return jwtService; - } - - /** - * @param jwtService the jwtService to set - */ - public void setJwtService(JWTSigningAndValidationService jwtService) { - this.jwtService = jwtService; - } - - /** - * @return the authenticationHolderRepository - */ - public AuthenticationHolderRepository getAuthenticationHolderRepository() { - return authenticationHolderRepository; - } - - /** - * @param authenticationHolderRepository the authenticationHolderRepository to set - */ - public void setAuthenticationHolderRepository( - AuthenticationHolderRepository authenticationHolderRepository) { - this.authenticationHolderRepository = authenticationHolderRepository; - } - - /** - * Hook for subclasses that allows adding custom claims to the JWT - * that will be used as id token. - * @param idClaims the builder holding the current claims - * @param client information about the requesting client - * @param request request that caused the id token to be created - * @param sub subject auf the id token - * @param accessToken the access token - * @param authentication current authentication - */ - protected void addCustomIdTokenClaims(JWTClaimsSet.Builder idClaims, ClientDetailsEntity client, OAuth2Request request, - String sub, OAuth2AccessTokenEntity accessToken) { - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultScopeClaimTranslationService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultScopeClaimTranslationService.java deleted file mode 100644 index 5c0637a5e2..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultScopeClaimTranslationService.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import java.util.HashSet; -import java.util.Set; - -import org.mitre.openid.connect.service.ScopeClaimTranslationService; -import org.springframework.stereotype.Service; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; - -/** - * Service to map scopes to claims, and claims to Java field names - * - * @author Amanda Anganes - * - */ -@Service("scopeClaimTranslator") -public class DefaultScopeClaimTranslationService implements ScopeClaimTranslationService { - - private SetMultimap scopesToClaims = HashMultimap.create(); - - /** - * Default constructor; initializes scopesToClaims map - */ - public DefaultScopeClaimTranslationService() { - scopesToClaims.put("openid", "sub"); - - scopesToClaims.put("profile", "name"); - scopesToClaims.put("profile", "preferred_username"); - scopesToClaims.put("profile", "given_name"); - scopesToClaims.put("profile", "family_name"); - scopesToClaims.put("profile", "middle_name"); - scopesToClaims.put("profile", "nickname"); - scopesToClaims.put("profile", "profile"); - scopesToClaims.put("profile", "picture"); - scopesToClaims.put("profile", "website"); - scopesToClaims.put("profile", "gender"); - scopesToClaims.put("profile", "zoneinfo"); - scopesToClaims.put("profile", "locale"); - scopesToClaims.put("profile", "updated_at"); - scopesToClaims.put("profile", "birthdate"); - - scopesToClaims.put("email", "email"); - scopesToClaims.put("email", "email_verified"); - - scopesToClaims.put("phone", "phone_number"); - scopesToClaims.put("phone", "phone_number_verified"); - - scopesToClaims.put("address", "address"); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.ScopeClaimTranslationService#getClaimsForScope(java.lang.String) - */ - @Override - public Set getClaimsForScope(String scope) { - if (scopesToClaims.containsKey(scope)) { - return scopesToClaims.get(scope); - } else { - return new HashSet<>(); - } - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.ScopeClaimTranslationService#getClaimsForScopeSet(java.util.Set) - */ - @Override - public Set getClaimsForScopeSet(Set scopes) { - Set result = new HashSet<>(); - for (String scope : scopes) { - result.addAll(getClaimsForScope(scope)); - } - return result; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java deleted file mode 100644 index ce830d6492..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultUserInfoService.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.repository.UserInfoRepository; -import org.mitre.openid.connect.service.PairwiseIdentiferService; -import org.mitre.openid.connect.service.UserInfoService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * Implementation of the UserInfoService - * - * @author Michael Joseph Walsh, jricher - * - */ -@Service -public class DefaultUserInfoService implements UserInfoService { - - @Autowired - private UserInfoRepository userInfoRepository; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private PairwiseIdentiferService pairwiseIdentifierService; - - @Override - public UserInfo getByUsername(String username) { - return userInfoRepository.getByUsername(username); - } - - @Override - public UserInfo getByUsernameAndClientId(String username, String clientId) { - - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - UserInfo userInfo = getByUsername(username); - - if (client == null || userInfo == null) { - return null; - } - - if (SubjectType.PAIRWISE.equals(client.getSubjectType())) { - String pairwiseSub = pairwiseIdentifierService.getIdentifier(userInfo, client); - userInfo.setSub(pairwiseSub); - } - - return userInfo; - - } - - @Override - public UserInfo getByEmailAddress(String email) { - return userInfoRepository.getByEmailAddress(email); - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DummyResourceSetService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DummyResourceSetService.java deleted file mode 100644 index ad60243c10..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DummyResourceSetService.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import java.util.Collection; -import java.util.Collections; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ResourceSetService; -import org.springframework.stereotype.Service; - -/** - * Dummy resource set service that doesn't do anything; acts as a stub for the - * introspection service when the UMA functionality is disabled. - * - * @author jricher - * - */ -@Service -public class DummyResourceSetService implements ResourceSetService { - - @Override - public ResourceSet saveNew(ResourceSet rs) { - throw new UnsupportedOperationException(); - } - - @Override - public ResourceSet getById(Long id) { - throw new UnsupportedOperationException(); - } - - @Override - public ResourceSet update(ResourceSet oldRs, ResourceSet newRs) { - throw new UnsupportedOperationException(); - } - - @Override - public void remove(ResourceSet rs) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection getAllForOwner(String owner) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection getAllForOwnerAndClient(String owner, String authClientId) { - return Collections.emptySet(); - } - - @Override - public Collection getAllForClient(ClientDetailsEntity client) { - return Collections.emptySet(); - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java deleted file mode 100644 index 57c3257726..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_0.java +++ /dev/null @@ -1,906 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import static org.mitre.util.JsonUtils.readMap; -import static org.mitre.util.JsonUtils.readSet; - -import java.io.IOException; -import java.text.ParseException; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AppType; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SavedUserAuthentication; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mitre.openid.connect.service.MITREidDataServiceExtension; -import org.mitre.openid.connect.service.MITREidDataServiceMaps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.stereotype.Service; - -import com.google.common.collect.Sets; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jwt.JWTParser; -/** - * - * Data service to import MITREid 1.0 configuration. - * - * @author jricher - * @author arielak - */ -@Service -@SuppressWarnings(value = {"unchecked"}) -public class MITREidDataService_1_0 extends MITREidDataServiceSupport implements MITREidDataService { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_0.class); - @Autowired - private OAuth2ClientRepository clientRepository; - @Autowired - private ApprovedSiteRepository approvedSiteRepository; - @Autowired - private WhitelistedSiteRepository wlSiteRepository; - @Autowired - private BlacklistedSiteRepository blSiteRepository; - @Autowired - private AuthenticationHolderRepository authHolderRepository; - @Autowired - private OAuth2TokenRepository tokenRepository; - @Autowired - private SystemScopeRepository sysScopeRepository; - @Autowired(required = false) - private List extensions = Collections.emptyList(); - - private MITREidDataServiceMaps maps = new MITREidDataServiceMaps(); - - private static final String THIS_VERSION = MITREID_CONNECT_1_0; - - @Override - public boolean supportsVersion(String version) { - return THIS_VERSION.equals(version); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter) - */ - - @Override - public void exportData(JsonWriter writer) throws IOException { - throw new UnsupportedOperationException("Can not export 1.0 format from this version."); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader) - */ - @Override - public void importData(JsonReader reader) throws IOException { - - logger.info("Reading configuration for 1.0"); - - // this *HAS* to start as an object - reader.beginObject(); - - while (reader.hasNext()) { - JsonToken tok = reader.peek(); - switch (tok) { - case NAME: - String name = reader.nextName(); - // find out which member it is - if (name.equals(CLIENTS)) { - readClients(reader); - } else if (name.equals(GRANTS)) { - readGrants(reader); - } else if (name.equals(WHITELISTEDSITES)) { - readWhitelistedSites(reader); - } else if (name.equals(BLACKLISTEDSITES)) { - readBlacklistedSites(reader); - } else if (name.equals(AUTHENTICATIONHOLDERS)) { - readAuthenticationHolders(reader); - } else if (name.equals(ACCESSTOKENS)) { - readAccessTokens(reader); - } else if (name.equals(REFRESHTOKENS)) { - readRefreshTokens(reader); - } else if (name.equals(SYSTEMSCOPES)) { - readSystemScopes(reader); - } else { - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.importExtensionData(name, reader); - break; - } - } - } - // unknown token, skip it - reader.skipValue(); - } - break; - case END_OBJECT: - // the object ended, we're done here - reader.endObject(); - continue; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; } - } - fixObjectReferences(); - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.fixExtensionObjectReferences(maps); - break; - } - } - maps.clearAll(); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readRefreshTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("expiration")) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals("value")) { - String value = reader.nextString(); - try { - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals("clientId")) { - clientId = reader.nextString(); - } else if (name.equals("authenticationHolderId")) { - authHolderId = reader.nextLong(); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveRefreshToken(token).getId(); - maps.getRefreshTokenToClientRefs().put(currentId, clientId); - maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId); - maps.getRefreshTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read refresh token {}", currentId); - } - reader.endArray(); - logger.info("Done reading refresh tokens"); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readAccessTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - Long refreshTokenId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("expiration")) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals("value")) { - String value = reader.nextString(); - try { - // all tokens are JWTs - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals("clientId")) { - clientId = reader.nextString(); - } else if (name.equals("authenticationHolderId")) { - authHolderId = reader.nextLong(); - } else if (name.equals("refreshTokenId")) { - refreshTokenId = reader.nextLong(); - } else if (name.equals("scope")) { - Set scope = readSet(reader); - token.setScope(scope); - } else if (name.equals("type")) { - token.setTokenType(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveAccessToken(token).getId(); - maps.getAccessTokenToClientRefs().put(currentId, clientId); - maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId); - if (refreshTokenId != null) { - maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId); - } - maps.getAccessTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read access token {}", currentId); - } - reader.endArray(); - logger.info("Done reading access tokens"); - } - /** - * @param reader - * @throws IOException - */ - private void readAuthenticationHolders(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - AuthenticationHolderEntity ahe = new AuthenticationHolderEntity(); - reader.beginObject(); - Long currentId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("ownerId")) { - //not needed - reader.skipValue(); - } else if (name.equals("authentication")) { - OAuth2Request clientAuthorization = null; - Authentication userAuthentication = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String subName = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (subName.equals("clientAuthorization")) { - clientAuthorization = readAuthorizationRequest(reader); - } else if (subName.equals("userAuthentication")) { - // skip binary encoded version - reader.skipValue(); - - } else if (subName.equals("savedUserAuthentication")) { - userAuthentication = readSavedUserAuthentication(reader); - - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - OAuth2Authentication auth = new OAuth2Authentication(clientAuthorization, userAuthentication); - ahe.setAuthentication(auth); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = authHolderRepository.save(ahe).getId(); - maps.getAuthHolderOldToNewIdMap().put(currentId, newId); - logger.debug("Read authentication holder {}", currentId); - } - reader.endArray(); - logger.info("Done reading authentication holders"); - } - - //used by readAuthenticationHolders - private OAuth2Request readAuthorizationRequest(JsonReader reader) throws IOException { - Set scope = new LinkedHashSet<>(); - Set resourceIds = new HashSet<>(); - boolean approved = false; - Collection authorities = new HashSet<>(); - Map authorizationParameters = new HashMap<>(); - Set responseTypes = new HashSet<>(); - String redirectUri = null; - String clientId = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("authorizationParameters")) { - authorizationParameters = readMap(reader); - } else if (name.equals("approvalParameters")) { - reader.skipValue(); - } else if (name.equals("clientId")) { - clientId = reader.nextString(); - } else if (name.equals("scope")) { - scope = readSet(reader); - } else if (name.equals("resourceIds")) { - resourceIds = readSet(reader); - } else if (name.equals("authorities")) { - Set authorityStrs = readSet(reader); - authorities = new HashSet<>(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - } else if (name.equals("approved")) { - approved = reader.nextBoolean(); - } else if (name.equals("denied")) { - if (approved == false) { - approved = !reader.nextBoolean(); - } - } else if (name.equals("redirectUri")) { - redirectUri = reader.nextString(); - } else if (name.equals("responseTypes")) { - responseTypes = readSet(reader); - } else { - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - return new OAuth2Request(authorizationParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, null); - } - - /** - * @param reader - * @return - * @throws IOException - */ - private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException { - SavedUserAuthentication savedUserAuth = new SavedUserAuthentication(); - reader.beginObject(); - - while (reader.hasNext()) { - switch(reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("name")) { - savedUserAuth.setName(reader.nextString()); - } else if (name.equals("sourceClass")) { - savedUserAuth.setSourceClass(reader.nextString()); - } else if (name.equals("authenticated")) { - savedUserAuth.setAuthenticated(reader.nextBoolean()); - } else if (name.equals("authorities")) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - savedUserAuth.setAuthorities(authorities); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - - reader.endObject(); - return savedUserAuth; - } - - /** - * @param reader - * @throws IOException - */ - private void readGrants(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ApprovedSite site = new ApprovedSite(); - Long currentId = null; - Long whitelistedSiteId = null; - Set tokenIds = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("accessDate")) { - Date date = utcToDate(reader.nextString()); - site.setAccessDate(date); - } else if (name.equals("clientId")) { - site.setClientId(reader.nextString()); - } else if (name.equals("creationDate")) { - Date date = utcToDate(reader.nextString()); - site.setCreationDate(date); - } else if (name.equals("timeoutDate")) { - Date date = utcToDate(reader.nextString()); - site.setTimeoutDate(date); - } else if (name.equals("userId")) { - site.setUserId(reader.nextString()); - } else if (name.equals("allowedScopes")) { - Set allowedScopes = readSet(reader); - site.setAllowedScopes(allowedScopes); - } else if (name.equals("whitelistedSiteId")) { - whitelistedSiteId = reader.nextLong(); - } else if (name.equals("approvedAccessTokens")) { - tokenIds = readSet(reader); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = approvedSiteRepository.save(site).getId(); - maps.getGrantOldToNewIdMap().put(currentId, newId); - if (whitelistedSiteId != null) { - logger.debug("Ignoring whitelisted site marker on approved site."); - } - if (tokenIds != null) { - maps.getGrantToAccessTokensRefs().put(currentId, tokenIds); - } - logger.debug("Read grant {}", currentId); - } - reader.endArray(); - logger.info("Done reading grants"); - } - /** - * @param reader - * @throws IOException - */ - private void readWhitelistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - WhitelistedSite wlSite = new WhitelistedSite(); - Long currentId = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("clientId")) { - wlSite.setClientId(reader.nextString()); - } else if (name.equals("creatorUserId")) { - wlSite.setCreatorUserId(reader.nextString()); - } else if (name.equals("allowedScopes")) { - Set allowedScopes = readSet(reader); - wlSite.setAllowedScopes(allowedScopes); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = wlSiteRepository.save(wlSite).getId(); - maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId); - } - reader.endArray(); - logger.info("Done reading whitelisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readBlacklistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - BlacklistedSite blSite = new BlacklistedSite(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals("id")) { - reader.skipValue(); - } else if (name.equals("uri")) { - blSite.setUri(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - blSiteRepository.save(blSite); - } - reader.endArray(); - logger.info("Done reading blacklisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readClients(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ClientDetailsEntity client = new ClientDetailsEntity(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("clientId")) { - client.setClientId(reader.nextString()); - } else if (name.equals("resourceIds")) { - Set resourceIds = readSet(reader); - client.setResourceIds(resourceIds); - } else if (name.equals("secret")) { - client.setClientSecret(reader.nextString()); - } else if (name.equals("scope")) { - Set scope = readSet(reader); - client.setScope(scope); - } else if (name.equals("authorities")) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet<>(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - client.setAuthorities(authorities); - } else if (name.equals("accessTokenValiditySeconds")) { - client.setAccessTokenValiditySeconds(reader.nextInt()); - } else if (name.equals("refreshTokenValiditySeconds")) { - client.setRefreshTokenValiditySeconds(reader.nextInt()); - } else if (name.equals("redirectUris")) { - Set redirectUris = readSet(reader); - client.setRedirectUris(redirectUris); - } else if (name.equals("name")) { - client.setClientName(reader.nextString()); - } else if (name.equals("uri")) { - client.setClientUri(reader.nextString()); - } else if (name.equals("logoUri")) { - client.setLogoUri(reader.nextString()); - } else if (name.equals("contacts")) { - Set contacts = readSet(reader); - client.setContacts(contacts); - } else if (name.equals("tosUri")) { - client.setTosUri(reader.nextString()); - } else if (name.equals("tokenEndpointAuthMethod")) { - AuthMethod am = AuthMethod.getByValue(reader.nextString()); - client.setTokenEndpointAuthMethod(am); - } else if (name.equals("grantTypes")) { - Set grantTypes = readSet(reader); - client.setGrantTypes(grantTypes); - } else if (name.equals("responseTypes")) { - Set responseTypes = readSet(reader); - client.setResponseTypes(responseTypes); - } else if (name.equals("policyUri")) { - client.setPolicyUri(reader.nextString()); - } else if (name.equals("applicationType")) { - AppType appType = AppType.getByValue(reader.nextString()); - client.setApplicationType(appType); - } else if (name.equals("sectorIdentifierUri")) { - client.setSectorIdentifierUri(reader.nextString()); - } else if (name.equals("subjectType")) { - SubjectType st = SubjectType.getByValue(reader.nextString()); - client.setSubjectType(st); - } else if (name.equals("jwks_uri")) { - client.setJwksUri(reader.nextString()); - } else if (name.equals("requestObjectSigningAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setRequestObjectSigningAlg(alg); - } else if (name.equals("userInfoEncryptedResponseAlg")) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setUserInfoEncryptedResponseAlg(alg); - } else if (name.equals("userInfoEncryptedResponseEnc")) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setUserInfoEncryptedResponseEnc(alg); - } else if (name.equals("userInfoSignedResponseAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setUserInfoSignedResponseAlg(alg); - } else if (name.equals("idTokenSignedResonseAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setIdTokenSignedResponseAlg(alg); - } else if (name.equals("idTokenEncryptedResponseAlg")) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setIdTokenEncryptedResponseAlg(alg); - } else if (name.equals("idTokenEncryptedResponseEnc")) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setIdTokenEncryptedResponseEnc(alg); - } else if (name.equals("tokenEndpointAuthSigningAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setTokenEndpointAuthSigningAlg(alg); - } else if (name.equals("defaultMaxAge")) { - client.setDefaultMaxAge(reader.nextInt()); - } else if (name.equals("requireAuthTime")) { - client.setRequireAuthTime(reader.nextBoolean()); - } else if (name.equals("defaultACRValues")) { - Set defaultACRvalues = readSet(reader); - client.setDefaultACRvalues(defaultACRvalues); - } else if (name.equals("initiateLoginUri")) { - client.setInitiateLoginUri(reader.nextString()); - } else if (name.equals("postLogoutRedirectUri")) { - HashSet postLogoutUris = Sets.newHashSet(reader.nextString()); - client.setPostLogoutRedirectUris(postLogoutUris); - } else if (name.equals("requestUris")) { - Set requestUris = readSet(reader); - client.setRequestUris(requestUris); - } else if (name.equals("description")) { - client.setClientDescription(reader.nextString()); - } else if (name.equals("allowIntrospection")) { - client.setAllowIntrospection(reader.nextBoolean()); - } else if (name.equals("reuseRefreshToken")) { - client.setReuseRefreshToken(reader.nextBoolean()); - } else if (name.equals("dynamicallyRegistered")) { - client.setDynamicallyRegistered(reader.nextBoolean()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - clientRepository.saveClient(client); - } - reader.endArray(); - logger.info("Done reading clients"); - } - - /** - * Read the list of system scopes from the reader and insert them into the - * scope repository. - * - * @param reader - * @throws IOException - */ - private void readSystemScopes(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - SystemScope scope = new SystemScope(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("value")) { - scope.setValue(reader.nextString()); - } else if (name.equals("description")) { - scope.setDescription(reader.nextString()); - } else if (name.equals("allowDynReg")) { - // previously "allowDynReg" scopes are now tagged as "not restricted" and vice versa - scope.setRestricted(!reader.nextBoolean()); - } else if (name.equals("defaultScope")) { - scope.setDefaultScope(reader.nextBoolean()); - } else if (name.equals("icon")) { - scope.setIcon(reader.nextString()); - } else { - logger.debug("found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - sysScopeRepository.save(scope); - } - reader.endArray(); - logger.info("Done reading system scopes"); - } - - private void fixObjectReferences() { - for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) { - String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setClient(client); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setAuthenticationHolder(authHolder); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) { - String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setClient(client); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setAuthenticationHolder(authHolder); - tokenRepository.saveAccessToken(accessToken); - } - maps.getAccessTokenToAuthHolderRefs().clear(); - for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) { - Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setRefreshToken(refreshToken); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) { - Set oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId); - - Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId); - ApprovedSite site = approvedSiteRepository.getById(newGrantId); - - for(Long oldTokenId : oldAccessTokenIds) { - Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId); - OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId); - token.setApprovedSite(site); - tokenRepository.saveAccessToken(token); - } - - approvedSiteRepository.save(site); - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java deleted file mode 100644 index 38287ee633..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java +++ /dev/null @@ -1,920 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import static org.mitre.util.JsonUtils.readMap; -import static org.mitre.util.JsonUtils.readSet; - -import java.io.IOException; -import java.io.Serializable; -import java.text.ParseException; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AppType; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SavedUserAuthentication; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mitre.openid.connect.service.MITREidDataServiceExtension; -import org.mitre.openid.connect.service.MITREidDataServiceMaps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.stereotype.Service; - -import com.google.common.collect.Sets; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jwt.JWTParser; - -/** - * - * Data service to import MITREid 1.1 configuration. - * - * @author jricher - * @author arielak - */ -@Service -@SuppressWarnings(value = {"unchecked"}) -public class MITREidDataService_1_1 extends MITREidDataServiceSupport implements MITREidDataService { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_1.class); - @Autowired - private OAuth2ClientRepository clientRepository; - @Autowired - private ApprovedSiteRepository approvedSiteRepository; - @Autowired - private WhitelistedSiteRepository wlSiteRepository; - @Autowired - private BlacklistedSiteRepository blSiteRepository; - @Autowired - private AuthenticationHolderRepository authHolderRepository; - @Autowired - private OAuth2TokenRepository tokenRepository; - @Autowired - private SystemScopeRepository sysScopeRepository; - @Autowired(required = false) - private List extensions = Collections.emptyList(); - - private static final String THIS_VERSION = MITREID_CONNECT_1_1; - - private MITREidDataServiceMaps maps = new MITREidDataServiceMaps(); - - @Override - public boolean supportsVersion(String version) { - return THIS_VERSION.equals(version); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter) - */ - @Override - public void exportData(JsonWriter writer) throws IOException { - throw new UnsupportedOperationException("Can not export 1.1 format from this version."); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader) - */ - @Override - public void importData(JsonReader reader) throws IOException { - - logger.info("Reading configuration for 1.1"); - - // this *HAS* to start as an object - reader.beginObject(); - - while (reader.hasNext()) { - JsonToken tok = reader.peek(); - switch (tok) { - case NAME: - String name = reader.nextName(); - // find out which member it is - if (name.equals(CLIENTS)) { - readClients(reader); - } else if (name.equals(GRANTS)) { - readGrants(reader); - } else if (name.equals(WHITELISTEDSITES)) { - readWhitelistedSites(reader); - } else if (name.equals(BLACKLISTEDSITES)) { - readBlacklistedSites(reader); - } else if (name.equals(AUTHENTICATIONHOLDERS)) { - readAuthenticationHolders(reader); - } else if (name.equals(ACCESSTOKENS)) { - readAccessTokens(reader); - } else if (name.equals(REFRESHTOKENS)) { - readRefreshTokens(reader); - } else if (name.equals(SYSTEMSCOPES)) { - readSystemScopes(reader); - } else { - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.importExtensionData(name, reader); - break; - } - } - } - // unknown token, skip it - reader.skipValue(); - } - break; - case END_OBJECT: - // the object ended, we're done here - reader.endObject(); - continue; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - fixObjectReferences(); - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.fixExtensionObjectReferences(maps); - break; - } - } - maps.clearAll(); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readRefreshTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("expiration")) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals("value")) { - String value = reader.nextString(); - try { - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals("clientId")) { - clientId = reader.nextString(); - } else if (name.equals("authenticationHolderId")) { - authHolderId = reader.nextLong(); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveRefreshToken(token).getId(); - maps.getRefreshTokenToClientRefs().put(currentId, clientId); - maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId); - maps.getRefreshTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read refresh token {}", currentId); - } - reader.endArray(); - logger.info("Done reading refresh tokens"); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readAccessTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - Long refreshTokenId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("expiration")) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals("value")) { - String value = reader.nextString(); - try { - // all tokens are JWTs - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals("clientId")) { - clientId = reader.nextString(); - } else if (name.equals("authenticationHolderId")) { - authHolderId = reader.nextLong(); - } else if (name.equals("refreshTokenId")) { - refreshTokenId = reader.nextLong(); - } else if (name.equals("scope")) { - Set scope = readSet(reader); - token.setScope(scope); - } else if (name.equals("type")) { - token.setTokenType(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveAccessToken(token).getId(); - maps.getAccessTokenToClientRefs().put(currentId, clientId); - maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId); - if (refreshTokenId != null) { - maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId); - } - maps.getAccessTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read access token {}", currentId); - } - reader.endArray(); - logger.info("Done reading access tokens"); - } - /** - * @param reader - * @throws IOException - */ - private void readAuthenticationHolders(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - AuthenticationHolderEntity ahe = new AuthenticationHolderEntity(); - reader.beginObject(); - Long currentId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("ownerId")) { - //not needed - reader.skipValue(); - } else if (name.equals("authentication")) { - OAuth2Request clientAuthorization = null; - Authentication userAuthentication = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String subName = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); // skip null values - } else if (subName.equals("clientAuthorization")) { - clientAuthorization = readAuthorizationRequest(reader); - } else if (subName.equals("userAuthentication")) { - // skip binary encoded version - reader.skipValue(); - - } else if (subName.equals("savedUserAuthentication")) { - userAuthentication = readSavedUserAuthentication(reader); - - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - OAuth2Authentication auth = new OAuth2Authentication(clientAuthorization, userAuthentication); - ahe.setAuthentication(auth); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = authHolderRepository.save(ahe).getId(); - maps.getAuthHolderOldToNewIdMap().put(currentId, newId); - logger.debug("Read authentication holder {}", currentId); - } - reader.endArray(); - logger.info("Done reading authentication holders"); - } - - //used by readAuthenticationHolders - private OAuth2Request readAuthorizationRequest(JsonReader reader) throws IOException { - Set scope = new LinkedHashSet<>(); - Set resourceIds = new HashSet<>(); - boolean approved = false; - Collection authorities = new HashSet<>(); - Map requestParameters = new HashMap<>(); - Set responseTypes = new HashSet<>(); - Map extensions = new HashMap<>(); - String redirectUri = null; - String clientId = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("requestParameters")) { - requestParameters = readMap(reader); - } else if (name.equals("clientId")) { - clientId = reader.nextString(); - } else if (name.equals("scope")) { - scope = readSet(reader); - } else if (name.equals("resourceIds")) { - resourceIds = readSet(reader); - } else if (name.equals("authorities")) { - Set authorityStrs = readSet(reader); - authorities = new HashSet<>(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - } else if (name.equals("approved")) { - approved = reader.nextBoolean(); - } else if (name.equals("denied")) { - if (approved == false) { - approved = !reader.nextBoolean(); - } - } else if (name.equals("redirectUri")) { - redirectUri = reader.nextString(); - } else if (name.equals("responseTypes")) { - responseTypes = readSet(reader); - } else if (name.equals("extensions")) { - // skip the binary encoded version - reader.skipValue(); - } else if (name.equals("extensionStrings")) { - Map extEnc = readMap(reader); - for (Entry entry : extEnc.entrySet()) { - extensions.put(entry.getKey(), entry.getValue()); - } - } else { - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - return new OAuth2Request(requestParameters, clientId, authorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions); - } - - /** - * @param reader - * @return - * @throws IOException - */ - private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException { - SavedUserAuthentication savedUserAuth = new SavedUserAuthentication(); - reader.beginObject(); - - while (reader.hasNext()) { - switch(reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("name")) { - savedUserAuth.setName(reader.nextString()); - } else if (name.equals("sourceClass")) { - savedUserAuth.setSourceClass(reader.nextString()); - } else if (name.equals("authenticated")) { - savedUserAuth.setAuthenticated(reader.nextBoolean()); - } else if (name.equals("authorities")) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - savedUserAuth.setAuthorities(authorities); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - - reader.endObject(); - return savedUserAuth; - } - - /** - * @param reader - * @throws IOException - */ - private void readGrants(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ApprovedSite site = new ApprovedSite(); - Long currentId = null; - Long whitelistedSiteId = null; - Set tokenIds = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("accessDate")) { - Date date = utcToDate(reader.nextString()); - site.setAccessDate(date); - } else if (name.equals("clientId")) { - site.setClientId(reader.nextString()); - } else if (name.equals("creationDate")) { - Date date = utcToDate(reader.nextString()); - site.setCreationDate(date); - } else if (name.equals("timeoutDate")) { - Date date = utcToDate(reader.nextString()); - site.setTimeoutDate(date); - } else if (name.equals("userId")) { - site.setUserId(reader.nextString()); - } else if (name.equals("allowedScopes")) { - Set allowedScopes = readSet(reader); - site.setAllowedScopes(allowedScopes); - } else if (name.equals("whitelistedSiteId")) { - whitelistedSiteId = reader.nextLong(); - } else if (name.equals("approvedAccessTokens")) { - tokenIds = readSet(reader); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = approvedSiteRepository.save(site).getId(); - maps.getGrantOldToNewIdMap().put(currentId, newId); - if (whitelistedSiteId != null) { - logger.debug("Ignoring whitelisted site marker on approved site."); - } - if (tokenIds != null) { - maps.getGrantToAccessTokensRefs().put(currentId, tokenIds); - } - logger.debug("Read grant {}", currentId); - } - reader.endArray(); - logger.info("Done reading grants"); - } - /** - * @param reader - * @throws IOException - */ - private void readWhitelistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - WhitelistedSite wlSite = new WhitelistedSite(); - Long currentId = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals("id")) { - currentId = reader.nextLong(); - } else if (name.equals("clientId")) { - wlSite.setClientId(reader.nextString()); - } else if (name.equals("creatorUserId")) { - wlSite.setCreatorUserId(reader.nextString()); - } else if (name.equals("allowedScopes")) { - Set allowedScopes = readSet(reader); - wlSite.setAllowedScopes(allowedScopes); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = wlSiteRepository.save(wlSite).getId(); - maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId); - } - reader.endArray(); - logger.info("Done reading whitelisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readBlacklistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - BlacklistedSite blSite = new BlacklistedSite(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals("id")) { - reader.skipValue(); - } else if (name.equals("uri")) { - blSite.setUri(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - blSiteRepository.save(blSite); - } - reader.endArray(); - logger.info("Done reading blacklisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readClients(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ClientDetailsEntity client = new ClientDetailsEntity(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("clientId")) { - client.setClientId(reader.nextString()); - } else if (name.equals("resourceIds")) { - Set resourceIds = readSet(reader); - client.setResourceIds(resourceIds); - } else if (name.equals("secret")) { - client.setClientSecret(reader.nextString()); - } else if (name.equals("scope")) { - Set scope = readSet(reader); - client.setScope(scope); - } else if (name.equals("authorities")) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet<>(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - client.setAuthorities(authorities); - } else if (name.equals("accessTokenValiditySeconds")) { - client.setAccessTokenValiditySeconds(reader.nextInt()); - } else if (name.equals("refreshTokenValiditySeconds")) { - client.setRefreshTokenValiditySeconds(reader.nextInt()); - } else if (name.equals("redirectUris")) { - Set redirectUris = readSet(reader); - client.setRedirectUris(redirectUris); - } else if (name.equals("name")) { - client.setClientName(reader.nextString()); - } else if (name.equals("uri")) { - client.setClientUri(reader.nextString()); - } else if (name.equals("logoUri")) { - client.setLogoUri(reader.nextString()); - } else if (name.equals("contacts")) { - Set contacts = readSet(reader); - client.setContacts(contacts); - } else if (name.equals("tosUri")) { - client.setTosUri(reader.nextString()); - } else if (name.equals("tokenEndpointAuthMethod")) { - AuthMethod am = AuthMethod.getByValue(reader.nextString()); - client.setTokenEndpointAuthMethod(am); - } else if (name.equals("grantTypes")) { - Set grantTypes = readSet(reader); - client.setGrantTypes(grantTypes); - } else if (name.equals("responseTypes")) { - Set responseTypes = readSet(reader); - client.setResponseTypes(responseTypes); - } else if (name.equals("policyUri")) { - client.setPolicyUri(reader.nextString()); - } else if (name.equals("applicationType")) { - AppType appType = AppType.getByValue(reader.nextString()); - client.setApplicationType(appType); - } else if (name.equals("sectorIdentifierUri")) { - client.setSectorIdentifierUri(reader.nextString()); - } else if (name.equals("subjectType")) { - SubjectType st = SubjectType.getByValue(reader.nextString()); - client.setSubjectType(st); - } else if (name.equals("jwks_uri")) { - client.setJwksUri(reader.nextString()); - } else if (name.equals("requestObjectSigningAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setRequestObjectSigningAlg(alg); - } else if (name.equals("userInfoEncryptedResponseAlg")) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setUserInfoEncryptedResponseAlg(alg); - } else if (name.equals("userInfoEncryptedResponseEnc")) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setUserInfoEncryptedResponseEnc(alg); - } else if (name.equals("userInfoSignedResponseAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setUserInfoSignedResponseAlg(alg); - } else if (name.equals("idTokenSignedResonseAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setIdTokenSignedResponseAlg(alg); - } else if (name.equals("idTokenEncryptedResponseAlg")) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setIdTokenEncryptedResponseAlg(alg); - } else if (name.equals("idTokenEncryptedResponseEnc")) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setIdTokenEncryptedResponseEnc(alg); - } else if (name.equals("tokenEndpointAuthSigningAlg")) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setTokenEndpointAuthSigningAlg(alg); - } else if (name.equals("defaultMaxAge")) { - client.setDefaultMaxAge(reader.nextInt()); - } else if (name.equals("requireAuthTime")) { - client.setRequireAuthTime(reader.nextBoolean()); - } else if (name.equals("defaultACRValues")) { - Set defaultACRvalues = readSet(reader); - client.setDefaultACRvalues(defaultACRvalues); - } else if (name.equals("initiateLoginUri")) { - client.setInitiateLoginUri(reader.nextString()); - } else if (name.equals("postLogoutRedirectUri")) { - HashSet postLogoutUris = Sets.newHashSet(reader.nextString()); - client.setPostLogoutRedirectUris(postLogoutUris); - } else if (name.equals("requestUris")) { - Set requestUris = readSet(reader); - client.setRequestUris(requestUris); - } else if (name.equals("description")) { - client.setClientDescription(reader.nextString()); - } else if (name.equals("allowIntrospection")) { - client.setAllowIntrospection(reader.nextBoolean()); - } else if (name.equals("reuseRefreshToken")) { - client.setReuseRefreshToken(reader.nextBoolean()); - } else if (name.equals("dynamicallyRegistered")) { - client.setDynamicallyRegistered(reader.nextBoolean()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - clientRepository.saveClient(client); - } - reader.endArray(); - logger.info("Done reading clients"); - } - - /** - * Read the list of system scopes from the reader and insert them into the - * scope repository. - * - * @param reader - * @throws IOException - */ - private void readSystemScopes(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - SystemScope scope = new SystemScope(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals("value")) { - scope.setValue(reader.nextString()); - } else if (name.equals("description")) { - scope.setDescription(reader.nextString()); - } else if (name.equals("allowDynReg")) { - // previously "allowDynReg" scopes are now tagged as "not restricted" and vice versa - scope.setRestricted(!reader.nextBoolean()); - } else if (name.equals("defaultScope")) { - scope.setDefaultScope(reader.nextBoolean()); - } else if (name.equals("structured")) { - logger.warn("Found a structured scope, ignoring structure"); - } else if (name.equals("structuredParameter")) { - logger.warn("Found a structured scope, ignoring structure"); - } else if (name.equals("icon")) { - scope.setIcon(reader.nextString()); - } else { - logger.debug("found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - sysScopeRepository.save(scope); - } - reader.endArray(); - logger.info("Done reading system scopes"); - } - - private void fixObjectReferences() { - for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) { - String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setClient(client); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setAuthenticationHolder(authHolder); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) { - String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setClient(client); - tokenRepository.saveAccessToken(accessToken); - } - maps.getAccessTokenToClientRefs().clear(); - for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setAuthenticationHolder(authHolder); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) { - Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setRefreshToken(refreshToken); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) { - Set oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId); - - Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId); - ApprovedSite site = approvedSiteRepository.getById(newGrantId); - - for(Long oldTokenId : oldAccessTokenIds) { - Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId); - OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId); - token.setApprovedSite(site); - tokenRepository.saveAccessToken(token); - } - - approvedSiteRepository.save(site); - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java deleted file mode 100644 index 8cbe31232d..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java +++ /dev/null @@ -1,901 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import static org.mitre.util.JsonUtils.readMap; -import static org.mitre.util.JsonUtils.readSet; - -import java.io.IOException; -import java.text.ParseException; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AppType; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SavedUserAuthentication; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mitre.openid.connect.service.MITREidDataServiceExtension; -import org.mitre.openid.connect.service.MITREidDataServiceMaps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jwt.JWTParser; - -/** - * - * Data service to import and export MITREid 1.2 configuration. - * - * @author jricher - * @author arielak - */ -@Service -@SuppressWarnings(value = {"unchecked"}) -public class MITREidDataService_1_2 extends MITREidDataServiceSupport implements MITREidDataService { - - private static final String DEFAULT_SCOPE = "defaultScope"; - private static final String STRUCTURED_PARAMETER = "structuredParameter"; - private static final String STRUCTURED = "structured"; - private static final String RESTRICTED = "restricted"; - private static final String ICON = "icon"; - private static final String DYNAMICALLY_REGISTERED = "dynamicallyRegistered"; - private static final String CLEAR_ACCESS_TOKENS_ON_REFRESH = "clearAccessTokensOnRefresh"; - private static final String REUSE_REFRESH_TOKEN = "reuseRefreshToken"; - private static final String ALLOW_INTROSPECTION = "allowIntrospection"; - private static final String DESCRIPTION = "description"; - private static final String REQUEST_URIS = "requestUris"; - private static final String POST_LOGOUT_REDIRECT_URI = "postLogoutRedirectUri"; - private static final String INTITATE_LOGIN_URI = "intitateLoginUri"; - private static final String DEFAULT_ACR_VALUES = "defaultACRValues"; - private static final String REQUIRE_AUTH_TIME = "requireAuthTime"; - private static final String DEFAULT_MAX_AGE = "defaultMaxAge"; - private static final String TOKEN_ENDPOINT_AUTH_SIGNING_ALG = "tokenEndpointAuthSigningAlg"; - private static final String USER_INFO_ENCRYPTED_RESPONSE_ENC = "userInfoEncryptedResponseEnc"; - private static final String USER_INFO_ENCRYPTED_RESPONSE_ALG = "userInfoEncryptedResponseAlg"; - private static final String USER_INFO_SIGNED_RESPONSE_ALG = "userInfoSignedResponseAlg"; - private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ENC = "idTokenEncryptedResponseEnc"; - private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ALG = "idTokenEncryptedResponseAlg"; - private static final String ID_TOKEN_SIGNED_RESPONSE_ALG = "idTokenSignedResponseAlg"; - private static final String REQUEST_OBJECT_SIGNING_ALG = "requestObjectSigningAlg"; - private static final String SUBJECT_TYPE = "subjectType"; - private static final String SECTOR_IDENTIFIER_URI = "sectorIdentifierUri"; - private static final String APPLICATION_TYPE = "applicationType"; - private static final String JWKS = "jwks"; - private static final String JWKS_URI = "jwksUri"; - private static final String POLICY_URI = "policyUri"; - private static final String GRANT_TYPES = "grantTypes"; - private static final String TOKEN_ENDPOINT_AUTH_METHOD = "tokenEndpointAuthMethod"; - private static final String TOS_URI = "tosUri"; - private static final String CONTACTS = "contacts"; - private static final String LOGO_URI = "logoUri"; - private static final String REDIRECT_URIS = "redirectUris"; - private static final String REFRESH_TOKEN_VALIDITY_SECONDS = "refreshTokenValiditySeconds"; - private static final String ACCESS_TOKEN_VALIDITY_SECONDS = "accessTokenValiditySeconds"; - private static final String SECRET = "secret"; - private static final String URI = "uri"; - private static final String CREATOR_USER_ID = "creatorUserId"; - private static final String APPROVED_ACCESS_TOKENS = "approvedAccessTokens"; - private static final String ALLOWED_SCOPES = "allowedScopes"; - private static final String USER_ID = "userId"; - private static final String TIMEOUT_DATE = "timeoutDate"; - private static final String CREATION_DATE = "creationDate"; - private static final String ACCESS_DATE = "accessDate"; - private static final String AUTHENTICATED = "authenticated"; - private static final String SOURCE_CLASS = "sourceClass"; - private static final String NAME = "name"; - private static final String SAVED_USER_AUTHENTICATION = "savedUserAuthentication"; - private static final String EXTENSIONS = "extensions"; - private static final String RESPONSE_TYPES = "responseTypes"; - private static final String REDIRECT_URI = "redirectUri"; - private static final String APPROVED = "approved"; - private static final String AUTHORITIES = "authorities"; - private static final String RESOURCE_IDS = "resourceIds"; - private static final String REQUEST_PARAMETERS = "requestParameters"; - private static final String TYPE = "type"; - private static final String SCOPE = "scope"; - private static final String REFRESH_TOKEN_ID = "refreshTokenId"; - private static final String VALUE = "value"; - private static final String AUTHENTICATION_HOLDER_ID = "authenticationHolderId"; - private static final String CLIENT_ID = "clientId"; - private static final String EXPIRATION = "expiration"; - private static final String CLAIMS_REDIRECT_URIS = "claimsRedirectUris"; - private static final String ID = "id"; - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_2.class); - @Autowired - private OAuth2ClientRepository clientRepository; - @Autowired - private ApprovedSiteRepository approvedSiteRepository; - @Autowired - private WhitelistedSiteRepository wlSiteRepository; - @Autowired - private BlacklistedSiteRepository blSiteRepository; - @Autowired - private AuthenticationHolderRepository authHolderRepository; - @Autowired - private OAuth2TokenRepository tokenRepository; - @Autowired - private SystemScopeRepository sysScopeRepository; - @Autowired(required = false) - private List extensions = Collections.emptyList(); - - private MITREidDataServiceMaps maps = new MITREidDataServiceMaps(); - - private static final String THIS_VERSION = MITREID_CONNECT_1_2; - - @Override - public boolean supportsVersion(String version) { - return THIS_VERSION.equals(version); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter) - */ - @Override - public void exportData(JsonWriter writer) throws IOException { - - throw new UnsupportedOperationException("Can not export 1.2 format from this version."); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader) - */ - @Override - public void importData(JsonReader reader) throws IOException { - - logger.info("Reading configuration for 1.2"); - - // this *HAS* to start as an object - reader.beginObject(); - - while (reader.hasNext()) { - JsonToken tok = reader.peek(); - switch (tok) { - case NAME: - String name = reader.nextName(); - // find out which member it is - if (name.equals(CLIENTS)) { - readClients(reader); - } else if (name.equals(GRANTS)) { - readGrants(reader); - } else if (name.equals(WHITELISTEDSITES)) { - readWhitelistedSites(reader); - } else if (name.equals(BLACKLISTEDSITES)) { - readBlacklistedSites(reader); - } else if (name.equals(AUTHENTICATIONHOLDERS)) { - readAuthenticationHolders(reader); - } else if (name.equals(ACCESSTOKENS)) { - readAccessTokens(reader); - } else if (name.equals(REFRESHTOKENS)) { - readRefreshTokens(reader); - } else if (name.equals(SYSTEMSCOPES)) { - readSystemScopes(reader); - } else { - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.importExtensionData(name, reader); - break; - } - } - // unknown token, skip it - reader.skipValue(); - } - break; - case END_OBJECT: - // the object ended, we're done here - reader.endObject(); - continue; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - fixObjectReferences(); - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.fixExtensionObjectReferences(maps); - break; - } - } - maps.clearAll(); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readRefreshTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(EXPIRATION)) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals(VALUE)) { - String value = reader.nextString(); - try { - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals(CLIENT_ID)) { - clientId = reader.nextString(); - } else if (name.equals(AUTHENTICATION_HOLDER_ID)) { - authHolderId = reader.nextLong(); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveRefreshToken(token).getId(); - maps.getRefreshTokenToClientRefs().put(currentId, clientId); - maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId); - maps.getRefreshTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read refresh token {}", currentId); - } - reader.endArray(); - logger.info("Done reading refresh tokens"); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readAccessTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - Long refreshTokenId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(EXPIRATION)) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals(VALUE)) { - String value = reader.nextString(); - try { - // all tokens are JWTs - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals(CLIENT_ID)) { - clientId = reader.nextString(); - } else if (name.equals(AUTHENTICATION_HOLDER_ID)) { - authHolderId = reader.nextLong(); - } else if (name.equals(REFRESH_TOKEN_ID)) { - refreshTokenId = reader.nextLong(); - } else if (name.equals(SCOPE)) { - Set scope = readSet(reader); - token.setScope(scope); - } else if (name.equals(TYPE)) { - token.setTokenType(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveAccessToken(token).getId(); - maps.getAccessTokenToClientRefs().put(currentId, clientId); - maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId); - if (refreshTokenId != null) { - maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId); - } - maps.getAccessTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read access token {}", currentId); - } - reader.endArray(); - logger.info("Done reading access tokens"); - } - /** - * @param reader - * @throws IOException - */ - private void readAuthenticationHolders(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - AuthenticationHolderEntity ahe = new AuthenticationHolderEntity(); - reader.beginObject(); - Long currentId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(REQUEST_PARAMETERS)) { - ahe.setRequestParameters(readMap(reader)); - } else if (name.equals(CLIENT_ID)) { - ahe.setClientId(reader.nextString()); - } else if (name.equals(SCOPE)) { - ahe.setScope(readSet(reader)); - } else if (name.equals(RESOURCE_IDS)) { - ahe.setResourceIds(readSet(reader)); - } else if (name.equals(AUTHORITIES)) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - ahe.setAuthorities(authorities); - } else if (name.equals(APPROVED)) { - ahe.setApproved(reader.nextBoolean()); - } else if (name.equals(REDIRECT_URI)) { - ahe.setRedirectUri(reader.nextString()); - } else if (name.equals(RESPONSE_TYPES)) { - ahe.setResponseTypes(readSet(reader)); - } else if (name.equals(EXTENSIONS)) { - ahe.setExtensions(readMap(reader)); - } else if (name.equals(SAVED_USER_AUTHENTICATION)) { - ahe.setUserAuth(readSavedUserAuthentication(reader)); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = authHolderRepository.save(ahe).getId(); - maps.getAuthHolderOldToNewIdMap().put(currentId, newId); - logger.debug("Read authentication holder {}", currentId); - } - reader.endArray(); - logger.info("Done reading authentication holders"); - } - - /** - * @param reader - * @return - * @throws IOException - */ - private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException { - SavedUserAuthentication savedUserAuth = new SavedUserAuthentication(); - reader.beginObject(); - - while (reader.hasNext()) { - switch(reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(NAME)) { - savedUserAuth.setName(reader.nextString()); - } else if (name.equals(SOURCE_CLASS)) { - savedUserAuth.setSourceClass(reader.nextString()); - } else if (name.equals(AUTHENTICATED)) { - savedUserAuth.setAuthenticated(reader.nextBoolean()); - } else if (name.equals(AUTHORITIES)) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - savedUserAuth.setAuthorities(authorities); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - - reader.endObject(); - return savedUserAuth; - } - - /** - * @param reader - * @throws IOException - */ - private void readGrants(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ApprovedSite site = new ApprovedSite(); - Long currentId = null; - Set tokenIds = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(ACCESS_DATE)) { - Date date = utcToDate(reader.nextString()); - site.setAccessDate(date); - } else if (name.equals(CLIENT_ID)) { - site.setClientId(reader.nextString()); - } else if (name.equals(CREATION_DATE)) { - Date date = utcToDate(reader.nextString()); - site.setCreationDate(date); - } else if (name.equals(TIMEOUT_DATE)) { - Date date = utcToDate(reader.nextString()); - site.setTimeoutDate(date); - } else if (name.equals(USER_ID)) { - site.setUserId(reader.nextString()); - } else if (name.equals(ALLOWED_SCOPES)) { - Set allowedScopes = readSet(reader); - site.setAllowedScopes(allowedScopes); - } else if (name.equals(APPROVED_ACCESS_TOKENS)) { - tokenIds = readSet(reader); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = approvedSiteRepository.save(site).getId(); - maps.getGrantOldToNewIdMap().put(currentId, newId); - if (tokenIds != null) { - maps.getGrantToAccessTokensRefs().put(currentId, tokenIds); - } - logger.debug("Read grant {}", currentId); - } - reader.endArray(); - logger.info("Done reading grants"); - } - /** - * @param reader - * @throws IOException - */ - private void readWhitelistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - WhitelistedSite wlSite = new WhitelistedSite(); - Long currentId = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(CLIENT_ID)) { - wlSite.setClientId(reader.nextString()); - } else if (name.equals(CREATOR_USER_ID)) { - wlSite.setCreatorUserId(reader.nextString()); - } else if (name.equals(ALLOWED_SCOPES)) { - Set allowedScopes = readSet(reader); - wlSite.setAllowedScopes(allowedScopes); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = wlSiteRepository.save(wlSite).getId(); - maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId); - } - reader.endArray(); - logger.info("Done reading whitelisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readBlacklistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - BlacklistedSite blSite = new BlacklistedSite(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals(ID)) { - reader.skipValue(); - } else if (name.equals(URI)) { - blSite.setUri(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - blSiteRepository.save(blSite); - } - reader.endArray(); - logger.info("Done reading blacklisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readClients(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ClientDetailsEntity client = new ClientDetailsEntity(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(CLIENT_ID)) { - client.setClientId(reader.nextString()); - } else if (name.equals(RESOURCE_IDS)) { - Set resourceIds = readSet(reader); - client.setResourceIds(resourceIds); - } else if (name.equals(SECRET)) { - client.setClientSecret(reader.nextString()); - } else if (name.equals(SCOPE)) { - Set scope = readSet(reader); - client.setScope(scope); - } else if (name.equals(AUTHORITIES)) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - client.setAuthorities(authorities); - } else if (name.equals(ACCESS_TOKEN_VALIDITY_SECONDS)) { - client.setAccessTokenValiditySeconds(reader.nextInt()); - } else if (name.equals(REFRESH_TOKEN_VALIDITY_SECONDS)) { - client.setRefreshTokenValiditySeconds(reader.nextInt()); - } else if (name.equals(REDIRECT_URIS)) { - Set redirectUris = readSet(reader); - client.setRedirectUris(redirectUris); - } else if (name.equals(CLAIMS_REDIRECT_URIS)) { - Set claimsRedirectUris = readSet(reader); - client.setClaimsRedirectUris(claimsRedirectUris); - } else if (name.equals(NAME)) { - client.setClientName(reader.nextString()); - } else if (name.equals(URI)) { - client.setClientUri(reader.nextString()); - } else if (name.equals(LOGO_URI)) { - client.setLogoUri(reader.nextString()); - } else if (name.equals(CONTACTS)) { - Set contacts = readSet(reader); - client.setContacts(contacts); - } else if (name.equals(TOS_URI)) { - client.setTosUri(reader.nextString()); - } else if (name.equals(TOKEN_ENDPOINT_AUTH_METHOD)) { - AuthMethod am = AuthMethod.getByValue(reader.nextString()); - client.setTokenEndpointAuthMethod(am); - } else if (name.equals(GRANT_TYPES)) { - Set grantTypes = readSet(reader); - client.setGrantTypes(grantTypes); - } else if (name.equals(RESPONSE_TYPES)) { - Set responseTypes = readSet(reader); - client.setResponseTypes(responseTypes); - } else if (name.equals(POLICY_URI)) { - client.setPolicyUri(reader.nextString()); - } else if (name.equals(APPLICATION_TYPE)) { - AppType appType = AppType.getByValue(reader.nextString()); - client.setApplicationType(appType); - } else if (name.equals(SECTOR_IDENTIFIER_URI)) { - client.setSectorIdentifierUri(reader.nextString()); - } else if (name.equals(SUBJECT_TYPE)) { - SubjectType st = SubjectType.getByValue(reader.nextString()); - client.setSubjectType(st); - } else if (name.equals(JWKS_URI)) { - client.setJwksUri(reader.nextString()); - } else if (name.equals(JWKS)) { - try { - client.setJwks(JWKSet.parse(reader.nextString())); - } catch (ParseException e) { - logger.error("Couldn't parse JWK Set", e); - } - } else if (name.equals(REQUEST_OBJECT_SIGNING_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setRequestObjectSigningAlg(alg); - } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ALG)) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setUserInfoEncryptedResponseAlg(alg); - } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ENC)) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setUserInfoEncryptedResponseEnc(alg); - } else if (name.equals(USER_INFO_SIGNED_RESPONSE_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setUserInfoSignedResponseAlg(alg); - } else if (name.equals(ID_TOKEN_SIGNED_RESPONSE_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setIdTokenSignedResponseAlg(alg); - } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setIdTokenEncryptedResponseAlg(alg); - } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setIdTokenEncryptedResponseEnc(alg); - } else if (name.equals(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setTokenEndpointAuthSigningAlg(alg); - } else if (name.equals(DEFAULT_MAX_AGE)) { - client.setDefaultMaxAge(reader.nextInt()); - } else if (name.equals(REQUIRE_AUTH_TIME)) { - client.setRequireAuthTime(reader.nextBoolean()); - } else if (name.equals(DEFAULT_ACR_VALUES)) { - Set defaultACRvalues = readSet(reader); - client.setDefaultACRvalues(defaultACRvalues); - } else if (name.equals("initiateLoginUri")) { - client.setInitiateLoginUri(reader.nextString()); - } else if (name.equals(POST_LOGOUT_REDIRECT_URI)) { - Set postLogoutUris = readSet(reader); - client.setPostLogoutRedirectUris(postLogoutUris); - } else if (name.equals(REQUEST_URIS)) { - Set requestUris = readSet(reader); - client.setRequestUris(requestUris); - } else if (name.equals(DESCRIPTION)) { - client.setClientDescription(reader.nextString()); - } else if (name.equals(ALLOW_INTROSPECTION)) { - client.setAllowIntrospection(reader.nextBoolean()); - } else if (name.equals(REUSE_REFRESH_TOKEN)) { - client.setReuseRefreshToken(reader.nextBoolean()); - } else if (name.equals(CLEAR_ACCESS_TOKENS_ON_REFRESH)) { - client.setClearAccessTokensOnRefresh(reader.nextBoolean()); - } else if (name.equals(DYNAMICALLY_REGISTERED)) { - client.setDynamicallyRegistered(reader.nextBoolean()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - clientRepository.saveClient(client); - } - reader.endArray(); - logger.info("Done reading clients"); - } - - /** - * Read the list of system scopes from the reader and insert them into the - * scope repository. - * - * @param reader - * @throws IOException - */ - private void readSystemScopes(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - SystemScope scope = new SystemScope(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(VALUE)) { - scope.setValue(reader.nextString()); - } else if (name.equals(DESCRIPTION)) { - scope.setDescription(reader.nextString()); - } else if (name.equals(RESTRICTED)) { - scope.setRestricted(reader.nextBoolean()); - } else if (name.equals(DEFAULT_SCOPE)) { - scope.setDefaultScope(reader.nextBoolean()); - } else if (name.equals(ICON)) { - scope.setIcon(reader.nextString()); - } else if (name.equals(STRUCTURED)) { - logger.warn("Found a structured scope, ignoring structure"); - } else if (name.equals(STRUCTURED_PARAMETER)) { - logger.warn("Found a structured scope, ignoring structure"); - } else { - logger.debug("found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - sysScopeRepository.save(scope); - } - reader.endArray(); - logger.info("Done reading system scopes"); - } - - private void fixObjectReferences() { - logger.info("Fixing object references..."); - for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) { - String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setClient(client); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setAuthenticationHolder(authHolder); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) { - String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setClient(client); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setAuthenticationHolder(authHolder); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) { - Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setRefreshToken(refreshToken); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) { - Set oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId); - - Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId); - ApprovedSite site = approvedSiteRepository.getById(newGrantId); - - for(Long oldTokenId : oldAccessTokenIds) { - Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId); - OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId); - token.setApprovedSite(site); - tokenRepository.saveAccessToken(token); - } - - approvedSiteRepository.save(site); - } - logger.info("Done fixing object references."); - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java deleted file mode 100644 index 2377306e57..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java +++ /dev/null @@ -1,1314 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import static org.mitre.util.JsonUtils.readMap; -import static org.mitre.util.JsonUtils.readSet; -import static org.mitre.util.JsonUtils.writeNullSafeArray; - -import java.io.IOException; -import java.io.Serializable; -import java.text.ParseException; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AppType; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.PKCEAlgorithm; -import org.mitre.oauth2.model.SavedUserAuthentication; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mitre.openid.connect.service.MITREidDataServiceExtension; -import org.mitre.openid.connect.service.MITREidDataServiceMaps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.stereotype.Service; - -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.jwk.JWKSet; -import com.nimbusds.jwt.JWTParser; - -/** - * - * Data service to import and export MITREid 1.3 configuration. - * - * @author jricher - * @author arielak - */ -@Service -@SuppressWarnings(value = {"unchecked"}) -public class MITREidDataService_1_3 extends MITREidDataServiceSupport implements MITREidDataService { - - private static final String DEFAULT_SCOPE = "defaultScope"; - private static final String RESTRICTED = "restricted"; - private static final String ICON = "icon"; - private static final String DYNAMICALLY_REGISTERED = "dynamicallyRegistered"; - private static final String CLEAR_ACCESS_TOKENS_ON_REFRESH = "clearAccessTokensOnRefresh"; - private static final String REUSE_REFRESH_TOKEN = "reuseRefreshToken"; - private static final String ALLOW_INTROSPECTION = "allowIntrospection"; - private static final String DESCRIPTION = "description"; - private static final String REQUEST_URIS = "requestUris"; - private static final String POST_LOGOUT_REDIRECT_URI = "postLogoutRedirectUri"; - private static final String INTITATE_LOGIN_URI = "intitateLoginUri"; - private static final String DEFAULT_ACR_VALUES = "defaultACRValues"; - private static final String REQUIRE_AUTH_TIME = "requireAuthTime"; - private static final String DEFAULT_MAX_AGE = "defaultMaxAge"; - private static final String TOKEN_ENDPOINT_AUTH_SIGNING_ALG = "tokenEndpointAuthSigningAlg"; - private static final String USER_INFO_ENCRYPTED_RESPONSE_ENC = "userInfoEncryptedResponseEnc"; - private static final String USER_INFO_ENCRYPTED_RESPONSE_ALG = "userInfoEncryptedResponseAlg"; - private static final String USER_INFO_SIGNED_RESPONSE_ALG = "userInfoSignedResponseAlg"; - private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ENC = "idTokenEncryptedResponseEnc"; - private static final String ID_TOKEN_ENCRYPTED_RESPONSE_ALG = "idTokenEncryptedResponseAlg"; - private static final String ID_TOKEN_SIGNED_RESPONSE_ALG = "idTokenSignedResponseAlg"; - private static final String REQUEST_OBJECT_SIGNING_ALG = "requestObjectSigningAlg"; - private static final String SUBJECT_TYPE = "subjectType"; - private static final String SECTOR_IDENTIFIER_URI = "sectorIdentifierUri"; - private static final String APPLICATION_TYPE = "applicationType"; - private static final String JWKS = "jwks"; - private static final String JWKS_URI = "jwksUri"; - private static final String POLICY_URI = "policyUri"; - private static final String GRANT_TYPES = "grantTypes"; - private static final String TOKEN_ENDPOINT_AUTH_METHOD = "tokenEndpointAuthMethod"; - private static final String TOS_URI = "tosUri"; - private static final String CONTACTS = "contacts"; - private static final String LOGO_URI = "logoUri"; - private static final String REDIRECT_URIS = "redirectUris"; - private static final String REFRESH_TOKEN_VALIDITY_SECONDS = "refreshTokenValiditySeconds"; - private static final String ACCESS_TOKEN_VALIDITY_SECONDS = "accessTokenValiditySeconds"; - private static final String ID_TOKEN_VALIDITY_SECONDS = "idTokenValiditySeconds"; - private static final String DEVICE_CODE_VALIDITY_SECONDS = "deviceCodeValiditySeconds"; - private static final String SECRET = "secret"; - private static final String URI = "uri"; - private static final String CREATOR_USER_ID = "creatorUserId"; - private static final String APPROVED_ACCESS_TOKENS = "approvedAccessTokens"; - private static final String ALLOWED_SCOPES = "allowedScopes"; - private static final String USER_ID = "userId"; - private static final String TIMEOUT_DATE = "timeoutDate"; - private static final String CREATION_DATE = "creationDate"; - private static final String ACCESS_DATE = "accessDate"; - private static final String AUTHENTICATED = "authenticated"; - private static final String SOURCE_CLASS = "sourceClass"; - private static final String NAME = "name"; - private static final String SAVED_USER_AUTHENTICATION = "savedUserAuthentication"; - private static final String EXTENSIONS = "extensions"; - private static final String RESPONSE_TYPES = "responseTypes"; - private static final String REDIRECT_URI = "redirectUri"; - private static final String APPROVED = "approved"; - private static final String AUTHORITIES = "authorities"; - private static final String RESOURCE_IDS = "resourceIds"; - private static final String REQUEST_PARAMETERS = "requestParameters"; - private static final String TYPE = "type"; - private static final String SCOPE = "scope"; - private static final String REFRESH_TOKEN_ID = "refreshTokenId"; - private static final String VALUE = "value"; - private static final String AUTHENTICATION_HOLDER_ID = "authenticationHolderId"; - private static final String CLIENT_ID = "clientId"; - private static final String EXPIRATION = "expiration"; - private static final String CLAIMS_REDIRECT_URIS = "claimsRedirectUris"; - private static final String ID = "id"; - private static final String CODE_CHALLENGE_METHOD = "codeChallengeMethod"; - private static final String SOFTWARE_STATEMENT = "softwareStatement"; - private static final String SOFTWARE_VERSION = "softwareVersion"; - private static final String SOFTWARE_ID = "softwareId"; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(MITREidDataService_1_3.class); - @Autowired - private OAuth2ClientRepository clientRepository; - @Autowired - private ApprovedSiteRepository approvedSiteRepository; - @Autowired - private WhitelistedSiteRepository wlSiteRepository; - @Autowired - private BlacklistedSiteRepository blSiteRepository; - @Autowired - private AuthenticationHolderRepository authHolderRepository; - @Autowired - private OAuth2TokenRepository tokenRepository; - @Autowired - private SystemScopeRepository sysScopeRepository; - @Autowired(required = false) - private List extensions = Collections.emptyList(); - - private static final String THIS_VERSION = MITREID_CONNECT_1_3; - - private MITREidDataServiceMaps maps = new MITREidDataServiceMaps(); - - @Override - public boolean supportsVersion(String version) { - return THIS_VERSION.equals(version); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#export(com.google.gson.stream.JsonWriter) - */ - @Override - public void exportData(JsonWriter writer) throws IOException { - - // version tag at the root - writer.name(THIS_VERSION); - - writer.beginObject(); - - // clients list - writer.name(CLIENTS); - writer.beginArray(); - writeClients(writer); - writer.endArray(); - - writer.name(GRANTS); - writer.beginArray(); - writeGrants(writer); - writer.endArray(); - - writer.name(WHITELISTEDSITES); - writer.beginArray(); - writeWhitelistedSites(writer); - writer.endArray(); - - writer.name(BLACKLISTEDSITES); - writer.beginArray(); - writeBlacklistedSites(writer); - writer.endArray(); - - writer.name(AUTHENTICATIONHOLDERS); - writer.beginArray(); - writeAuthenticationHolders(writer); - writer.endArray(); - - writer.name(ACCESSTOKENS); - writer.beginArray(); - writeAccessTokens(writer); - writer.endArray(); - - writer.name(REFRESHTOKENS); - writer.beginArray(); - writeRefreshTokens(writer); - writer.endArray(); - - writer.name(SYSTEMSCOPES); - writer.beginArray(); - writeSystemScopes(writer); - writer.endArray(); - - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.exportExtensionData(writer); - break; - } - } - - writer.endObject(); // end mitreid-connect-1.3 - } - - /** - * @param writer - */ - private void writeRefreshTokens(JsonWriter writer) throws IOException { - for (OAuth2RefreshTokenEntity token : tokenRepository.getAllRefreshTokens()) { - writer.beginObject(); - writer.name(ID).value(token.getId()); - writer.name(EXPIRATION).value(toUTCString(token.getExpiration())); - writer.name(CLIENT_ID) - .value((token.getClient() != null) ? token.getClient().getClientId() : null); - writer.name(AUTHENTICATION_HOLDER_ID) - .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null); - writer.name(VALUE).value(token.getValue()); - writer.endObject(); - logger.debug("Wrote refresh token {}", token.getId()); - } - logger.info("Done writing refresh tokens"); - } - - /** - * @param writer - */ - private void writeAccessTokens(JsonWriter writer) throws IOException { - for (OAuth2AccessTokenEntity token : tokenRepository.getAllAccessTokens()) { - writer.beginObject(); - writer.name(ID).value(token.getId()); - writer.name(EXPIRATION).value(toUTCString(token.getExpiration())); - writer.name(CLIENT_ID) - .value((token.getClient() != null) ? token.getClient().getClientId() : null); - writer.name(AUTHENTICATION_HOLDER_ID) - .value((token.getAuthenticationHolder() != null) ? token.getAuthenticationHolder().getId() : null); - writer.name(REFRESH_TOKEN_ID) - .value((token.getRefreshToken() != null) ? token.getRefreshToken().getId() : null); - writer.name(SCOPE); - writer.beginArray(); - for (String s : token.getScope()) { - writer.value(s); - } - writer.endArray(); - writer.name(TYPE).value(token.getTokenType()); - writer.name(VALUE).value(token.getValue()); - writer.endObject(); - logger.debug("Wrote access token {}", token.getId()); - } - logger.info("Done writing access tokens"); - } - - /** - * @param writer - */ - private void writeAuthenticationHolders(JsonWriter writer) throws IOException { - for (AuthenticationHolderEntity holder : authHolderRepository.getAll()) { - writer.beginObject(); - writer.name(ID).value(holder.getId()); - - writer.name(REQUEST_PARAMETERS); - writer.beginObject(); - for (Entry entry : holder.getRequestParameters().entrySet()) { - writer.name(entry.getKey()).value(entry.getValue()); - } - writer.endObject(); - writer.name(CLIENT_ID).value(holder.getClientId()); - Set scope = holder.getScope(); - writer.name(SCOPE); - writer.beginArray(); - for (String s : scope) { - writer.value(s); - } - writer.endArray(); - writer.name(RESOURCE_IDS); - writer.beginArray(); - if (holder.getResourceIds() != null) { - for (String s : holder.getResourceIds()) { - writer.value(s); - } - } - writer.endArray(); - writer.name(AUTHORITIES); - writer.beginArray(); - for (GrantedAuthority authority : holder.getAuthorities()) { - writer.value(authority.getAuthority()); - } - writer.endArray(); - writer.name(APPROVED).value(holder.isApproved()); - writer.name(REDIRECT_URI).value(holder.getRedirectUri()); - writer.name(RESPONSE_TYPES); - writer.beginArray(); - for (String s : holder.getResponseTypes()) { - writer.value(s); - } - writer.endArray(); - writer.name(EXTENSIONS); - writer.beginObject(); - for (Entry entry : holder.getExtensions().entrySet()) { - // while the extension map itself is Serializable, we enforce storage of Strings - if (entry.getValue() instanceof String) { - writer.name(entry.getKey()).value((String) entry.getValue()); - } else { - logger.warn("Skipping non-string extension: " + entry); - } - } - writer.endObject(); - - writer.name(SAVED_USER_AUTHENTICATION); - if (holder.getUserAuth() != null) { - writer.beginObject(); - writer.name(NAME).value(holder.getUserAuth().getName()); - writer.name(SOURCE_CLASS).value(holder.getUserAuth().getSourceClass()); - writer.name(AUTHENTICATED).value(holder.getUserAuth().isAuthenticated()); - writer.name(AUTHORITIES); - writer.beginArray(); - for (GrantedAuthority authority : holder.getUserAuth().getAuthorities()) { - writer.value(authority.getAuthority()); - } - writer.endArray(); - - writer.endObject(); - } else { - writer.nullValue(); - } - - - writer.endObject(); - logger.debug("Wrote authentication holder {}", holder.getId()); - } - logger.info("Done writing authentication holders"); - } - - /** - * @param writer - */ - private void writeGrants(JsonWriter writer) throws IOException { - for (ApprovedSite site : approvedSiteRepository.getAll()) { - writer.beginObject(); - writer.name(ID).value(site.getId()); - writer.name(ACCESS_DATE).value(toUTCString(site.getAccessDate())); - writer.name(CLIENT_ID).value(site.getClientId()); - writer.name(CREATION_DATE).value(toUTCString(site.getCreationDate())); - writer.name(TIMEOUT_DATE).value(toUTCString(site.getTimeoutDate())); - writer.name(USER_ID).value(site.getUserId()); - writer.name(ALLOWED_SCOPES); - writeNullSafeArray(writer, site.getAllowedScopes()); - List tokens = tokenRepository.getAccessTokensForApprovedSite(site); - writer.name(APPROVED_ACCESS_TOKENS); - writer.beginArray(); - for (OAuth2AccessTokenEntity token : tokens) { - writer.value(token.getId()); - } - writer.endArray(); - writer.endObject(); - logger.debug("Wrote grant {}", site.getId()); - } - logger.info("Done writing grants"); - } - - /** - * @param writer - */ - private void writeWhitelistedSites(JsonWriter writer) throws IOException { - for (WhitelistedSite wlSite : wlSiteRepository.getAll()) { - writer.beginObject(); - writer.name(ID).value(wlSite.getId()); - writer.name(CLIENT_ID).value(wlSite.getClientId()); - writer.name(CREATOR_USER_ID).value(wlSite.getCreatorUserId()); - writer.name(ALLOWED_SCOPES); - writeNullSafeArray(writer, wlSite.getAllowedScopes()); - writer.endObject(); - logger.debug("Wrote whitelisted site {}", wlSite.getId()); - } - logger.info("Done writing whitelisted sites"); - } - - /** - * @param writer - */ - private void writeBlacklistedSites(JsonWriter writer) throws IOException { - for (BlacklistedSite blSite : blSiteRepository.getAll()) { - writer.beginObject(); - writer.name(ID).value(blSite.getId()); - writer.name(URI).value(blSite.getUri()); - writer.endObject(); - logger.debug("Wrote blacklisted site {}", blSite.getId()); - } - logger.info("Done writing blacklisted sites"); - } - - /** - * @param writer - */ - private void writeClients(JsonWriter writer) { - for (ClientDetailsEntity client : clientRepository.getAllClients()) { - try { - writer.beginObject(); - writer.name(CLIENT_ID).value(client.getClientId()); - writer.name(RESOURCE_IDS); - writeNullSafeArray(writer, client.getResourceIds()); - - writer.name(SECRET).value(client.getClientSecret()); - - writer.name(SCOPE); - writeNullSafeArray(writer, client.getScope()); - - writer.name(AUTHORITIES); - writer.beginArray(); - for (GrantedAuthority authority : client.getAuthorities()) { - writer.value(authority.getAuthority()); - } - writer.endArray(); - writer.name(ACCESS_TOKEN_VALIDITY_SECONDS).value(client.getAccessTokenValiditySeconds()); - writer.name(REFRESH_TOKEN_VALIDITY_SECONDS).value(client.getRefreshTokenValiditySeconds()); - writer.name(ID_TOKEN_VALIDITY_SECONDS).value(client.getIdTokenValiditySeconds()); - writer.name(DEVICE_CODE_VALIDITY_SECONDS).value(client.getDeviceCodeValiditySeconds()); - writer.name(REDIRECT_URIS); - writeNullSafeArray(writer, client.getRedirectUris()); - writer.name(CLAIMS_REDIRECT_URIS); - writeNullSafeArray(writer, client.getClaimsRedirectUris()); - writer.name(NAME).value(client.getClientName()); - writer.name(URI).value(client.getClientUri()); - writer.name(LOGO_URI).value(client.getLogoUri()); - writer.name(CONTACTS); - writeNullSafeArray(writer, client.getContacts()); - writer.name(TOS_URI).value(client.getTosUri()); - writer.name(TOKEN_ENDPOINT_AUTH_METHOD) - .value((client.getTokenEndpointAuthMethod() != null) ? client.getTokenEndpointAuthMethod().getValue() : null); - writer.name(GRANT_TYPES); - writer.beginArray(); - for (String s : client.getGrantTypes()) { - writer.value(s); - } - writer.endArray(); - writer.name(RESPONSE_TYPES); - writer.beginArray(); - for (String s : client.getResponseTypes()) { - writer.value(s); - } - writer.endArray(); - writer.name(POLICY_URI).value(client.getPolicyUri()); - writer.name(JWKS_URI).value(client.getJwksUri()); - writer.name(JWKS).value((client.getJwks() != null) ? client.getJwks().toString() : null); - writer.name(APPLICATION_TYPE) - .value((client.getApplicationType() != null) ? client.getApplicationType().getValue() : null); - writer.name(SECTOR_IDENTIFIER_URI).value(client.getSectorIdentifierUri()); - writer.name(SUBJECT_TYPE) - .value((client.getSubjectType() != null) ? client.getSubjectType().getValue() : null); - writer.name(REQUEST_OBJECT_SIGNING_ALG) - .value((client.getRequestObjectSigningAlg() != null) ? client.getRequestObjectSigningAlg().getName() : null); - writer.name(ID_TOKEN_SIGNED_RESPONSE_ALG) - .value((client.getIdTokenSignedResponseAlg() != null) ? client.getIdTokenSignedResponseAlg().getName() : null); - writer.name(ID_TOKEN_ENCRYPTED_RESPONSE_ALG) - .value((client.getIdTokenEncryptedResponseAlg() != null) ? client.getIdTokenEncryptedResponseAlg().getName() : null); - writer.name(ID_TOKEN_ENCRYPTED_RESPONSE_ENC) - .value((client.getIdTokenEncryptedResponseEnc() != null) ? client.getIdTokenEncryptedResponseEnc().getName() : null); - writer.name(USER_INFO_SIGNED_RESPONSE_ALG) - .value((client.getUserInfoSignedResponseAlg() != null) ? client.getUserInfoSignedResponseAlg().getName() : null); - writer.name(USER_INFO_ENCRYPTED_RESPONSE_ALG) - .value((client.getUserInfoEncryptedResponseAlg() != null) ? client.getUserInfoEncryptedResponseAlg().getName() : null); - writer.name(USER_INFO_ENCRYPTED_RESPONSE_ENC) - .value((client.getUserInfoEncryptedResponseEnc() != null) ? client.getUserInfoEncryptedResponseEnc().getName() : null); - writer.name(TOKEN_ENDPOINT_AUTH_SIGNING_ALG) - .value((client.getTokenEndpointAuthSigningAlg() != null) ? client.getTokenEndpointAuthSigningAlg().getName() : null); - writer.name(DEFAULT_MAX_AGE).value(client.getDefaultMaxAge()); - Boolean requireAuthTime = null; - try { - requireAuthTime = client.getRequireAuthTime(); - } catch (NullPointerException e) { - } - if (requireAuthTime != null) { - writer.name(REQUIRE_AUTH_TIME).value(requireAuthTime); - } - writer.name(DEFAULT_ACR_VALUES); - writeNullSafeArray(writer, client.getDefaultACRvalues()); - writer.name(INTITATE_LOGIN_URI).value(client.getInitiateLoginUri()); - writer.name(POST_LOGOUT_REDIRECT_URI); - writeNullSafeArray(writer, client.getPostLogoutRedirectUris()); - writer.name(REQUEST_URIS); - writeNullSafeArray(writer, client.getRequestUris()); - writer.name(DESCRIPTION).value(client.getClientDescription()); - writer.name(ALLOW_INTROSPECTION).value(client.isAllowIntrospection()); - writer.name(REUSE_REFRESH_TOKEN).value(client.isReuseRefreshToken()); - writer.name(CLEAR_ACCESS_TOKENS_ON_REFRESH).value(client.isClearAccessTokensOnRefresh()); - writer.name(DYNAMICALLY_REGISTERED).value(client.isDynamicallyRegistered()); - writer.name(CODE_CHALLENGE_METHOD).value(client.getCodeChallengeMethod() != null ? client.getCodeChallengeMethod().getName() : null); - writer.name(SOFTWARE_ID).value(client.getSoftwareId()); - writer.name(SOFTWARE_VERSION).value(client.getSoftwareVersion()); - writer.name(SOFTWARE_STATEMENT).value(client.getSoftwareStatement() != null ? client.getSoftwareStatement().serialize() : null); - writer.name(CREATION_DATE).value(toUTCString(client.getCreatedAt())); - writer.endObject(); - logger.debug("Wrote client {}", client.getId()); - } catch (IOException ex) { - logger.error("Unable to write client {}", client.getId(), ex); - } - } - logger.info("Done writing clients"); - } - - /** - * @param writer - */ - private void writeSystemScopes(JsonWriter writer) { - for (SystemScope sysScope : sysScopeRepository.getAll()) { - try { - writer.beginObject(); - writer.name(ID).value(sysScope.getId()); - writer.name(DESCRIPTION).value(sysScope.getDescription()); - writer.name(ICON).value(sysScope.getIcon()); - writer.name(VALUE).value(sysScope.getValue()); - writer.name(RESTRICTED).value(sysScope.isRestricted()); - writer.name(DEFAULT_SCOPE).value(sysScope.isDefaultScope()); - writer.endObject(); - logger.debug("Wrote system scope {}", sysScope.getId()); - } catch (IOException ex) { - logger.error("Unable to write system scope {}", sysScope.getId(), ex); - } - } - logger.info("Done writing system scopes"); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataService#importData(com.google.gson.stream.JsonReader) - */ - @Override - public void importData(JsonReader reader) throws IOException { - - logger.info("Reading configuration for 1.3"); - - // this *HAS* to start as an object - reader.beginObject(); - - while (reader.hasNext()) { - JsonToken tok = reader.peek(); - switch (tok) { - case NAME: - String name = reader.nextName(); - // find out which member it is - if (name.equals(CLIENTS)) { - readClients(reader); - } else if (name.equals(GRANTS)) { - readGrants(reader); - } else if (name.equals(WHITELISTEDSITES)) { - readWhitelistedSites(reader); - } else if (name.equals(BLACKLISTEDSITES)) { - readBlacklistedSites(reader); - } else if (name.equals(AUTHENTICATIONHOLDERS)) { - readAuthenticationHolders(reader); - } else if (name.equals(ACCESSTOKENS)) { - readAccessTokens(reader); - } else if (name.equals(REFRESHTOKENS)) { - readRefreshTokens(reader); - } else if (name.equals(SYSTEMSCOPES)) { - readSystemScopes(reader); - } else { - boolean processed = false; - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - processed = extension.importExtensionData(name, reader); - if (processed) { - // if the extension processed data, break out of this inner loop - // (only the first extension to claim an extension point gets it) - break; - } - } - } - if (!processed) { - // unknown token, skip it - reader.skipValue(); - } - } - break; - case END_OBJECT: - // the object ended, we're done here - reader.endObject(); - continue; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - fixObjectReferences(); - for (MITREidDataServiceExtension extension : extensions) { - if (extension.supportsVersion(THIS_VERSION)) { - extension.fixExtensionObjectReferences(maps); - break; - } - } - maps.clearAll(); - } - - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readRefreshTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2RefreshTokenEntity token = new OAuth2RefreshTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(EXPIRATION)) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals(VALUE)) { - String value = reader.nextString(); - try { - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals(CLIENT_ID)) { - clientId = reader.nextString(); - } else if (name.equals(AUTHENTICATION_HOLDER_ID)) { - authHolderId = reader.nextLong(); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveRefreshToken(token).getId(); - maps.getRefreshTokenToClientRefs().put(currentId, clientId); - maps.getRefreshTokenToAuthHolderRefs().put(currentId, authHolderId); - maps.getRefreshTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read refresh token {}", currentId); - } - reader.endArray(); - logger.info("Done reading refresh tokens"); - } - /** - * @param reader - * @throws IOException - */ - /** - * @param reader - * @throws IOException - */ - private void readAccessTokens(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - reader.beginObject(); - Long currentId = null; - String clientId = null; - Long authHolderId = null; - Long refreshTokenId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(EXPIRATION)) { - Date date = utcToDate(reader.nextString()); - token.setExpiration(date); - } else if (name.equals(VALUE)) { - String value = reader.nextString(); - try { - // all tokens are JWTs - token.setJwt(JWTParser.parse(value)); - } catch (ParseException ex) { - logger.error("Unable to set refresh token value to {}", value, ex); - } - } else if (name.equals(CLIENT_ID)) { - clientId = reader.nextString(); - } else if (name.equals(AUTHENTICATION_HOLDER_ID)) { - authHolderId = reader.nextLong(); - } else if (name.equals(REFRESH_TOKEN_ID)) { - refreshTokenId = reader.nextLong(); - } else if (name.equals(SCOPE)) { - Set scope = readSet(reader); - token.setScope(scope); - } else if (name.equals(TYPE)) { - token.setTokenType(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = tokenRepository.saveAccessToken(token).getId(); - maps.getAccessTokenToClientRefs().put(currentId, clientId); - maps.getAccessTokenToAuthHolderRefs().put(currentId, authHolderId); - if (refreshTokenId != null) { - maps.getAccessTokenToRefreshTokenRefs().put(currentId, refreshTokenId); - } - maps.getAccessTokenOldToNewIdMap().put(currentId, newId); - logger.debug("Read access token {}", currentId); - } - reader.endArray(); - logger.info("Done reading access tokens"); - } - /** - * @param reader - * @throws IOException - */ - private void readAuthenticationHolders(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - AuthenticationHolderEntity ahe = new AuthenticationHolderEntity(); - reader.beginObject(); - Long currentId = null; - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(REQUEST_PARAMETERS)) { - ahe.setRequestParameters(readMap(reader)); - } else if (name.equals(CLIENT_ID)) { - ahe.setClientId(reader.nextString()); - } else if (name.equals(SCOPE)) { - ahe.setScope(readSet(reader)); - } else if (name.equals(RESOURCE_IDS)) { - ahe.setResourceIds(readSet(reader)); - } else if (name.equals(AUTHORITIES)) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - ahe.setAuthorities(authorities); - } else if (name.equals(APPROVED)) { - ahe.setApproved(reader.nextBoolean()); - } else if (name.equals(REDIRECT_URI)) { - ahe.setRedirectUri(reader.nextString()); - } else if (name.equals(RESPONSE_TYPES)) { - ahe.setResponseTypes(readSet(reader)); - } else if (name.equals(EXTENSIONS)) { - ahe.setExtensions(readMap(reader)); - } else if (name.equals(SAVED_USER_AUTHENTICATION)) { - ahe.setUserAuth(readSavedUserAuthentication(reader)); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = authHolderRepository.save(ahe).getId(); - maps.getAuthHolderOldToNewIdMap().put(currentId, newId); - logger.debug("Read authentication holder {}", currentId); - } - reader.endArray(); - logger.info("Done reading authentication holders"); - } - - /** - * @param reader - * @return - * @throws IOException - */ - private SavedUserAuthentication readSavedUserAuthentication(JsonReader reader) throws IOException { - SavedUserAuthentication savedUserAuth = new SavedUserAuthentication(); - reader.beginObject(); - - while (reader.hasNext()) { - switch(reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(NAME)) { - savedUserAuth.setName(reader.nextString()); - } else if (name.equals(SOURCE_CLASS)) { - savedUserAuth.setSourceClass(reader.nextString()); - } else if (name.equals(AUTHENTICATED)) { - savedUserAuth.setAuthenticated(reader.nextBoolean()); - } else if (name.equals(AUTHORITIES)) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - savedUserAuth.setAuthorities(authorities); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - - reader.endObject(); - return savedUserAuth; - } - - /** - * @param reader - * @throws IOException - */ - private void readGrants(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ApprovedSite site = new ApprovedSite(); - Long currentId = null; - Set tokenIds = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(ACCESS_DATE)) { - Date date = utcToDate(reader.nextString()); - site.setAccessDate(date); - } else if (name.equals(CLIENT_ID)) { - site.setClientId(reader.nextString()); - } else if (name.equals(CREATION_DATE)) { - Date date = utcToDate(reader.nextString()); - site.setCreationDate(date); - } else if (name.equals(TIMEOUT_DATE)) { - Date date = utcToDate(reader.nextString()); - site.setTimeoutDate(date); - } else if (name.equals(USER_ID)) { - site.setUserId(reader.nextString()); - } else if (name.equals(ALLOWED_SCOPES)) { - Set allowedScopes = readSet(reader); - site.setAllowedScopes(allowedScopes); - } else if (name.equals(APPROVED_ACCESS_TOKENS)) { - tokenIds = readSet(reader); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = approvedSiteRepository.save(site).getId(); - maps.getGrantOldToNewIdMap().put(currentId, newId); - if (tokenIds != null) { - maps.getGrantToAccessTokensRefs().put(currentId, tokenIds); - } - logger.debug("Read grant {}", currentId); - } - reader.endArray(); - logger.info("Done reading grants"); - } - - /** - * @param reader - * @throws IOException - */ - private void readWhitelistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - WhitelistedSite wlSite = new WhitelistedSite(); - Long currentId = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals(ID)) { - currentId = reader.nextLong(); - } else if (name.equals(CLIENT_ID)) { - wlSite.setClientId(reader.nextString()); - } else if (name.equals(CREATOR_USER_ID)) { - wlSite.setCreatorUserId(reader.nextString()); - } else if (name.equals(ALLOWED_SCOPES)) { - Set allowedScopes = readSet(reader); - wlSite.setAllowedScopes(allowedScopes); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = wlSiteRepository.save(wlSite).getId(); - maps.getWhitelistedSiteOldToNewIdMap().put(currentId, newId); - } - reader.endArray(); - logger.info("Done reading whitelisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readBlacklistedSites(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - BlacklistedSite blSite = new BlacklistedSite(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals(ID)) { - reader.skipValue(); - } else if (name.equals(URI)) { - blSite.setUri(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - blSiteRepository.save(blSite); - } - reader.endArray(); - logger.info("Done reading blacklisted sites"); - } - - /** - * @param reader - * @throws IOException - */ - private void readClients(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - ClientDetailsEntity client = new ClientDetailsEntity(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(CLIENT_ID)) { - client.setClientId(reader.nextString()); - } else if (name.equals(RESOURCE_IDS)) { - Set resourceIds = readSet(reader); - client.setResourceIds(resourceIds); - } else if (name.equals(SECRET)) { - client.setClientSecret(reader.nextString()); - } else if (name.equals(SCOPE)) { - Set scope = readSet(reader); - client.setScope(scope); - } else if (name.equals(AUTHORITIES)) { - Set authorityStrs = readSet(reader); - Set authorities = new HashSet(); - for (String s : authorityStrs) { - GrantedAuthority ga = new SimpleGrantedAuthority(s); - authorities.add(ga); - } - client.setAuthorities(authorities); - } else if (name.equals(ACCESS_TOKEN_VALIDITY_SECONDS)) { - client.setAccessTokenValiditySeconds(reader.nextInt()); - } else if (name.equals(REFRESH_TOKEN_VALIDITY_SECONDS)) { - client.setRefreshTokenValiditySeconds(reader.nextInt()); - } else if (name.equals(ID_TOKEN_VALIDITY_SECONDS)) { - client.setIdTokenValiditySeconds(reader.nextInt()); - } else if (name.equals(DEVICE_CODE_VALIDITY_SECONDS)) { - client.setDeviceCodeValiditySeconds(reader.nextInt()); - } else if (name.equals(REDIRECT_URIS)) { - Set redirectUris = readSet(reader); - client.setRedirectUris(redirectUris); - } else if (name.equals(CLAIMS_REDIRECT_URIS)) { - Set claimsRedirectUris = readSet(reader); - client.setClaimsRedirectUris(claimsRedirectUris); - } else if (name.equals(NAME)) { - client.setClientName(reader.nextString()); - } else if (name.equals(URI)) { - client.setClientUri(reader.nextString()); - } else if (name.equals(LOGO_URI)) { - client.setLogoUri(reader.nextString()); - } else if (name.equals(CONTACTS)) { - Set contacts = readSet(reader); - client.setContacts(contacts); - } else if (name.equals(TOS_URI)) { - client.setTosUri(reader.nextString()); - } else if (name.equals(TOKEN_ENDPOINT_AUTH_METHOD)) { - AuthMethod am = AuthMethod.getByValue(reader.nextString()); - client.setTokenEndpointAuthMethod(am); - } else if (name.equals(GRANT_TYPES)) { - Set grantTypes = readSet(reader); - client.setGrantTypes(grantTypes); - } else if (name.equals(RESPONSE_TYPES)) { - Set responseTypes = readSet(reader); - client.setResponseTypes(responseTypes); - } else if (name.equals(POLICY_URI)) { - client.setPolicyUri(reader.nextString()); - } else if (name.equals(APPLICATION_TYPE)) { - AppType appType = AppType.getByValue(reader.nextString()); - client.setApplicationType(appType); - } else if (name.equals(SECTOR_IDENTIFIER_URI)) { - client.setSectorIdentifierUri(reader.nextString()); - } else if (name.equals(SUBJECT_TYPE)) { - SubjectType st = SubjectType.getByValue(reader.nextString()); - client.setSubjectType(st); - } else if (name.equals(JWKS_URI)) { - client.setJwksUri(reader.nextString()); - } else if (name.equals(JWKS)) { - try { - client.setJwks(JWKSet.parse(reader.nextString())); - } catch (ParseException e) { - logger.error("Couldn't parse JWK Set", e); - } - } else if (name.equals(REQUEST_OBJECT_SIGNING_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setRequestObjectSigningAlg(alg); - } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ALG)) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setUserInfoEncryptedResponseAlg(alg); - } else if (name.equals(USER_INFO_ENCRYPTED_RESPONSE_ENC)) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setUserInfoEncryptedResponseEnc(alg); - } else if (name.equals(USER_INFO_SIGNED_RESPONSE_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setUserInfoSignedResponseAlg(alg); - } else if (name.equals(ID_TOKEN_SIGNED_RESPONSE_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setIdTokenSignedResponseAlg(alg); - } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ALG)) { - JWEAlgorithm alg = JWEAlgorithm.parse(reader.nextString()); - client.setIdTokenEncryptedResponseAlg(alg); - } else if (name.equals(ID_TOKEN_ENCRYPTED_RESPONSE_ENC)) { - EncryptionMethod alg = EncryptionMethod.parse(reader.nextString()); - client.setIdTokenEncryptedResponseEnc(alg); - } else if (name.equals(TOKEN_ENDPOINT_AUTH_SIGNING_ALG)) { - JWSAlgorithm alg = JWSAlgorithm.parse(reader.nextString()); - client.setTokenEndpointAuthSigningAlg(alg); - } else if (name.equals(DEFAULT_MAX_AGE)) { - client.setDefaultMaxAge(reader.nextInt()); - } else if (name.equals(REQUIRE_AUTH_TIME)) { - client.setRequireAuthTime(reader.nextBoolean()); - } else if (name.equals(DEFAULT_ACR_VALUES)) { - Set defaultACRvalues = readSet(reader); - client.setDefaultACRvalues(defaultACRvalues); - } else if (name.equals("initiateLoginUri")) { - client.setInitiateLoginUri(reader.nextString()); - } else if (name.equals(POST_LOGOUT_REDIRECT_URI)) { - Set postLogoutUris = readSet(reader); - client.setPostLogoutRedirectUris(postLogoutUris); - } else if (name.equals(REQUEST_URIS)) { - Set requestUris = readSet(reader); - client.setRequestUris(requestUris); - } else if (name.equals(DESCRIPTION)) { - client.setClientDescription(reader.nextString()); - } else if (name.equals(ALLOW_INTROSPECTION)) { - client.setAllowIntrospection(reader.nextBoolean()); - } else if (name.equals(REUSE_REFRESH_TOKEN)) { - client.setReuseRefreshToken(reader.nextBoolean()); - } else if (name.equals(CLEAR_ACCESS_TOKENS_ON_REFRESH)) { - client.setClearAccessTokensOnRefresh(reader.nextBoolean()); - } else if (name.equals(DYNAMICALLY_REGISTERED)) { - client.setDynamicallyRegistered(reader.nextBoolean()); - } else if (name.equals(CODE_CHALLENGE_METHOD)) { - client.setCodeChallengeMethod(PKCEAlgorithm.parse(reader.nextString())); - } else if (name.equals(SOFTWARE_ID)) { - client.setSoftwareId(reader.nextString()); - } else if (name.equals(SOFTWARE_VERSION)) { - client.setSoftwareVersion(reader.nextString()); - } else if (name.equals(SOFTWARE_STATEMENT)) { - try { - client.setSoftwareStatement(JWTParser.parse(reader.nextString())); - } catch (ParseException e) { - logger.error("Couldn't parse software statement", e); - } - } else if (name.equals(CREATION_DATE)) { - Date date = utcToDate(reader.nextString()); - client.setCreatedAt(date); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - clientRepository.saveClient(client); - } - reader.endArray(); - logger.info("Done reading clients"); - } - - /** - * Read the list of system scopes from the reader and insert them into the - * scope repository. - * - * @param reader - * @throws IOException - */ - private void readSystemScopes(JsonReader reader) throws IOException { - reader.beginArray(); - while (reader.hasNext()) { - SystemScope scope = new SystemScope(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(VALUE)) { - scope.setValue(reader.nextString()); - } else if (name.equals(DESCRIPTION)) { - scope.setDescription(reader.nextString()); - } else if (name.equals(RESTRICTED)) { - scope.setRestricted(reader.nextBoolean()); - } else if (name.equals(DEFAULT_SCOPE)) { - scope.setDefaultScope(reader.nextBoolean()); - } else if (name.equals(ICON)) { - scope.setIcon(reader.nextString()); - } else { - logger.debug("found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - sysScopeRepository.save(scope); - } - reader.endArray(); - logger.info("Done reading system scopes"); - } - - private void fixObjectReferences() { - logger.info("Fixing object references..."); - for (Long oldRefreshTokenId : maps.getRefreshTokenToClientRefs().keySet()) { - String clientRef = maps.getRefreshTokenToClientRefs().get(oldRefreshTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setClient(client); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldRefreshTokenId : maps.getRefreshTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getRefreshTokenToAuthHolderRefs().get(oldRefreshTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - refreshToken.setAuthenticationHolder(authHolder); - tokenRepository.saveRefreshToken(refreshToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToClientRefs().keySet()) { - String clientRef = maps.getAccessTokenToClientRefs().get(oldAccessTokenId); - ClientDetailsEntity client = clientRepository.getClientByClientId(clientRef); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setClient(client); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToAuthHolderRefs().keySet()) { - Long oldAuthHolderId = maps.getAccessTokenToAuthHolderRefs().get(oldAccessTokenId); - Long newAuthHolderId = maps.getAuthHolderOldToNewIdMap().get(oldAuthHolderId); - AuthenticationHolderEntity authHolder = authHolderRepository.getById(newAuthHolderId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setAuthenticationHolder(authHolder); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldAccessTokenId : maps.getAccessTokenToRefreshTokenRefs().keySet()) { - Long oldRefreshTokenId = maps.getAccessTokenToRefreshTokenRefs().get(oldAccessTokenId); - Long newRefreshTokenId = maps.getRefreshTokenOldToNewIdMap().get(oldRefreshTokenId); - OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenById(newRefreshTokenId); - Long newAccessTokenId = maps.getAccessTokenOldToNewIdMap().get(oldAccessTokenId); - OAuth2AccessTokenEntity accessToken = tokenRepository.getAccessTokenById(newAccessTokenId); - accessToken.setRefreshToken(refreshToken); - tokenRepository.saveAccessToken(accessToken); - } - for (Long oldGrantId : maps.getGrantToAccessTokensRefs().keySet()) { - Set oldAccessTokenIds = maps.getGrantToAccessTokensRefs().get(oldGrantId); - - Long newGrantId = maps.getGrantOldToNewIdMap().get(oldGrantId); - ApprovedSite site = approvedSiteRepository.getById(newGrantId); - - for(Long oldTokenId : oldAccessTokenIds) { - Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(oldTokenId); - OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId); - token.setApprovedSite(site); - tokenRepository.saveAccessToken(token); - } - - approvedSiteRepository.save(site); - } - /* - refreshTokenToClientRefs.clear(); - refreshTokenToAuthHolderRefs.clear(); - accessTokenToClientRefs.clear(); - accessTokenToAuthHolderRefs.clear(); - accessTokenToRefreshTokenRefs.clear(); - refreshTokenOldToNewIdMap.clear(); - accessTokenOldToNewIdMap.clear(); - grantOldToNewIdMap.clear(); - */ - logger.info("Done fixing object references."); - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MatchLoginHintsAgainstUsers.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MatchLoginHintsAgainstUsers.java deleted file mode 100644 index 74d98ea31b..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MatchLoginHintsAgainstUsers.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.LoginHintExtracter; -import org.mitre.openid.connect.service.UserInfoService; -import org.springframework.beans.factory.annotation.Autowired; - -import com.google.common.base.Strings; - -/** - * Checks the login hint against the User Info collection, only populates it if a user is found. - * @author jricher - * - */ -public class MatchLoginHintsAgainstUsers implements LoginHintExtracter { - - @Autowired - private UserInfoService userInfoService; - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.LoginHintTester#useHint(java.lang.String) - */ - @Override - public String extractHint(String loginHint) { - if (Strings.isNullOrEmpty(loginHint)) { - return null; - } else { - UserInfo user = userInfoService.getByEmailAddress(loginHint); - if (user == null) { - user = userInfoService.getByUsername(loginHint); - if (user == null) { - return null; - } else { - return user.getPreferredUsername(); - } - } else { - return user.getPreferredUsername(); - } - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/PassAllLoginHints.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/PassAllLoginHints.java deleted file mode 100644 index b1894466b6..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/PassAllLoginHints.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import org.mitre.openid.connect.service.LoginHintExtracter; - -/** - * Sends all login hints through to the login page regardless of setup. - * - * @author jricher - * - */ -public class PassAllLoginHints implements LoginHintExtracter { - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.LoginHintTester#useHint(java.lang.String) - */ - @Override - public String extractHint(String loginHint) { - return loginHint; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/RemoveLoginHintsWithHTTP.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/RemoveLoginHintsWithHTTP.java index eab1585c20..bd45eff941 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/RemoveLoginHintsWithHTTP.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/RemoveLoginHintsWithHTTP.java @@ -28,20 +28,22 @@ */ public class RemoveLoginHintsWithHTTP implements LoginHintExtracter { - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.LoginHintTester#useHint(java.lang.String) - */ - @Override - public String extractHint(String loginHint) { - if (Strings.isNullOrEmpty(loginHint)) { - return null; - } else { - if (loginHint.startsWith("http")) { - return null; - } else { - return loginHint; - } - } - } + /* + * (non-Javadoc) + * + * @see org.mitre.openid.connect.service.LoginHintTester#useHint(java.lang.String) + */ + @Override + public String extractHint(String loginHint) { + if (Strings.isNullOrEmpty(loginHint)) { + return null; + } else { + if (loginHint.startsWith("http")) { + return null; + } else { + return loginHint; + } + } + } } diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java deleted file mode 100644 index d5b6a9cdc0..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/ConnectTokenEnhancer.java +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.token; - -import java.util.Date; -import java.util.UUID; - -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.OIDCTokenService; -import org.mitre.openid.connect.service.UserInfoService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.security.oauth2.provider.token.TokenEnhancer; -import org.springframework.stereotype.Service; - -import com.google.common.base.Strings; -import com.google.common.collect.Lists; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.JWTClaimsSet.Builder; -import com.nimbusds.jwt.SignedJWT; - -@Service -public class ConnectTokenEnhancer implements TokenEnhancer { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(ConnectTokenEnhancer.class); - - @Autowired - private ConfigurationPropertiesBean configBean; - - @Autowired - private JWTSigningAndValidationService jwtService; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private UserInfoService userInfoService; - - @Autowired - private OIDCTokenService connectTokenService; - - @Override - public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { - - OAuth2AccessTokenEntity token = (OAuth2AccessTokenEntity) accessToken; - OAuth2Request originalAuthRequest = authentication.getOAuth2Request(); - - String clientId = originalAuthRequest.getClientId(); - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - Builder builder = new JWTClaimsSet.Builder() - .claim("azp", clientId) - .issuer(configBean.getIssuer()) - .issueTime(new Date()) - .expirationTime(token.getExpiration()) - .subject(authentication.getName()) - .jwtID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it - - String audience = (String) authentication.getOAuth2Request().getExtensions().get("aud"); - if (!Strings.isNullOrEmpty(audience)) { - builder.audience(Lists.newArrayList(audience)); - } - - addCustomAccessTokenClaims(builder, token, authentication); - - JWTClaimsSet claims = builder.build(); - - JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); - JWSHeader header = new JWSHeader(signingAlg, null, null, null, null, null, null, null, null, null, - jwtService.getDefaultSignerKeyId(), - null, null); - SignedJWT signed = new SignedJWT(header, claims); - - jwtService.signJwt(signed); - - token.setJwt(signed); - - /** - * Authorization request scope MUST include "openid" in OIDC, but access token request - * may or may not include the scope parameter. As long as the AuthorizationRequest - * has the proper scope, we can consider this a valid OpenID Connect request. Otherwise, - * we consider it to be a vanilla OAuth2 request. - * - * Also, there must be a user authentication involved in the request for it to be considered - * OIDC and not OAuth, so we check for that as well. - */ - if (originalAuthRequest.getScope().contains(SystemScopeService.OPENID_SCOPE) - && !authentication.isClientOnly()) { - - String username = authentication.getName(); - UserInfo userInfo = userInfoService.getByUsernameAndClientId(username, clientId); - - if (userInfo != null) { - - JWT idToken = connectTokenService.createIdToken(client, - originalAuthRequest, claims.getIssueTime(), - userInfo.getSub(), token); - - // attach the id token to the parent access token - token.setIdToken(idToken); - } else { - // can't create an id token if we can't find the user - logger.warn("Request for ID token when no user is present."); - } - } - - return token; - } - - public ConfigurationPropertiesBean getConfigBean() { - return configBean; - } - - public void setConfigBean(ConfigurationPropertiesBean configBean) { - this.configBean = configBean; - } - - public JWTSigningAndValidationService getJwtService() { - return jwtService; - } - - public void setJwtService(JWTSigningAndValidationService jwtService) { - this.jwtService = jwtService; - } - - public ClientDetailsEntityService getClientService() { - return clientService; - } - - public void setClientService(ClientDetailsEntityService clientService) { - this.clientService = clientService; - } - - - /** - * Hook for subclasses that allows adding custom claims to the JWT that will be used as access token. - * @param builder the builder holding the current claims - * @param token the un-enhanced token - * @param authentication current authentication - */ - protected void addCustomAccessTokenClaims(JWTClaimsSet.Builder builder, OAuth2AccessTokenEntity token, - OAuth2Authentication authentication) { - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java deleted file mode 100644 index 821b1fafb6..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java +++ /dev/null @@ -1,271 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.token; - -import static org.mitre.openid.connect.request.ConnectRequestParameters.APPROVED_SITE; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_CONSENT; -import static org.mitre.openid.connect.request.ConnectRequestParameters.PROMPT_SEPARATOR; - -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.HttpSession; - -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.service.ApprovedSiteService; -import org.mitre.openid.connect.service.WhitelistedSiteService; -import org.mitre.openid.connect.web.AuthenticationTimeStamper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.provider.AuthorizationRequest; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.ClientDetailsService; -import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; -import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Sets; - -/** - * Custom User Approval Handler implementation which uses a concept of a whitelist, - * blacklist, and greylist. - * - * Blacklisted sites will be caught and handled before this - * point. - * - * Whitelisted sites will be automatically approved, and an ApprovedSite entry will - * be created for the site the first time a given user access it. - * - * All other sites fall into the greylist - the user will be presented with the user - * approval page upon their first visit - * @author aanganes - * - */ -@Component("tofuUserApprovalHandler") -public class TofuUserApprovalHandler implements UserApprovalHandler { - - @Autowired - private ApprovedSiteService approvedSiteService; - - @Autowired - private WhitelistedSiteService whitelistedSiteService; - - @Autowired - private ClientDetailsService clientDetailsService; - - @Autowired - private SystemScopeService systemScopes; - - /** - * Check if the user has already stored a positive approval decision for this site; or if the - * site is whitelisted, approve it automatically. - * - * Otherwise, return false so that the user will see the approval page and can make their own decision. - * - * @param authorizationRequest the incoming authorization request - * @param userAuthentication the Principal representing the currently-logged-in user - * - * @return true if the site is approved, false otherwise - */ - @Override - public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { - - // if this request is already approved, pass that info through - // (this flag may be set by updateBeforeApproval, which can also do funny things with scopes, etc) - if (authorizationRequest.isApproved()) { - return true; - } else { - // if not, check to see if the user has approved it - // TODO: make parameter name configurable? - return Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval")); - } - - } - - /** - * Check if the user has already stored a positive approval decision for this site; or if the - * site is whitelisted, approve it automatically. - * - * Otherwise the user will be directed to the approval page and can make their own decision. - * - * @param authorizationRequest the incoming authorization request - * @param userAuthentication the Principal representing the currently-logged-in user - * - * @return the updated AuthorizationRequest - */ - @Override - public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { - - //First, check database to see if the user identified by the userAuthentication has stored an approval decision - - String userId = userAuthentication.getName(); - String clientId = authorizationRequest.getClientId(); - - //lookup ApprovedSites by userId and clientId - boolean alreadyApproved = false; - - // find out if we're supposed to force a prompt on the user or not - String prompt = (String) authorizationRequest.getExtensions().get(PROMPT); - List prompts = Splitter.on(PROMPT_SEPARATOR).splitToList(Strings.nullToEmpty(prompt)); - if (!prompts.contains(PROMPT_CONSENT)) { - // if the prompt parameter is set to "consent" then we can't use approved sites or whitelisted sites - // otherwise, we need to check them below - - Collection aps = approvedSiteService.getByClientIdAndUserId(clientId, userId); - for (ApprovedSite ap : aps) { - - if (!ap.isExpired()) { - - // if we find one that fits... - if (systemScopes.scopesMatch(ap.getAllowedScopes(), authorizationRequest.getScope())) { - - //We have a match; update the access date on the AP entry and return true. - ap.setAccessDate(new Date()); - approvedSiteService.save(ap); - - String apId = ap.getId().toString(); - authorizationRequest.getExtensions().put(APPROVED_SITE, apId); - authorizationRequest.setApproved(true); - alreadyApproved = true; - - setAuthTime(authorizationRequest); - } - } - } - - if (!alreadyApproved) { - WhitelistedSite ws = whitelistedSiteService.getByClientId(clientId); - if (ws != null && systemScopes.scopesMatch(ws.getAllowedScopes(), authorizationRequest.getScope())) { - authorizationRequest.setApproved(true); - - setAuthTime(authorizationRequest); - } - } - } - - return authorizationRequest; - - } - - - @Override - public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { - - String userId = userAuthentication.getName(); - String clientId = authorizationRequest.getClientId(); - ClientDetails client = clientDetailsService.loadClientByClientId(clientId); - - // This must be re-parsed here because SECOAUTH forces us to call things in a strange order - if (Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval"))) { - - authorizationRequest.setApproved(true); - - // process scopes from user input - Set allowedScopes = Sets.newHashSet(); - Map approvalParams = authorizationRequest.getApprovalParameters(); - - Set keys = approvalParams.keySet(); - - for (String key : keys) { - if (key.startsWith("scope_")) { - //This is a scope parameter from the approval page. The value sent back should - //be the scope string. Check to make sure it is contained in the client's - //registered allowed scopes. - - String scope = approvalParams.get(key); - Set approveSet = Sets.newHashSet(scope); - - //Make sure this scope is allowed for the given client - if (systemScopes.scopesMatch(client.getScope(), approveSet)) { - - allowedScopes.add(scope); - } - - } - } - - // inject the user-allowed scopes into the auth request - authorizationRequest.setScope(allowedScopes); - - //Only store an ApprovedSite if the user has checked "remember this decision": - String remember = authorizationRequest.getApprovalParameters().get("remember"); - if (!Strings.isNullOrEmpty(remember) && !remember.equals("none")) { - - Date timeout = null; - if (remember.equals("one-hour")) { - // set the timeout to one hour from now - Calendar cal = Calendar.getInstance(); - cal.add(Calendar.HOUR, 1); - timeout = cal.getTime(); - } - - ApprovedSite newSite = approvedSiteService.createApprovedSite(clientId, userId, timeout, allowedScopes); - String newSiteId = newSite.getId().toString(); - authorizationRequest.getExtensions().put(APPROVED_SITE, newSiteId); - } - - setAuthTime(authorizationRequest); - - - } - - return authorizationRequest; - } - - /** - * Get the auth time out of the current session and add it to the - * auth request in the extensions map. - * - * @param authorizationRequest - */ - private void setAuthTime(AuthorizationRequest authorizationRequest) { - // Get the session auth time, if we have it, and store it in the request - ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); - if (attr != null) { - HttpSession session = attr.getRequest().getSession(); - if (session != null) { - Date authTime = (Date) session.getAttribute(AuthenticationTimeStamper.AUTH_TIMESTAMP); - if (authTime != null) { - String authTimeString = Long.toString(authTime.getTime()); - authorizationRequest.getExtensions().put(AuthenticationTimeStamper.AUTH_TIMESTAMP, authTimeString); - } - } - } - } - - @Override - public Map getUserApprovalRequest(AuthorizationRequest authorizationRequest, - Authentication userAuthentication) { - Map model = new HashMap<>(); - // In case of a redirect we might want the request parameters to be included - model.putAll(authorizationRequest.getRequestParameters()); - return model; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/AuthenticationTimeStamper.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/AuthenticationTimeStamper.java deleted file mode 100644 index 4b5bd4c2e0..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/AuthenticationTimeStamper.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.web; - -import java.io.IOException; -import java.util.Date; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.mitre.openid.connect.filter.AuthorizationRequestFilter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.stereotype.Component; - -/** - * This class sets a timestamp on the current HttpSession - * when someone successfully authenticates. - * - * @author jricher - * - */ -@Component("authenticationTimeStamper") -public class AuthenticationTimeStamper extends SavedRequestAwareAuthenticationSuccessHandler { - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(AuthenticationTimeStamper.class); - - public static final String AUTH_TIMESTAMP = "AUTH_TIMESTAMP"; - - /** - * Set the timestamp on the session to mark when the authentication happened, - * useful for calculating authentication age. This gets stored in the sesion - * and can get pulled out by other components. - */ - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - - Date authTimestamp = new Date(); - - HttpSession session = request.getSession(); - - session.setAttribute(AUTH_TIMESTAMP, authTimestamp); - - if (session.getAttribute(AuthorizationRequestFilter.PROMPT_REQUESTED) != null) { - session.setAttribute(AuthorizationRequestFilter.PROMPTED, Boolean.TRUE); - session.removeAttribute(AuthorizationRequestFilter.PROMPT_REQUESTED); - } - - logger.info("Successful Authentication of " + authentication.getName() + " at " + authTimestamp.toString()); - - super.onAuthenticationSuccess(request, response, authentication); - - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java deleted file mode 100644 index 773b331df9..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ClientAPI.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.web; - -import java.util.Collection; - -import org.mitre.jwt.assertion.AssertionValidator; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.web.AuthenticationUtilities; -import org.mitre.openid.connect.model.CachedImage; -import org.mitre.openid.connect.service.ClientLogoLoadingService; -import org.mitre.openid.connect.view.ClientEntityViewForAdmins; -import org.mitre.openid.connect.view.ClientEntityViewForUsers; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.common.base.Strings; - -/** - * @author Michael Jett - */ - -@Controller -@RequestMapping("/" + ClientAPI.URL) -@PreAuthorize("hasRole('ROLE_USER')") -public class ClientAPI { - - public static final String URL = RootController.API_URL + "/clients"; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private ClientLogoLoadingService clientLogoLoadingService; - - @Autowired - @Qualifier("clientAssertionValidator") - private AssertionValidator assertionValidator; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(ClientAPI.class); - - /** - * Get a list of all clients - * - * @param modelAndView - * @return - */ - @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public String apiGetAllClients(Model model, Authentication auth) { - - Collection clients = clientService.getAllClients(); - model.addAttribute(JsonEntityView.ENTITY, clients); - - if (AuthenticationUtilities.isAdmin(auth)) { - return ClientEntityViewForAdmins.VIEWNAME; - } - return ClientEntityViewForUsers.VIEWNAME; - } - - /** - * Get an individual client - * - * @param id - * @param modelAndView - * @return - */ - @RequestMapping(value = "/{id}", method = RequestMethod.GET, - produces = MediaType.APPLICATION_JSON_VALUE) - public String apiShowClient(@PathVariable("id") Long id, Model model, Authentication auth) { - - ClientDetailsEntity client = clientService.getClientById(id); - - if (client == null) { - logger.error("apiShowClient failed; client with id " + id + " could not be found."); - model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - model.addAttribute(JsonErrorView.ERROR_MESSAGE, - "The requested client with id " + id + " could not be found."); - return JsonErrorView.VIEWNAME; - } - - model.addAttribute(JsonEntityView.ENTITY, client); - - if (AuthenticationUtilities.isAdmin(auth)) { - return ClientEntityViewForAdmins.VIEWNAME; - } - return ClientEntityViewForUsers.VIEWNAME; - } - - @RequestMapping(value = "/{id}/logo", method = RequestMethod.GET, - produces = {MediaType.IMAGE_GIF_VALUE, MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE}) - public ResponseEntity getClientLogo(@PathVariable("id") Long id, Model model) { - - ClientDetailsEntity client = clientService.getClientById(id); - - if (client == null) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } else if (Strings.isNullOrEmpty(client.getLogoUri())) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } else { - // get the image from cache - CachedImage image = clientLogoLoadingService.getLogo(client); - - if (image == null) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.parseMediaType(image.getContentType())); - headers.setContentLength(image.getLength()); - - return new ResponseEntity<>(image.getData(), headers, HttpStatus.OK); - } - } -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/DataAPI.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/DataAPI.java deleted file mode 100644 index 84b0de503b..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/DataAPI.java +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.web; - -import java.io.IOException; -import java.io.Reader; -import java.security.Principal; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; - -import javax.servlet.http.HttpServletResponse; - -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mitre.openid.connect.service.impl.MITREidDataService_1_3; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.common.collect.ImmutableList; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; - -/** - * API endpoint for importing and exporting the current state of a server. - * Includes all tokens, grants, whitelists, blacklists, and clients. - * - * @author jricher - * - */ -@Controller -@RequestMapping("/" + DataAPI.URL) -@PreAuthorize("hasRole('ROLE_ADMIN')") // you need to be an admin to even think about this -- this is a potentially dangerous API!! -public class DataAPI { - - public static final String URL = RootController.API_URL + "/data"; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(DataAPI.class); - - private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); - - @Autowired - private ConfigurationPropertiesBean config; - - @Autowired - private List importers; - - private List supportedVersions = ImmutableList.of( - MITREidDataService.MITREID_CONNECT_1_0, - MITREidDataService.MITREID_CONNECT_1_1, - MITREidDataService.MITREID_CONNECT_1_2, - MITREidDataService.MITREID_CONNECT_1_3); - - @Autowired - private MITREidDataService_1_3 exporter; - - @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) - public String importData(Reader in, Model m) throws IOException { - - JsonReader reader = new JsonReader(in); - - reader.beginObject(); - - while (reader.hasNext()) { - JsonToken tok = reader.peek(); - switch (tok) { - case NAME: - String name = reader.nextName(); - - if (supportedVersions.contains(name)) { - // we're working with a known data version tag - for (MITREidDataService dataService : importers) { - // dispatch to the correct service - if (dataService.supportsVersion(name)) { - dataService.importData(reader); - break; - } - } - } else { - // consume the next bit silently for now - logger.debug("Skipping value for " + name); // TODO: write these out? - reader.skipValue(); - } - break; - case END_OBJECT: - break; - case END_DOCUMENT: - break; - } - } - - reader.endObject(); - - return "httpCodeView"; - } - - @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) - public void exportData(HttpServletResponse resp, Principal prin) throws IOException { - - resp.setContentType(MediaType.APPLICATION_JSON_VALUE); - - // this writer puts things out onto the wire - JsonWriter writer = new JsonWriter(resp.getWriter()); - writer.setIndent(" "); - - try { - - writer.beginObject(); - - writer.name("exported-at"); - writer.value(dateFormat.format(new Date())); - - writer.name("exported-from"); - writer.value(config.getIssuer()); - - writer.name("exported-by"); - writer.value(prin.getName()); - - // delegate to the service to do the actual export - exporter.exportData(writer); - - writer.endObject(); // end root - writer.close(); - - } catch (IOException e) { - logger.error("Unable to export data", e); - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/EndSessionEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/EndSessionEndpoint.java deleted file mode 100644 index 26055501a4..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/EndSessionEndpoint.java +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.web; - -import java.text.ParseException; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.mitre.jwt.assertion.AssertionValidator; -import org.mitre.jwt.assertion.impl.SelfAssertionValidator; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.UserInfoService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; -import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.web.util.UriUtils; - -import com.google.common.base.Strings; -import com.google.common.collect.Iterables; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.JWTParser; - -/** - * Implementation of the End Session Endpoint from OIDC session management - * - * @author jricher - * - */ -@Controller -public class EndSessionEndpoint { - - public static final String URL = "endsession"; - - private static final String CLIENT_KEY = "client"; - private static final String STATE_KEY = "state"; - private static final String REDIRECT_URI_KEY = "redirectUri"; - - private static Logger logger = LoggerFactory.getLogger(EndSessionEndpoint.class); - - @Autowired - private SelfAssertionValidator validator; - - @Autowired - private UserInfoService userInfoService; - - @Autowired - private ClientDetailsEntityService clientService; - - @RequestMapping(value = "/" + URL, method = RequestMethod.GET) - public String endSession(@RequestParam (value = "id_token_hint", required = false) String idTokenHint, - @RequestParam (value = "post_logout_redirect_uri", required = false) String postLogoutRedirectUri, - @RequestParam (value = STATE_KEY, required = false) String state, - HttpServletRequest request, - HttpServletResponse response, - HttpSession session, - Authentication auth, Model m) { - - // conditionally filled variables - JWTClaimsSet idTokenClaims = null; // pulled from the parsed and validated ID token - ClientDetailsEntity client = null; // pulled from ID token's audience field - - if (!Strings.isNullOrEmpty(postLogoutRedirectUri)) { - session.setAttribute(REDIRECT_URI_KEY, postLogoutRedirectUri); - } - if (!Strings.isNullOrEmpty(state)) { - session.setAttribute(STATE_KEY, state); - } - - // parse the ID token hint to see if it's valid - if (!Strings.isNullOrEmpty(idTokenHint)) { - try { - JWT idToken = JWTParser.parse(idTokenHint); - - if (validator.isValid(idToken)) { - // we issued this ID token, figure out who it's for - idTokenClaims = idToken.getJWTClaimsSet(); - - String clientId = Iterables.getOnlyElement(idTokenClaims.getAudience()); - - client = clientService.loadClientByClientId(clientId); - - // save a reference in the session for us to pick up later - //session.setAttribute("endSession_idTokenHint_claims", idTokenClaims); - session.setAttribute(CLIENT_KEY, client); - } - } catch (ParseException e) { - // it's not a valid ID token, ignore it - logger.debug("Invalid id token hint", e); - } catch (InvalidClientException e) { - // couldn't find the client, ignore it - logger.debug("Invalid client", e); - } - } - - // are we logged in or not? - if (auth == null || !request.isUserInRole("ROLE_USER")) { - // we're not logged in anyway, process the final redirect bits if needed - return processLogout(null, request, response, session, auth, m); - } else { - // we are logged in, need to prompt the user before we log out - - // see who the current user is - UserInfo ui = userInfoService.getByUsername(auth.getName()); - - if (idTokenClaims != null) { - String subject = idTokenClaims.getSubject(); - // see if the current user is the same as the one in the ID token - // TODO: should we do anything different in these cases? - if (!Strings.isNullOrEmpty(subject) && subject.equals(ui.getSub())) { - // it's the same user - } else { - // it's not the same user - } - } - - m.addAttribute("client", client); - m.addAttribute("idToken", idTokenClaims); - - // display the log out confirmation page - return "logoutConfirmation"; - } - } - - @RequestMapping(value = "/" + URL, method = RequestMethod.POST) - public String processLogout(@RequestParam(value = "approve", required = false) String approved, - HttpServletRequest request, - HttpServletResponse response, - HttpSession session, - Authentication auth, Model m) { - - String redirectUri = (String) session.getAttribute(REDIRECT_URI_KEY); - String state = (String) session.getAttribute(STATE_KEY); - ClientDetailsEntity client = (ClientDetailsEntity) session.getAttribute(CLIENT_KEY); - - if (!Strings.isNullOrEmpty(approved)) { - // use approved, perform the logout - if (auth != null){ - new SecurityContextLogoutHandler().logout(request, response, auth); - } - SecurityContextHolder.getContext().setAuthentication(null); - // TODO: hook into other logout post-processing - } - - // if the user didn't approve, don't log out but hit the landing page anyway for redirect as needed - - - - // if we have a client AND the client has post-logout redirect URIs - // registered AND the URI given is in that list, then... - if (!Strings.isNullOrEmpty(redirectUri) && - client != null && client.getPostLogoutRedirectUris() != null) { - - if (client.getPostLogoutRedirectUris().contains(redirectUri)) { - // TODO: future, add the redirect URI to the model for the display page for an interstitial - // m.addAttribute("redirectUri", postLogoutRedirectUri); - - UriComponents uri = UriComponentsBuilder.fromHttpUrl(redirectUri).queryParam("state", state).build(); - - return "redirect:" + uri; - } - } - - // otherwise, return to a nice post-logout landing page - return "postLogout"; - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java deleted file mode 100644 index de667331ad..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/ProtectedResourceRegistrationEndpoint.java +++ /dev/null @@ -1,489 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.web; - -import java.text.ParseException; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.RegisteredClient; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.exception.ValidationException; -import org.mitre.openid.connect.service.OIDCTokenService; -import org.mitre.openid.connect.view.ClientInformationResponseView; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.util.UriUtils; - -import com.google.common.base.Strings; -import com.google.gson.JsonSyntaxException; - -@Controller -@RequestMapping(value = ProtectedResourceRegistrationEndpoint.URL) -public class ProtectedResourceRegistrationEndpoint { - - /** - * - */ - public static final String URL = "resource"; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private OAuth2TokenEntityService tokenService; - - @Autowired - private SystemScopeService scopeService; - - @Autowired - private ConfigurationPropertiesBean config; - - @Autowired - private OIDCTokenService connectTokenService; - - /** - * Logger for this class - */ - private static final Logger logger = - LoggerFactory.getLogger(ProtectedResourceRegistrationEndpoint.class); - - /** - * Create a new Client, issue a client ID, and create a registration access token. - * - * @param jsonString - * @param m - * @param p - * @return - */ - @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - public String registerNewProtectedResource(@RequestBody String jsonString, Model m) { - - ClientDetailsEntity newClient = null; - try { - newClient = ClientDetailsEntityJsonProcessor.parse(jsonString); - } catch (JsonSyntaxException e) { - // bad parse - // didn't parse, this is a bad request - logger.error("registerNewProtectedResource failed; submitted JSON is malformed"); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400 - return HttpCodeView.VIEWNAME; - } - - if (newClient != null) { - // it parsed! - - // - // Now do some post-processing consistency checks on it - // - - // clear out any spurious id/secret (clients don't get to pick) - newClient.setClientId(null); - newClient.setClientSecret(null); - - // do validation on the fields - try { - newClient = validateScopes(newClient); - newClient = validateAuth(newClient); - } catch (ValidationException ve) { - // validation failed, return an error - m.addAttribute(JsonErrorView.ERROR, ve.getError()); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, ve.getErrorDescription()); - m.addAttribute(HttpCodeView.CODE, ve.getStatus()); - return JsonErrorView.VIEWNAME; - } - - - // no grant types are allowed - newClient.setGrantTypes(new HashSet()); - newClient.setResponseTypes(new HashSet()); - newClient.setRedirectUris(new HashSet()); - - // don't issue tokens to this client - newClient.setAccessTokenValiditySeconds(0); - newClient.setIdTokenValiditySeconds(0); - newClient.setRefreshTokenValiditySeconds(0); - - // clear out unused fields - newClient.setDefaultACRvalues(new HashSet()); - newClient.setDefaultMaxAge(null); - newClient.setIdTokenEncryptedResponseAlg(null); - newClient.setIdTokenEncryptedResponseEnc(null); - newClient.setIdTokenSignedResponseAlg(null); - newClient.setInitiateLoginUri(null); - newClient.setPostLogoutRedirectUris(null); - newClient.setRequestObjectSigningAlg(null); - newClient.setRequireAuthTime(null); - newClient.setReuseRefreshToken(false); - newClient.setSectorIdentifierUri(null); - newClient.setSubjectType(null); - newClient.setUserInfoEncryptedResponseAlg(null); - newClient.setUserInfoEncryptedResponseEnc(null); - newClient.setUserInfoSignedResponseAlg(null); - - // this client has been dynamically registered (obviously) - newClient.setDynamicallyRegistered(true); - - // this client has access to the introspection endpoint - newClient.setAllowIntrospection(true); - - // now save it - try { - ClientDetailsEntity savedClient = clientService.saveNewClient(newClient); - - // generate the registration access token - OAuth2AccessTokenEntity token = connectTokenService.createResourceAccessToken(savedClient); - tokenService.saveAccessToken(token); - - // send it all out to the view - - RegisteredClient registered = - new RegisteredClient(savedClient, token.getValue(), config.getIssuer() + "resource/" - + UriUtils.encodePathSegment(savedClient.getClientId(), "UTF-8")); - m.addAttribute("client", registered); - m.addAttribute(HttpCodeView.CODE, HttpStatus.CREATED); // http 201 - - return ClientInformationResponseView.VIEWNAME; - } catch (IllegalArgumentException e) { - logger.error("Couldn't save client", e); - - m.addAttribute(JsonErrorView.ERROR, "invalid_client_metadata"); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, - "Unable to save client due to invalid or inconsistent metadata."); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400 - - return JsonErrorView.VIEWNAME; - } - } else { - // didn't parse, this is a bad request - logger.error("registerNewClient failed; submitted JSON is malformed"); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400 - - return HttpCodeView.VIEWNAME; - } - - } - - private ClientDetailsEntity validateScopes(ClientDetailsEntity newClient) - throws ValidationException { - // scopes that the client is asking for - Set requestedScopes = scopeService.fromStrings(newClient.getScope()); - - // the scopes that the client can have must be a subset of the dynamically allowed scopes - Set allowedScopes = requestedScopes.stream() - .filter(s -> !s.isRestricted() && !SystemScopeService.reservedValues.contains(s.getValue())) - .collect(Collectors.toSet()); - - // if the client didn't ask for any, give them the defaults - if (allowedScopes == null || allowedScopes.isEmpty()) { - allowedScopes = scopeService.getDefaults(); - } - - newClient.setScope(scopeService.toStrings(allowedScopes)); - - return newClient; - } - - /** - * Get the meta information for a client. - * - * @param clientId - * @param m - * @param auth - * @return - */ - @PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" - + SystemScopeService.RESOURCE_TOKEN_SCOPE + "')") - @RequestMapping(value = "/{id}", method = RequestMethod.GET, - produces = MediaType.APPLICATION_JSON_VALUE) - public String readResourceConfiguration(@PathVariable("id") String clientId, Model m, - OAuth2Authentication auth) { - - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - if (client != null && client.getClientId().equals(auth.getOAuth2Request().getClientId())) { - - // possibly update the token - OAuth2AccessTokenEntity token = fetchValidRegistrationToken(auth, client); - - RegisteredClient registered = - new RegisteredClient(client, token.getValue(), config.getIssuer() + "resource/" - + UriUtils.encodePathSegment(client.getClientId(), "UTF-8")); - - // send it all out to the view - m.addAttribute("client", registered); - m.addAttribute(HttpCodeView.CODE, HttpStatus.OK); // http 200 - - return ClientInformationResponseView.VIEWNAME; - - } else { - // client mismatch - logger.error("readResourceConfiguration failed, client ID mismatch: " + clientId + " and " - + auth.getOAuth2Request().getClientId() + " do not match."); - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); // http 403 - - return HttpCodeView.VIEWNAME; - } - } - - /** - * Update the metainformation for a given client. - * - * @param clientId - * @param jsonString - * @param m - * @param auth - * @return - */ - @PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" - + SystemScopeService.RESOURCE_TOKEN_SCOPE + "')") - @RequestMapping(value = "/{id}", method = RequestMethod.PUT, - produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) - public String updateProtectedResource(@PathVariable("id") String clientId, - @RequestBody String jsonString, Model m, OAuth2Authentication auth) { - - - ClientDetailsEntity newClient = null; - try { - newClient = ClientDetailsEntityJsonProcessor.parse(jsonString); - } catch (JsonSyntaxException e) { - // bad parse - // didn't parse, this is a bad request - logger.error("updateProtectedResource failed; submitted JSON is malformed"); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400 - return HttpCodeView.VIEWNAME; - } - - ClientDetailsEntity oldClient = clientService.loadClientByClientId(clientId); - - if (newClient != null && oldClient != null // we have an existing client and the new one parsed - && oldClient.getClientId().equals(auth.getOAuth2Request().getClientId()) // the client - // passed in the - // URI matches the - // one in the auth - && oldClient.getClientId().equals(newClient.getClientId()) // the client passed in the body - // matches the one in the URI - ) { - - // a client can't ask to update its own client secret to any particular value - newClient.setClientSecret(oldClient.getClientSecret()); - - newClient.setCreatedAt(oldClient.getCreatedAt()); - - // no grant types are allowed - newClient.setGrantTypes(new HashSet()); - newClient.setResponseTypes(new HashSet()); - newClient.setRedirectUris(new HashSet()); - - // don't issue tokens to this client - newClient.setAccessTokenValiditySeconds(0); - newClient.setIdTokenValiditySeconds(0); - newClient.setRefreshTokenValiditySeconds(0); - - // clear out unused fields - newClient.setDefaultACRvalues(new HashSet()); - newClient.setDefaultMaxAge(null); - newClient.setIdTokenEncryptedResponseAlg(null); - newClient.setIdTokenEncryptedResponseEnc(null); - newClient.setIdTokenSignedResponseAlg(null); - newClient.setInitiateLoginUri(null); - newClient.setPostLogoutRedirectUris(null); - newClient.setRequestObjectSigningAlg(null); - newClient.setRequireAuthTime(null); - newClient.setReuseRefreshToken(false); - newClient.setSectorIdentifierUri(null); - newClient.setSubjectType(null); - newClient.setUserInfoEncryptedResponseAlg(null); - newClient.setUserInfoEncryptedResponseEnc(null); - newClient.setUserInfoSignedResponseAlg(null); - - // this client has been dynamically registered (obviously) - newClient.setDynamicallyRegistered(true); - - // this client has access to the introspection endpoint - newClient.setAllowIntrospection(true); - - // do validation on the fields - try { - newClient = validateScopes(newClient); - newClient = validateAuth(newClient); - } catch (ValidationException ve) { - // validation failed, return an error - m.addAttribute(JsonErrorView.ERROR, ve.getError()); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, ve.getErrorDescription()); - m.addAttribute(HttpCodeView.CODE, ve.getStatus()); - return JsonErrorView.VIEWNAME; - } - - - try { - // save the client - ClientDetailsEntity savedClient = clientService.updateClient(oldClient, newClient); - - // possibly update the token - OAuth2AccessTokenEntity token = fetchValidRegistrationToken(auth, savedClient); - - RegisteredClient registered = - new RegisteredClient(savedClient, token.getValue(), config.getIssuer() + "resource/" - + UriUtils.encodePathSegment(savedClient.getClientId(), "UTF-8")); - - // send it all out to the view - m.addAttribute("client", registered); - m.addAttribute(HttpCodeView.CODE, HttpStatus.OK); // http 200 - - return ClientInformationResponseView.VIEWNAME; - } catch (IllegalArgumentException e) { - logger.error("Couldn't save client", e); - - m.addAttribute(JsonErrorView.ERROR, "invalid_client_metadata"); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, - "Unable to save client due to invalid or inconsistent metadata."); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); // http 400 - - return JsonErrorView.VIEWNAME; - } - } else { - // client mismatch - logger.error("updateProtectedResource" + " failed, client ID mismatch: " + clientId + " and " - + auth.getOAuth2Request().getClientId() + " do not match."); - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); // http 403 - - return HttpCodeView.VIEWNAME; - } - } - - /** - * Delete the indicated client from the system. - * - * @param clientId - * @param m - * @param auth - * @return - */ - @PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" - + SystemScopeService.RESOURCE_TOKEN_SCOPE + "')") - @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, - produces = MediaType.APPLICATION_JSON_VALUE) - public String deleteResource(@PathVariable("id") String clientId, Model m, - OAuth2Authentication auth) { - - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - if (client != null && client.getClientId().equals(auth.getOAuth2Request().getClientId())) { - - clientService.deleteClient(client); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT); // http 204 - - return HttpCodeView.VIEWNAME; - } else { - // client mismatch - logger.error("readClientConfiguration failed, client ID mismatch: " + clientId + " and " - + auth.getOAuth2Request().getClientId() + " do not match."); - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); // http 403 - - return HttpCodeView.VIEWNAME; - } - } - - private ClientDetailsEntity validateAuth(ClientDetailsEntity newClient) - throws ValidationException { - if (newClient.getTokenEndpointAuthMethod() == null) { - newClient.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC); - } - - if (newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_BASIC - || newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_JWT - || newClient.getTokenEndpointAuthMethod() == AuthMethod.SECRET_POST) { - - if (Strings.isNullOrEmpty(newClient.getClientSecret())) { - // no secret yet, we need to generate a secret - newClient = clientService.generateClientSecret(newClient); - } - } else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.PRIVATE_KEY) { - if (Strings.isNullOrEmpty(newClient.getJwksUri()) && newClient.getJwks() == null) { - throw new ValidationException("invalid_client_metadata", - "JWK Set URI required when using private key authentication", HttpStatus.BAD_REQUEST); - } - - newClient.setClientSecret(null); - } else if (newClient.getTokenEndpointAuthMethod() == AuthMethod.NONE) { - newClient.setClientSecret(null); - } else { - throw new ValidationException("invalid_client_metadata", "Unknown authentication method", - HttpStatus.BAD_REQUEST); - } - return newClient; - } - - private OAuth2AccessTokenEntity fetchValidRegistrationToken(OAuth2Authentication auth, - ClientDetailsEntity client) { - - OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) auth.getDetails(); - OAuth2AccessTokenEntity token = tokenService.readAccessToken(details.getTokenValue()); - - if (config.getRegTokenLifeTime() != null) { - - try { - // Re-issue the token if it has been issued before [currentTime - validity] - Date validToDate = - new Date(System.currentTimeMillis() - config.getRegTokenLifeTime() * 1000); - if (token.getJwt().getJWTClaimsSet().getIssueTime().before(validToDate)) { - logger.info("Rotating the registration access token for " + client.getClientId()); - tokenService.revokeAccessToken(token); - OAuth2AccessTokenEntity newToken = connectTokenService.createResourceAccessToken(client); - tokenService.saveAccessToken(newToken); - return newToken; - } else { - // it's not expired, keep going - return token; - } - } catch (ParseException e) { - logger.error("Couldn't parse a known-valid token?", e); - return token; - } - } else { - // tokens don't expire, just return it - return token; - } - } - -} diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java deleted file mode 100644 index 16950a0926..0000000000 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.web; - -import java.util.List; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.UserInfoService; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.UserInfoJWTView; -import org.mitre.openid.connect.view.UserInfoView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -import com.google.common.base.Strings; - -/** - * OpenID Connect UserInfo endpoint, as specified in Standard sec 5 and Messages sec 2.4. - * - * @author AANGANES - * - */ -@Controller -@RequestMapping("/" + UserInfoEndpoint.URL) -public class UserInfoEndpoint { - - public static final String URL = "userinfo"; - - @Autowired - private UserInfoService userInfoService; - - @Autowired - private ClientDetailsEntityService clientService; - - /** - * Logger for this class - */ - private static final Logger logger = LoggerFactory.getLogger(UserInfoEndpoint.class); - - /** - * Get information about the user as specified in the accessToken included in this request - */ - @PreAuthorize("hasRole('ROLE_USER') and #oauth2.hasScope('" + SystemScopeService.OPENID_SCOPE + "')") - @RequestMapping(method= {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_JSON_VALUE, UserInfoJWTView.JOSE_MEDIA_TYPE_VALUE}) - public String getInfo(@RequestParam(value="claims", required=false) String claimsRequestJsonString, - @RequestHeader(value=HttpHeaders.ACCEPT, required=false) String acceptHeader, - OAuth2Authentication auth, Model model) { - - if (auth == null) { - logger.error("getInfo failed; no principal. Requester is not authorized."); - model.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - String username = auth.getName(); - UserInfo userInfo = userInfoService.getByUsernameAndClientId(username, auth.getOAuth2Request().getClientId()); - - if (userInfo == null) { - logger.error("getInfo failed; user not found: " + username); - model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - model.addAttribute(UserInfoView.SCOPE, auth.getOAuth2Request().getScope()); - - model.addAttribute(UserInfoView.AUTHORIZED_CLAIMS, auth.getOAuth2Request().getExtensions().get("claims")); - - if (!Strings.isNullOrEmpty(claimsRequestJsonString)) { - model.addAttribute(UserInfoView.REQUESTED_CLAIMS, claimsRequestJsonString); - } - - model.addAttribute(UserInfoView.USER_INFO, userInfo); - - // content negotiation - - // start off by seeing if the client has registered for a signed/encrypted JWT from here - ClientDetailsEntity client = clientService.loadClientByClientId(auth.getOAuth2Request().getClientId()); - model.addAttribute(UserInfoJWTView.CLIENT, client); - - List mediaTypes = MediaType.parseMediaTypes(acceptHeader); - MediaType.sortBySpecificityAndQuality(mediaTypes); - - if (client.getUserInfoSignedResponseAlg() != null - || client.getUserInfoEncryptedResponseAlg() != null - || client.getUserInfoEncryptedResponseEnc() != null) { - // client has a preference, see if they ask for plain JSON specifically on this request - for (MediaType m : mediaTypes) { - if (!m.isWildcardType() && m.isCompatibleWith(UserInfoJWTView.JOSE_MEDIA_TYPE)) { - return UserInfoJWTView.VIEWNAME; - } else if (!m.isWildcardType() && m.isCompatibleWith(MediaType.APPLICATION_JSON)) { - return UserInfoView.VIEWNAME; - } - } - - // otherwise return JWT - return UserInfoJWTView.VIEWNAME; - } else { - // client has no preference, see if they asked for JWT specifically on this request - for (MediaType m : mediaTypes) { - if (!m.isWildcardType() && m.isCompatibleWith(MediaType.APPLICATION_JSON)) { - return UserInfoView.VIEWNAME; - } else if (!m.isWildcardType() && m.isCompatibleWith(UserInfoJWTView.JOSE_MEDIA_TYPE)) { - return UserInfoJWTView.VIEWNAME; - } - } - - // otherwise return JSON - return UserInfoView.VIEWNAME; - } - - } - -} diff --git a/openid-connect-server/src/test/java/org/mitre/oauth2/repository/impl/TestDatabaseConfiguration.java b/openid-connect-server/src/test/java/org/mitre/oauth2/repository/impl/TestDatabaseConfiguration.java deleted file mode 100644 index 51ab0f43c5..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/oauth2/repository/impl/TestDatabaseConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.mitre.oauth2.repository.impl; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.core.io.ByteArrayResource; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.JpaVendorAdapter; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.Database; -import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; -import org.springframework.transaction.PlatformTransactionManager; - -public class TestDatabaseConfiguration { - - @Autowired - private JpaVendorAdapter jpaAdapter; - - @Autowired - private DataSource dataSource; - - @Autowired - private EntityManagerFactory entityManagerFactory; - - @Bean - public JpaOAuth2TokenRepository repository() { - return new JpaOAuth2TokenRepository(); - } - - @Bean(name = "defaultPersistenceUnit") - public FactoryBean entityManagerFactory() { - LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); - factory.setPackagesToScan("org.mitre", "org.mitre"); - factory.setPersistenceProviderClass(org.eclipse.persistence.jpa.PersistenceProvider.class); - factory.setPersistenceUnitName("test" + System.currentTimeMillis()); - factory.setDataSource(dataSource); - factory.setJpaVendorAdapter(jpaAdapter); - Map jpaProperties = new HashMap(); - jpaProperties.put("eclipselink.weaving", "false"); - jpaProperties.put("eclipselink.logging.level", "INFO"); - jpaProperties.put("eclipselink.logging.level.sql", "INFO"); - jpaProperties.put("eclipselink.cache.shared.default", "false"); - factory.setJpaPropertyMap(jpaProperties); - - return factory; - } - - @Bean - public DataSource dataSource() { - return new EmbeddedDatabaseBuilder(new DefaultResourceLoader() { - @Override - public Resource getResource(String location) { - String sql; - try { - sql = new String(Files.readAllBytes(Paths.get("..", "openid-connect-server-webapp", "src", "main", - "resources", "db", "hsql", location)), UTF_8); - } catch (IOException e) { - throw new RuntimeException("Failed to read sql-script " + location, e); - } - - return new ByteArrayResource(sql.getBytes(UTF_8)); - } - }).generateUniqueName(true).setScriptEncoding(UTF_8.name()).setType(EmbeddedDatabaseType.HSQL) - .addScripts("hsql_database_tables.sql").build(); - } - - @Bean - public JpaVendorAdapter jpaAdapter() { - EclipseLinkJpaVendorAdapter adapter = new EclipseLinkJpaVendorAdapter(); - adapter.setDatabase(Database.HSQL); - adapter.setShowSql(true); - return adapter; - } - - @Bean - public PlatformTransactionManager transactionManager() { - JpaTransactionManager platformTransactionManager = new JpaTransactionManager(); - platformTransactionManager.setEntityManagerFactory(entityManagerFactory); - return platformTransactionManager; - } -} diff --git a/openid-connect-server/src/test/java/org/mitre/oauth2/repository/impl/TestJpaOAuth2TokenRepository.java b/openid-connect-server/src/test/java/org/mitre/oauth2/repository/impl/TestJpaOAuth2TokenRepository.java deleted file mode 100644 index 4ad4b355cc..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/oauth2/repository/impl/TestJpaOAuth2TokenRepository.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.mitre.oauth2.repository.impl; - -import static org.junit.Assert.assertEquals; - -import java.util.Set; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SavedUserAuthentication; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.transaction.annotation.Transactional; - -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = { TestDatabaseConfiguration.class }) -@Transactional -public class TestJpaOAuth2TokenRepository { - - @Autowired - private JpaOAuth2TokenRepository repository; - - @PersistenceContext - private EntityManager entityManager; - - @Before - public void setUp(){ - createAccessToken("user1"); - createAccessToken("user1"); - createAccessToken("user2"); - createAccessToken("user2"); - - createRefreshToken("user1"); - createRefreshToken("user1"); - createRefreshToken("user2"); - createRefreshToken("user2"); - createRefreshToken("user2"); - } - - @Test - public void testGetAccessTokensByUserName() { - Set tokens = repository.getAccessTokensByUserName("user1"); - assertEquals(2, tokens.size()); - assertEquals("user1", tokens.iterator().next().getAuthenticationHolder().getUserAuth().getName()); - } - - @Test - public void testGetRefreshTokensByUserName() { - Set tokens = repository.getRefreshTokensByUserName("user2"); - assertEquals(3, tokens.size()); - assertEquals("user2", tokens.iterator().next().getAuthenticationHolder().getUserAuth().getName()); - } - - @Test - public void testGetAllAccessTokens(){ - Set tokens = repository.getAllAccessTokens(); - assertEquals(4, tokens.size()); - } - - @Test - public void testGetAllRefreshTokens(){ - Set tokens = repository.getAllRefreshTokens(); - assertEquals(5, tokens.size()); - } - - private OAuth2AccessTokenEntity createAccessToken(String name) { - SavedUserAuthentication userAuth = new SavedUserAuthentication(); - userAuth.setName(name); - userAuth = entityManager.merge(userAuth); - - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setUserAuth(userAuth); - authHolder = entityManager.merge(authHolder); - - OAuth2AccessTokenEntity accessToken = new OAuth2AccessTokenEntity(); - accessToken.setAuthenticationHolder(authHolder); - - accessToken = entityManager.merge(accessToken); - - return accessToken; - } - - private OAuth2RefreshTokenEntity createRefreshToken(String name) { - SavedUserAuthentication userAuth = new SavedUserAuthentication(); - userAuth.setName(name); - userAuth = entityManager.merge(userAuth); - - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setUserAuth(userAuth); - authHolder = entityManager.merge(authHolder); - - OAuth2RefreshTokenEntity refreshToken = new OAuth2RefreshTokenEntity(); - refreshToken.setAuthenticationHolder(authHolder); - - refreshToken = entityManager.merge(refreshToken); - - return refreshToken; - } - -} diff --git a/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java b/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java deleted file mode 100644 index 7bc273ec95..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultOAuth2ClientDetailsEntityService.java +++ /dev/null @@ -1,627 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.oauth2.service.impl; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.service.ApprovedSiteService; -import org.mitre.openid.connect.service.BlacklistedSiteService; -import org.mitre.openid.connect.service.StatsService; -import org.mitre.openid.connect.service.WhitelistedSiteService; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ResourceSetService; -import org.mockito.InjectMocks; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; - -import com.google.common.collect.Sets; - -/** - * @author wkim - * - */ -@RunWith(MockitoJUnitRunner.class) -public class TestDefaultOAuth2ClientDetailsEntityService { - - @Mock - private OAuth2ClientRepository clientRepository; - - @Mock - private OAuth2TokenRepository tokenRepository; - - @Mock - private ApprovedSiteService approvedSiteService; - - @Mock - private WhitelistedSiteService whitelistedSiteService; - - @Mock - private BlacklistedSiteService blacklistedSiteService; - - @Mock - private SystemScopeService scopeService; - - @Mock - private ResourceSetService resourceSetService; - - @Mock - private StatsService statsService; - - @Mock - private ConfigurationPropertiesBean config; - - @InjectMocks - private DefaultOAuth2ClientDetailsEntityService service; - - @Before - public void prepare() { - Mockito.reset(clientRepository, tokenRepository, approvedSiteService, whitelistedSiteService, - blacklistedSiteService, scopeService, statsService); - - Mockito.when(clientRepository.saveClient(Matchers.any(ClientDetailsEntity.class))) - .thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - return (ClientDetailsEntity) args[0]; - } - }); - - Mockito - .when(clientRepository.updateClient(Matchers.anyLong(), - Matchers.any(ClientDetailsEntity.class))) - .thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - return (ClientDetailsEntity) args[1]; - } - }); - - Mockito.when(scopeService.fromStrings(Matchers.anySet())) - .thenAnswer(new Answer>() { - @Override - public Set answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - Set input = (Set) args[0]; - Set output = new HashSet<>(); - for (String scope : input) { - output.add(new SystemScope(scope)); - } - return output; - } - }); - - Mockito.when(scopeService.toStrings(Matchers.anySet())).thenAnswer(new Answer>() { - @Override - public Set answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - Set input = (Set) args[0]; - Set output = new HashSet<>(); - for (SystemScope scope : input) { - output.add(scope.getValue()); - } - return output; - } - }); - - Mockito.when(config.isHeartMode()).thenReturn(false); - - } - - /** - * Failure case of existing client id. - */ - @Test(expected = IllegalArgumentException.class) - public void saveNewClient_badId() { - - // Set up a mock client. - ClientDetailsEntity client = Mockito.mock(ClientDetailsEntity.class); - Mockito.when(client.getId()).thenReturn(12345L); // any non-null ID will work - - service.saveNewClient(client); - } - - /** - * Failure case of blacklisted client uri. - */ - @Test(expected = IllegalArgumentException.class) - public void saveNewClient_blacklisted() { - - ClientDetailsEntity client = Mockito.mock(ClientDetailsEntity.class); - Mockito.when(client.getId()).thenReturn(null); - - String badUri = "badplace.xxx"; - - Mockito.when(blacklistedSiteService.isBlacklisted(badUri)).thenReturn(true); - Mockito.when(client.getRegisteredRedirectUri()).thenReturn(Sets.newHashSet(badUri)); - - service.saveNewClient(client); - } - - @Test - public void saveNewClient_idWasAssigned() { - - // Set up a mock client. - ClientDetailsEntity client = Mockito.mock(ClientDetailsEntity.class); - Mockito.when(client.getId()).thenReturn(null); - - service.saveNewClient(client); - - Mockito.verify(client).setClientId(Matchers.anyString()); - } - - /** - * Makes sure client has offline access granted scope if allowed refresh tokens. - */ - @Test - public void saveNewClient_yesOfflineAccess() { - - ClientDetailsEntity client = new ClientDetailsEntity(); - - Set grantTypes = new HashSet<>(); - grantTypes.add("refresh_token"); - client.setGrantTypes(grantTypes); - - client = service.saveNewClient(client); - - assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(true))); - } - - /** - * Makes sure client does not have offline access if not allowed to have refresh tokens. - */ - @Test - public void saveNewClient_noOfflineAccess() { - - ClientDetailsEntity client = new ClientDetailsEntity(); - - client = service.saveNewClient(client); - - assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(false))); - } - - @Test - public void loadClientByClientId_badId() { - - // null id - try { - service.loadClientByClientId(null); - fail("Null client id. Expected an IllegalArgumentException."); - } catch (IllegalArgumentException e) { - assertThat(e, is(notNullValue())); - } - - // empty id - try { - service.loadClientByClientId(""); - fail("Empty client id. Expected an IllegalArgumentException."); - } catch (IllegalArgumentException e) { - assertThat(e, is(notNullValue())); - } - - // id not found - String clientId = "b00g3r"; - Mockito.when(clientRepository.getClientByClientId(clientId)).thenReturn(null); - try { - service.loadClientByClientId(clientId); - fail("Client id not found. Expected an InvalidClientException."); - } catch (InvalidClientException e) { - assertThat(e, is(notNullValue())); - } - - } - - @Test(expected = InvalidClientException.class) - public void deleteClient_badId() { - - Long id = 12345L; - ClientDetailsEntity client = Mockito.mock(ClientDetailsEntity.class); - Mockito.when(client.getId()).thenReturn(id); - Mockito.when(clientRepository.getById(id)).thenReturn(null); - - service.deleteClient(client); - } - - @Test - public void deleteClient() { - - Long id = 12345L; - String clientId = "b00g3r"; - - ClientDetailsEntity client = Mockito.mock(ClientDetailsEntity.class); - Mockito.when(client.getId()).thenReturn(id); - Mockito.when(client.getClientId()).thenReturn(clientId); - - Mockito.when(clientRepository.getById(id)).thenReturn(client); - - WhitelistedSite site = Mockito.mock(WhitelistedSite.class); - Mockito.when(whitelistedSiteService.getByClientId(clientId)).thenReturn(site); - - Mockito.when(resourceSetService.getAllForClient(client)).thenReturn(new HashSet()); - - service.deleteClient(client); - - Mockito.verify(tokenRepository).clearTokensForClient(client); - Mockito.verify(approvedSiteService).clearApprovedSitesForClient(client); - Mockito.verify(whitelistedSiteService).remove(site); - Mockito.verify(clientRepository).deleteClient(client); - } - - @Test - public void updateClient_nullClients() { - - ClientDetailsEntity oldClient = Mockito.mock(ClientDetailsEntity.class); - ClientDetailsEntity newClient = Mockito.mock(ClientDetailsEntity.class); - - try { - service.updateClient(oldClient, null); - fail("New client is null. Expected an IllegalArgumentException."); - } catch (IllegalArgumentException e) { - assertThat(e, is(notNullValue())); - } - - try { - service.updateClient(null, newClient); - fail("Old client is null. Expected an IllegalArgumentException."); - } catch (IllegalArgumentException e) { - assertThat(e, is(notNullValue())); - } - - try { - service.updateClient(null, null); - fail("Both clients are null. Expected an IllegalArgumentException."); - } catch (IllegalArgumentException e) { - assertThat(e, is(notNullValue())); - } - } - - @Test(expected = IllegalArgumentException.class) - public void updateClient_blacklistedUri() { - - ClientDetailsEntity oldClient = Mockito.mock(ClientDetailsEntity.class); - ClientDetailsEntity newClient = Mockito.mock(ClientDetailsEntity.class); - - String badSite = "badsite.xxx"; - - Mockito.when(newClient.getRegisteredRedirectUri()).thenReturn(Sets.newHashSet(badSite)); - Mockito.when(blacklistedSiteService.isBlacklisted(badSite)).thenReturn(true); - - service.updateClient(oldClient, newClient); - } - - @Test - public void updateClient_yesOfflineAccess() { - - ClientDetailsEntity oldClient = new ClientDetailsEntity(); - ClientDetailsEntity client = new ClientDetailsEntity(); - - Set grantTypes = new HashSet<>(); - grantTypes.add("refresh_token"); - client.setGrantTypes(grantTypes); - - client = service.updateClient(oldClient, client); - - assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(true))); - } - - @Test - public void updateClient_noOfflineAccess() { - - ClientDetailsEntity oldClient = new ClientDetailsEntity(); - - oldClient.getScope().add(SystemScopeService.OFFLINE_ACCESS); - - ClientDetailsEntity client = new ClientDetailsEntity(); - - client = service.updateClient(oldClient, client); - - assertThat(client.getScope().contains(SystemScopeService.OFFLINE_ACCESS), is(equalTo(false))); - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_authcode_invalidGrants() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - grantTypes.add("implicit"); - grantTypes.add("client_credentials"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_implicit_invalidGrants() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("implicit"); - grantTypes.add("authorization_code"); - grantTypes.add("client_credentials"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.NONE); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_clientcreds_invalidGrants() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("client_credentials"); - grantTypes.add("authorization_code"); - grantTypes.add("implicit"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_authcode_authMethod() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.SECRET_POST); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_implicit_authMethod() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("implicit"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_clientcreds_authMethod() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("client_credentials"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.SECRET_BASIC); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_authcode_redirectUris() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_implicit_redirectUris() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("implicit"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.NONE); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_clientcreds_redirectUris() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("client_credentials"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("http://foo.bar/")); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_clientSecret() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("http://foo.bar/")); - - client.setClientSecret("secret!"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_noJwks() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwks(null); - client.setJwksUri(null); - - service.saveNewClient(client); - - } - - @Test - public void heartMode_validAuthcodeClient() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - grantTypes.add("refresh_token"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("https://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - assertThat(client.getClientId(), is(notNullValue(String.class))); - assertThat(client.getClientSecret(), is(nullValue())); - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_nonLocalHttpRedirect() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - grantTypes.add("refresh_token"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("http://foo.bar/")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } - - @Test(expected = IllegalArgumentException.class) - public void heartMode_multipleRedirectClass() { - Mockito.when(config.isHeartMode()).thenReturn(true); - - ClientDetailsEntity client = new ClientDetailsEntity(); - Set grantTypes = new LinkedHashSet<>(); - grantTypes.add("authorization_code"); - grantTypes.add("refresh_token"); - client.setGrantTypes(grantTypes); - - client.setTokenEndpointAuthMethod(AuthMethod.PRIVATE_KEY); - - client.setRedirectUris(Sets.newHashSet("http://localhost/", "https://foo.bar", "foo://bar")); - - client.setJwksUri("https://foo.bar/jwks"); - - service.saveNewClient(client); - - } -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/assertion/TestJWTBearerAuthenticationProvider.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/assertion/TestJWTBearerAuthenticationProvider.java deleted file mode 100644 index fde99f499e..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/assertion/TestJWTBearerAuthenticationProvider.java +++ /dev/null @@ -1,414 +0,0 @@ -package org.mitre.openid.connect.assertion; - -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.jwt.signer.service.impl.ClientKeyCacheService; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.AuthMethod; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.security.authentication.AuthenticationServiceException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.oauth2.common.exceptions.InvalidClientException; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.nimbusds.jose.EncryptionMethod; -import com.nimbusds.jose.JWEAlgorithm; -import com.nimbusds.jose.JWEHeader; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.EncryptedJWT; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.PlainJWT; -import com.nimbusds.jwt.SignedJWT; - -@RunWith(MockitoJUnitRunner.class) -public class TestJWTBearerAuthenticationProvider { - - private static final String CLIENT_ID = "client"; - private static final String SUBJECT = "subject"; - - @Mock - private ClientKeyCacheService validators; - @Mock - private ClientDetailsEntityService clientService; - @Mock - private ConfigurationPropertiesBean config; - - @InjectMocks - private JWTBearerAuthenticationProvider jwtBearerAuthenticationProvider; - - @Mock - private JWTBearerAssertionAuthenticationToken token; - @Mock - private ClientDetailsEntity client; - @Mock - private JWTSigningAndValidationService validator; - - private GrantedAuthority authority1 = new SimpleGrantedAuthority("1"); - private GrantedAuthority authority2 = new SimpleGrantedAuthority("2"); - private GrantedAuthority authority3 = new SimpleGrantedAuthority("3"); - - @Before - public void setup() { - when(clientService.loadClientByClientId(CLIENT_ID)).thenReturn(client); - - when(token.getName()).thenReturn(CLIENT_ID); - - when(client.getClientId()).thenReturn(CLIENT_ID); - when(client.getTokenEndpointAuthMethod()).thenReturn(AuthMethod.NONE); - when(client.getAuthorities()).thenReturn(ImmutableSet.of(authority1, authority2, authority3)); - - when(validators.getValidator(client, JWSAlgorithm.RS256)).thenReturn(validator); - when(validator.validateSignature(any(SignedJWT.class))).thenReturn(true); - - when(config.getIssuer()).thenReturn("http://issuer.com/"); - } - - @Test - public void should_not_support_UsernamePasswordAuthenticationToken() { - assertThat(jwtBearerAuthenticationProvider.supports(UsernamePasswordAuthenticationToken.class), is(false)); - } - - @Test - public void should_support_JWTBearerAssertionAuthenticationToken() { - assertThat(jwtBearerAuthenticationProvider.supports(JWTBearerAssertionAuthenticationToken.class), is(true)); - } - - @Test - public void should_throw_UsernameNotFoundException_when_clientService_throws_InvalidClientException() { - when(clientService.loadClientByClientId(CLIENT_ID)).thenThrow(new InvalidClientException("invalid client")); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(UsernameNotFoundException.class)); - assertThat(thrown.getMessage(), is("Could not find client: " + CLIENT_ID)); - } - - @Test - public void should_throw_AuthenticationServiceException_for_PlainJWT() { - mockPlainJWTAuthAttempt(); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Unsupported JWT type: " + PlainJWT.class.getName())); - } - - @Test - public void should_throw_AuthenticationServiceException_for_EncryptedJWT() { - mockEncryptedJWTAuthAttempt(); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Unsupported JWT type: " + EncryptedJWT.class.getName())); - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_signing_algorithms_do_not_match() { - when(client.getTokenEndpointAuthSigningAlg()).thenReturn(JWSAlgorithm.RS256); - SignedJWT signedJWT = createSignedJWT(JWSAlgorithm.ES384); - when(token.getJwt()).thenReturn(signedJWT); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Client's registered token endpoint signing algorithm (RS256) does not match token's actual algorithm (ES384)")); - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_unsupported_authentication_method_for_SignedJWT() { - List unsupportedAuthMethods = - Arrays.asList(null, AuthMethod.NONE, AuthMethod.SECRET_BASIC, AuthMethod.SECRET_POST); - - for (AuthMethod unsupportedAuthMethod : unsupportedAuthMethods) { - SignedJWT signedJWT = createSignedJWT(); - when(token.getJwt()).thenReturn(signedJWT); - when(client.getTokenEndpointAuthMethod()).thenReturn(unsupportedAuthMethod); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Client does not support this authentication method.")); - } - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_invalid_algorithm_for_PRIVATE_KEY_auth_method() { - List invalidAlgorithms = Arrays.asList(JWSAlgorithm.HS256, JWSAlgorithm.HS384, JWSAlgorithm.HS512); - - for (JWSAlgorithm algorithm : invalidAlgorithms) { - SignedJWT signedJWT = createSignedJWT(algorithm); - when(token.getJwt()).thenReturn(signedJWT); - when(client.getTokenEndpointAuthMethod()).thenReturn(AuthMethod.PRIVATE_KEY); - when(client.getTokenEndpointAuthSigningAlg()).thenReturn(algorithm); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Unable to create signature validator for method")); - } - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_invalid_algorithm_for_SECRET_JWT_auth_method() { - List invalidAlgorithms = Arrays.asList( - JWSAlgorithm.RS256, JWSAlgorithm.RS384, JWSAlgorithm.RS512, - JWSAlgorithm.ES256, JWSAlgorithm.ES384, JWSAlgorithm.ES512, - JWSAlgorithm.PS256, JWSAlgorithm.PS384, JWSAlgorithm.PS512); - - for (JWSAlgorithm algorithm : invalidAlgorithms) { - SignedJWT signedJWT = createSignedJWT(algorithm); - when(token.getJwt()).thenReturn(signedJWT); - when(client.getTokenEndpointAuthMethod()).thenReturn(AuthMethod.SECRET_JWT); - when(client.getTokenEndpointAuthSigningAlg()).thenReturn(algorithm); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Unable to create signature validator for method")); - } - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_in_heart_mode_and_auth_method_is_not_PRIVATE_KEY() { - SignedJWT signedJWT = createSignedJWT(JWSAlgorithm.HS256); - when(token.getJwt()).thenReturn(signedJWT); - when(client.getTokenEndpointAuthSigningAlg()).thenReturn(JWSAlgorithm.HS256); - when(config.isHeartMode()).thenReturn(true); - when(client.getTokenEndpointAuthMethod()).thenReturn(AuthMethod.SECRET_JWT); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("[HEART mode] Invalid authentication method")); - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_null_validator() { - mockSignedJWTAuthAttempt(); - when(validators.getValidator(any(ClientDetailsEntity.class), any(JWSAlgorithm.class))).thenReturn(null); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Unable to create signature validator for client")); - } - - @Test - public void should_throw_AuthenticationServiceException_for_SignedJWT_when_invalid_signature() { - SignedJWT signedJWT = mockSignedJWTAuthAttempt(); - when(validator.validateSignature(signedJWT)).thenReturn(false); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Signature did not validate for presented JWT authentication.")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_null_issuer() { - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer(null).build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Assertion Token Issuer is null")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_not_matching_issuer() { - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer("not matching").build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Issuers do not match")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_null_expiration_time() { - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer(CLIENT_ID).expirationTime(null).build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), is("Assertion Token does not have required expiration claim")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_expired_jwt() { - Date expiredDate = new Date(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(500)); - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer(CLIENT_ID).expirationTime(expiredDate).build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Assertion Token is expired")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_jwt_valid_in_future() { - Date futureDate = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(500)); - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer(CLIENT_ID).expirationTime(futureDate).notBeforeTime(futureDate).build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Assertion Token not valid until")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_jwt_issued_in_future() { - Date futureDate = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(500)); - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer(CLIENT_ID).expirationTime(futureDate).issueTime(futureDate).build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Assertion Token was issued in the future")); - } - - @Test - public void should_throw_AuthenticationServiceException_when_unmatching_audience() { - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder().issuer(CLIENT_ID).expirationTime(new Date()).audience("invalid").build(); - mockSignedJWTAuthAttempt(jwtClaimsSet); - - Throwable thrown = authenticateAndReturnThrownException(); - - assertThat(thrown, instanceOf(AuthenticationServiceException.class)); - assertThat(thrown.getMessage(), startsWith("Audience does not match")); - } - - @Test - public void should_return_valid_token_when_audience_contains_token_endpoint() { - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder() - .issuer(CLIENT_ID) - .subject(SUBJECT) - .expirationTime(new Date()) - .audience(ImmutableList.of("http://issuer.com/token", "invalid")) - .build(); - JWT jwt = mockSignedJWTAuthAttempt(jwtClaimsSet); - - Authentication authentication = jwtBearerAuthenticationProvider.authenticate(token); - - assertThat(authentication, instanceOf(JWTBearerAssertionAuthenticationToken.class)); - - JWTBearerAssertionAuthenticationToken token = (JWTBearerAssertionAuthenticationToken) authentication; - assertThat(token.getName(), is(SUBJECT)); - assertThat(token.getJwt(), is(jwt)); - assertThat(token.getAuthorities(), hasItems(authority1, authority2, authority3)); - assertThat(token.getAuthorities().size(), is(4)); - } - - @Test - public void should_return_valid_token_when_issuer_does_not_end_with_slash_and_audience_contains_token_endpoint() { - JWTClaimsSet jwtClaimsSet = new JWTClaimsSet.Builder() - .issuer(CLIENT_ID) - .subject(SUBJECT) - .expirationTime(new Date()) - .audience(ImmutableList.of("http://issuer.com/token")) - .build(); - JWT jwt = mockSignedJWTAuthAttempt(jwtClaimsSet); - when(config.getIssuer()).thenReturn("http://issuer.com/"); - - Authentication authentication = jwtBearerAuthenticationProvider.authenticate(token); - - assertThat(authentication, instanceOf(JWTBearerAssertionAuthenticationToken.class)); - - JWTBearerAssertionAuthenticationToken token = (JWTBearerAssertionAuthenticationToken) authentication; - assertThat(token.getName(), is(SUBJECT)); - assertThat(token.getJwt(), is(jwt)); - assertThat(token.getAuthorities(), hasItems(authority1, authority2, authority3)); - assertThat(token.getAuthorities().size(), is(4)); - } - - private void mockPlainJWTAuthAttempt() { - PlainJWT plainJWT = new PlainJWT(createJwtClaimsSet()); - when(token.getJwt()).thenReturn(plainJWT); - } - - private void mockEncryptedJWTAuthAttempt() { - JWEHeader jweHeader = new JWEHeader.Builder(JWEAlgorithm.A128GCMKW, EncryptionMethod.A256GCM).build(); - EncryptedJWT encryptedJWT = new EncryptedJWT(jweHeader, createJwtClaimsSet()); - when(token.getJwt()).thenReturn(encryptedJWT); - } - - private SignedJWT mockSignedJWTAuthAttempt() { - return mockSignedJWTAuthAttempt(createJwtClaimsSet()); - } - - private SignedJWT mockSignedJWTAuthAttempt(JWTClaimsSet jwtClaimsSet) { - SignedJWT signedJWT = createSignedJWT(JWSAlgorithm.RS256, jwtClaimsSet); - when(token.getJwt()).thenReturn(signedJWT); - when(client.getTokenEndpointAuthMethod()).thenReturn(AuthMethod.PRIVATE_KEY); - when(client.getTokenEndpointAuthSigningAlg()).thenReturn(JWSAlgorithm.RS256); - return signedJWT; - } - - private Throwable authenticateAndReturnThrownException() { - try { - jwtBearerAuthenticationProvider.authenticate(token); - } catch (Throwable throwable) { - return throwable; - } - throw new AssertionError("No exception thrown when expected"); - } - - private SignedJWT createSignedJWT() { - return createSignedJWT(JWSAlgorithm.RS256); - } - - private SignedJWT createSignedJWT(JWSAlgorithm jwsAlgorithm) { - JWSHeader jwsHeader = new JWSHeader.Builder(jwsAlgorithm).build(); - JWTClaimsSet claims = createJwtClaimsSet(); - - return new SignedJWT(jwsHeader, claims); - } - - private SignedJWT createSignedJWT(JWSAlgorithm jwsAlgorithm, JWTClaimsSet jwtClaimsSet) { - JWSHeader jwsHeader = new JWSHeader.Builder(jwsAlgorithm).build(); - - return new SignedJWT(jwsHeader, jwtClaimsSet); - } - - private JWTClaimsSet createJwtClaimsSet() { - return new JWTClaimsSet.Builder() - .issuer(CLIENT_ID) - .expirationTime(new Date()) - .audience("http://issuer.com/") - .build(); - } - -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java deleted file mode 100644 index 8524145f0b..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultApprovedSiteService.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import static org.mockito.Matchers.any; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.service.ApprovedSiteService; -import org.mitre.openid.connect.service.StatsService; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.test.annotation.Rollback; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; - -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; - -@RunWith(MockitoJUnitRunner.class) -public class TestDefaultApprovedSiteService { - - private ApprovedSite site1; - private ApprovedSite site2; - private ApprovedSite site3; - - private ClientDetailsEntity client; - private final String clientId = "client"; - - @Mock - private ApprovedSiteRepository repository; - - @Mock - private OAuth2TokenRepository tokenRepository; - - @Mock - private StatsService statsService; - - @InjectMocks - private ApprovedSiteService service = new DefaultApprovedSiteService(); - - - /** - * Initialize the service and repository mock. Initialize a client and - * several ApprovedSite objects for use in unit tests. - */ - @Before - public void prepare() { - - client = new ClientDetailsEntity(); - client.setClientId(clientId); - - site1 = new ApprovedSite(); - site1.setId(1L); - site1.setUserId("user1"); - site1.setClientId("other"); - - site2 = new ApprovedSite(); - site2.setId(2L); - site2.setUserId("user1"); - site2.setClientId(clientId); - - site3 = new ApprovedSite(); - site3.setId(3L); - site3.setUserId("user2"); - site3.setClientId(clientId); - - Mockito.reset(repository, statsService); - - } - - /** - * Test clearing approved sites for a client that has 2 stored approved sites. - * Ensure that the repository's remove() method is called twice. - */ - @Test - public void clearApprovedSitesForClient_success() { - Set setToReturn = Sets.newHashSet(site2, site3); - Mockito.when(repository.getByClientId(client.getClientId())).thenReturn(setToReturn); - List tokens = ImmutableList.of(); - Mockito.when(tokenRepository.getAccessTokensForApprovedSite(any(ApprovedSite.class))).thenReturn(tokens); - - service.clearApprovedSitesForClient(client); - - Mockito.verify(repository, times(2)).remove(any(ApprovedSite.class)); - } - - /** - * Test clearing approved sites for a client that doesn't have any stored approved - * sites. Ensure that the repository's remove() method is never called in this case. - */ - @Test - @Rollback - public void clearApprovedSitesForClient_null() { - String otherId = "a different id"; - client.setClientId(otherId); - service.clearApprovedSitesForClient(client); - Mockito.when(repository.getByClientId(otherId)).thenReturn(new HashSet()); - Mockito.verify(repository, never()).remove(any(ApprovedSite.class)); - } - - -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultOIDCTokenService.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultOIDCTokenService.java deleted file mode 100644 index 5914ff0e18..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultOIDCTokenService.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import java.util.Date; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; - -@RunWith(MockitoJUnitRunner.class) -public class TestDefaultOIDCTokenService { - private static final String CLIENT_ID = "client"; - private static final String KEY_ID = "key"; - - private ConfigurationPropertiesBean configBean = new ConfigurationPropertiesBean(); - private ClientDetailsEntity client = new ClientDetailsEntity(); - private OAuth2AccessTokenEntity accessToken = new OAuth2AccessTokenEntity(); - private OAuth2Request request = new OAuth2Request(CLIENT_ID) { }; - - @Mock - private JWTSigningAndValidationService jwtService; - - @Before - public void prepare() { - configBean.setIssuer("https://auth.example.org/"); - - client.setClientId(CLIENT_ID); - Mockito.when(jwtService.getDefaultSigningAlgorithm()).thenReturn(JWSAlgorithm.RS256); - Mockito.when(jwtService.getDefaultSignerKeyId()).thenReturn(KEY_ID); - } - - @Test - public void invokesCustomClaimsHook() throws java.text.ParseException { - DefaultOIDCTokenService s = new DefaultOIDCTokenService() { - @Override - protected void addCustomIdTokenClaims(JWTClaimsSet.Builder idClaims, ClientDetailsEntity client, OAuth2Request request, - String sub, OAuth2AccessTokenEntity accessToken) { - idClaims.claim("test", "foo"); - } - }; - - configure(s); - - JWT token = s.createIdToken(client, request, new Date(), "sub", accessToken); - Assert.assertEquals("foo", token.getJWTClaimsSet().getClaim("test")); - } - - - private void configure(DefaultOIDCTokenService s) { - s.setConfigBean(configBean); - s.setJwtService(jwtService); - } -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultUserInfoService.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultUserInfoService.java deleted file mode 100644 index e5e7070832..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestDefaultUserInfoService.java +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.ClientDetailsEntity.SubjectType; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.model.DefaultUserInfo; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.repository.UserInfoRepository; -import org.mitre.openid.connect.service.PairwiseIdentiferService; -import org.mockito.InjectMocks; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -/** - * @author jricher - * - */ -@RunWith(MockitoJUnitRunner.class) -public class TestDefaultUserInfoService { - @InjectMocks - private DefaultUserInfoService service = new DefaultUserInfoService(); - - @Mock - private UserInfoRepository userInfoRepository; - - @Mock - private ClientDetailsEntityService clientDetailsEntityService; - - @Mock - private PairwiseIdentiferService pairwiseIdentiferService; - - private UserInfo userInfoAdmin; - private UserInfo userInfoRegular; - - private ClientDetailsEntity publicClient1; - private ClientDetailsEntity publicClient2; - private ClientDetailsEntity pairwiseClient1; - private ClientDetailsEntity pairwiseClient2; - private ClientDetailsEntity pairwiseClient3; - private ClientDetailsEntity pairwiseClient4; - - private String adminUsername = "username"; - private String regularUsername = "regular"; - private String adminSub = "adminSub12d3a1f34a2"; - private String regularSub = "regularSub652ha23b"; - - private String pairwiseSub12 = "regularPairwise-12-31ijoef"; - private String pairwiseSub3 = "regularPairwise-3-1ojadsio"; - private String pairwiseSub4 = "regularPairwise-4-1ojadsio"; - - private String publicClientId1 = "publicClient-1-313124"; - private String publicClientId2 = "publicClient-2-4109312"; - private String pairwiseClientId1 = "pairwiseClient-1-2312"; - private String pairwiseClientId2 = "pairwiseClient-2-324416"; - private String pairwiseClientId3 = "pairwiseClient-3-154157"; - private String pairwiseClientId4 = "pairwiseClient-4-4589723"; - - private String sectorIdentifier1 = "https://sector-identifier-12/url"; - private String sectorIdentifier2 = "https://sector-identifier-12/url2"; - private String sectorIdentifier3 = "https://sector-identifier-3/url"; - - - - - /** - * Initialize the service and the mocked repository. - * Initialize 2 users, one of them an admin, for use in unit tests. - */ - @Before - public void prepare() { - - - userInfoAdmin = new DefaultUserInfo(); - userInfoAdmin.setPreferredUsername(adminUsername); - userInfoAdmin.setSub(adminSub); - - userInfoRegular = new DefaultUserInfo(); - userInfoRegular.setPreferredUsername(regularUsername); - userInfoRegular.setSub(regularSub); - - publicClient1 = new ClientDetailsEntity(); - publicClient1.setClientId(publicClientId1); - - publicClient2 = new ClientDetailsEntity(); - publicClient2.setClientId(publicClientId2); - publicClient2.setSubjectType(SubjectType.PUBLIC); - - // pairwise set 1 - pairwiseClient1 = new ClientDetailsEntity(); - pairwiseClient1.setClientId(pairwiseClientId1); - pairwiseClient1.setSubjectType(SubjectType.PAIRWISE); - pairwiseClient1.setSectorIdentifierUri(sectorIdentifier1); - - pairwiseClient2 = new ClientDetailsEntity(); - pairwiseClient2.setClientId(pairwiseClientId2); - pairwiseClient2.setSubjectType(SubjectType.PAIRWISE); - pairwiseClient2.setSectorIdentifierUri(sectorIdentifier2); - - // pairwise set 2 - pairwiseClient3 = new ClientDetailsEntity(); - pairwiseClient3.setClientId(pairwiseClientId3); - pairwiseClient3.setSubjectType(SubjectType.PAIRWISE); - pairwiseClient3.setSectorIdentifierUri(sectorIdentifier3); - - // pairwise with null sector - pairwiseClient4 = new ClientDetailsEntity(); - pairwiseClient4.setClientId(pairwiseClientId4); - pairwiseClient4.setSubjectType(SubjectType.PAIRWISE); - - - - - } - - /** - * Test loading an admin user, ensuring that the UserDetails object returned - * has both the ROLE_USER and ROLE_ADMIN authorities. - */ - @Test - public void loadByUsername_admin_success() { - Mockito.when(userInfoRepository.getByUsername(adminUsername)).thenReturn(userInfoAdmin); - UserInfo user = service.getByUsername(adminUsername); - assertEquals(user.getSub(), adminSub); - } - - /** - * Test loading a regular, non-admin user, ensuring that the returned UserDetails - * object has ROLE_USER but *not* ROLE_ADMIN. - */ - @Test - public void loadByUsername_regular_success() { - - Mockito.when(userInfoRepository.getByUsername(regularUsername)).thenReturn(userInfoRegular); - UserInfo user = service.getByUsername(regularUsername); - assertEquals(user.getSub(), regularSub); - - } - - /** - * If a user is not found, the loadByUsername method should throw an exception. - */ - @Test() - public void loadByUsername_nullUser() { - - Mockito.when(userInfoRepository.getByUsername(adminUsername)).thenReturn(null); - UserInfo user = service.getByUsername(adminUsername); - - assertNull(user); - } - - /** - * Clients with public subs should always return the same sub - */ - @Test - public void getByUsernameAndClientId_publicClients() { - - Mockito.when(clientDetailsEntityService.loadClientByClientId(publicClientId1)).thenReturn(publicClient1); - Mockito.when(clientDetailsEntityService.loadClientByClientId(publicClientId2)).thenReturn(publicClient2); - - Mockito.when(userInfoRepository.getByUsername(regularUsername)).thenReturn(userInfoRegular); - - Mockito.verify(pairwiseIdentiferService, Mockito.never()).getIdentifier(Matchers.any(UserInfo.class), Matchers.any(ClientDetailsEntity.class)); - - UserInfo user1 = service.getByUsernameAndClientId(regularUsername, publicClientId1); - UserInfo user2 = service.getByUsernameAndClientId(regularUsername, publicClientId2); - - assertEquals(regularSub, user1.getSub()); - assertEquals(regularSub, user2.getSub()); - } - - /** - * Clients with pairwise subs should be grouped by the sector URI - */ - @Test - public void getByUsernameAndClientId_pairwiseClients() { - - Mockito.when(clientDetailsEntityService.loadClientByClientId(pairwiseClientId1)).thenReturn(pairwiseClient1); - Mockito.when(clientDetailsEntityService.loadClientByClientId(pairwiseClientId2)).thenReturn(pairwiseClient2); - Mockito.when(clientDetailsEntityService.loadClientByClientId(pairwiseClientId3)).thenReturn(pairwiseClient3); - Mockito.when(clientDetailsEntityService.loadClientByClientId(pairwiseClientId4)).thenReturn(pairwiseClient4); - - Mockito.when(userInfoRepository.getByUsername(regularUsername)).thenAnswer(new Answer() { - @Override - public UserInfo answer(InvocationOnMock invocation) throws Throwable { - UserInfo userInfo = new DefaultUserInfo(); - userInfo.setPreferredUsername(regularUsername); - userInfo.setSub(regularSub); - - return userInfo; - } - }); - - Mockito.when(pairwiseIdentiferService.getIdentifier(userInfoRegular, pairwiseClient1)).thenReturn(pairwiseSub12); - Mockito.when(pairwiseIdentiferService.getIdentifier(userInfoRegular, pairwiseClient2)).thenReturn(pairwiseSub12); - Mockito.when(pairwiseIdentiferService.getIdentifier(userInfoRegular, pairwiseClient3)).thenReturn(pairwiseSub3); - Mockito.when(pairwiseIdentiferService.getIdentifier(userInfoRegular, pairwiseClient4)).thenReturn(pairwiseSub4); - - UserInfo user1 = service.getByUsernameAndClientId(regularUsername, pairwiseClientId1); - UserInfo user2 = service.getByUsernameAndClientId(regularUsername, pairwiseClientId2); - UserInfo user3 = service.getByUsernameAndClientId(regularUsername, pairwiseClientId3); - UserInfo user4 = service.getByUsernameAndClientId(regularUsername, pairwiseClientId4); - - assertEquals(pairwiseSub12, user1.getSub()); - assertEquals(pairwiseSub12, user2.getSub()); - assertEquals(pairwiseSub3, user3.getSub()); - assertEquals(pairwiseSub4, user4.getSub()); - - } - - - -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java deleted file mode 100644 index b8ed64b211..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_0.java +++ /dev/null @@ -1,971 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.springframework.format.annotation.DateTimeFormat.ISO; -import org.springframework.format.datetime.DateFormatter; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jwt.JWTParser; - -@RunWith(MockitoJUnitRunner.class) -@SuppressWarnings(value = {"rawtypes", "unchecked"}) -public class TestMITREidDataService_1_0 { - - @Mock - private OAuth2ClientRepository clientRepository; - @Mock - private ApprovedSiteRepository approvedSiteRepository; - @Mock - private WhitelistedSiteRepository wlSiteRepository; - @Mock - private BlacklistedSiteRepository blSiteRepository; - @Mock - private AuthenticationHolderRepository authHolderRepository; - @Mock - private OAuth2TokenRepository tokenRepository; - @Mock - private SystemScopeRepository sysScopeRepository; - - @Captor - private ArgumentCaptor capturedRefreshTokens; - @Captor - private ArgumentCaptor capturedAccessTokens; - @Captor - private ArgumentCaptor capturedClients; - @Captor - private ArgumentCaptor capturedBlacklistedSites; - @Captor - private ArgumentCaptor capturedWhitelistedSites; - @Captor - private ArgumentCaptor capturedApprovedSites; - @Captor - private ArgumentCaptor capturedAuthHolders; - @Captor - private ArgumentCaptor capturedScope; - - @InjectMocks - private MITREidDataService_1_0 dataService; - - private DateFormatter formatter; - - @Before - public void prepare() { - formatter = new DateFormatter(); - formatter.setIso(ISO.DATE_TIME); - Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository, wlSiteRepository, blSiteRepository); - } - - private class refreshTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2RefreshTokenEntity entity1, OAuth2RefreshTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - @Test - public void testImportRefreshTokens() throws IOException, ParseException { - - Date expirationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(mockedAuthHolder1); - - Date expirationDate2 = formatter.parse("2015-01-07T18:31:50.079+00:00", Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(mockedAuthHolder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - - System.err.println(configJson); - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 678L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder - verify(tokenRepository, times(6)).saveRefreshToken(capturedRefreshTokens.capture()); - - List savedRefreshTokens = new ArrayList(fakeDb.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.size(), is(2)); - - assertThat(savedRefreshTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedRefreshTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedRefreshTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedRefreshTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedRefreshTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedRefreshTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - private class accessTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2AccessTokenEntity entity1, OAuth2AccessTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - @Test - public void testImportAccessTokens() throws IOException, ParseException { - - Date expirationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0")); - token1.setAuthenticationHolder(mockedAuthHolder1); - token1.setScope(ImmutableSet.of("id-token")); - token1.setTokenType("Bearer"); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); - when(mockRefreshToken2.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ")); - token2.setAuthenticationHolder(mockedAuthHolder2); - token2.setRefreshToken(mockRefreshToken2); - token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); - token2.setTokenType("Bearer"); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"refreshTokenId\":null,\"idTokenId\":null,\"scope\":[\"id-token\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"refreshTokenId\":1,\"idTokenId\":1,\"scope\":[\"openid\",\"offline_access\",\"email\",\"profile\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ\"}" + - - " ]" + - "}"; - - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveAccessToken(isA(OAuth2AccessTokenEntity.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = (OAuth2AccessTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getAccessTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 234L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder, 1 times to update refresh token - verify(tokenRepository, times(7)).saveAccessToken(capturedAccessTokens.capture()); - - List savedAccessTokens = new ArrayList(fakeDb.values()); //capturedAccessTokens.getAllValues(); - Collections.sort(savedAccessTokens, new accessTokenIdComparator()); - - assertThat(savedAccessTokens.size(), is(2)); - - assertThat(savedAccessTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedAccessTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedAccessTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedAccessTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedAccessTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedAccessTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - - //several new client fields added in 1.1, perhaps additional tests for these should be added - @Test - public void testImportClients() throws IOException { - ClientDetailsEntity client1 = new ClientDetailsEntity(); - client1.setId(1L); - client1.setAccessTokenValiditySeconds(3600); - client1.setClientId("client1"); - client1.setClientSecret("clientsecret1"); - client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); - client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); - client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); - client1.setAllowIntrospection(true); - - ClientDetailsEntity client2 = new ClientDetailsEntity(); - client2.setId(2L); - client2.setAccessTokenValiditySeconds(3600); - client2.setClientId("client2"); - client2.setClientSecret("clientsecret2"); - client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); - client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); - client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); - client2.setAllowIntrospection(false); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [" + - - "{\"id\":1,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client1\",\"secret\":\"clientsecret1\"," - + "\"redirectUris\":[\"http://foo.com/\"]," - + "\"scope\":[\"foo\",\"bar\",\"baz\",\"dolphin\"]," - + "\"grantTypes\":[\"implicit\",\"authorization_code\",\"urn:ietf:params:oauth:grant_type:redelegate\",\"refresh_token\"]," - + "\"allowIntrospection\":true}," + - "{\"id\":2,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client2\",\"secret\":\"clientsecret2\"," - + "\"redirectUris\":[\"http://bar.baz.com/\"]," - + "\"scope\":[\"foo\",\"dolphin\",\"electric-wombat\"]," - + "\"grantTypes\":[\"client_credentials\",\"urn:ietf:params:oauth:grant_type:redelegate\"]," - + "\"allowIntrospection\":false}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(clientRepository, times(2)).saveClient(capturedClients.capture()); - - List savedClients = capturedClients.getAllValues(); - - assertThat(savedClients.size(), is(2)); - - assertThat(savedClients.get(0).getAccessTokenValiditySeconds(), equalTo(client1.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(0).getClientId(), equalTo(client1.getClientId())); - assertThat(savedClients.get(0).getClientSecret(), equalTo(client1.getClientSecret())); - assertThat(savedClients.get(0).getRedirectUris(), equalTo(client1.getRedirectUris())); - assertThat(savedClients.get(0).getScope(), equalTo(client1.getScope())); - assertThat(savedClients.get(0).getGrantTypes(), equalTo(client1.getGrantTypes())); - assertThat(savedClients.get(0).isAllowIntrospection(), equalTo(client1.isAllowIntrospection())); - - assertThat(savedClients.get(1).getAccessTokenValiditySeconds(), equalTo(client2.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(1).getClientId(), equalTo(client2.getClientId())); - assertThat(savedClients.get(1).getClientSecret(), equalTo(client2.getClientSecret())); - assertThat(savedClients.get(1).getRedirectUris(), equalTo(client2.getRedirectUris())); - assertThat(savedClients.get(1).getScope(), equalTo(client2.getScope())); - assertThat(savedClients.get(1).getGrantTypes(), equalTo(client2.getGrantTypes())); - assertThat(savedClients.get(1).isAllowIntrospection(), equalTo(client2.isAllowIntrospection())); - } - - @Test - public void testImportBlacklistedSites() throws IOException { - BlacklistedSite site1 = new BlacklistedSite(); - site1.setId(1L); - site1.setUri("http://foo.com"); - - BlacklistedSite site2 = new BlacklistedSite(); - site2.setId(2L); - site2.setUri("http://bar.com"); - - BlacklistedSite site3 = new BlacklistedSite(); - site3.setId(3L); - site3.setUri("http://baz.com"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [" + - - "{\"id\":1,\"uri\":\"http://foo.com\"}," + - "{\"id\":2,\"uri\":\"http://bar.com\"}," + - "{\"id\":3,\"uri\":\"http://baz.com\"}" + - - " ]" + - "}"; - - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(blSiteRepository, times(3)).save(capturedBlacklistedSites.capture()); - - List savedSites = capturedBlacklistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getUri(), equalTo(site1.getUri())); - assertThat(savedSites.get(1).getUri(), equalTo(site2.getUri())); - assertThat(savedSites.get(2).getUri(), equalTo(site3.getUri())); - } - - @Test - public void testImportWhitelistedSites() throws IOException { - WhitelistedSite site1 = new WhitelistedSite(); - site1.setId(1L); - site1.setClientId("foo"); - - WhitelistedSite site2 = new WhitelistedSite(); - site2.setId(2L); - site2.setClientId("bar"); - - WhitelistedSite site3 = new WhitelistedSite(); - site3.setId(3L); - site3.setClientId("baz"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\"}," + - "{\"id\":2,\"clientId\":\"bar\"}," + - "{\"id\":3,\"clientId\":\"baz\"}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(wlSiteRepository.save(isA(WhitelistedSite.class))).thenAnswer(new Answer() { - Long id = 345L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = (WhitelistedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(wlSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - - dataService.importData(reader); - verify(wlSiteRepository, times(3)).save(capturedWhitelistedSites.capture()); - - List savedSites = capturedWhitelistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(2).getClientId(), equalTo(site3.getClientId())); - } - - @Test - public void testImportGrants() throws IOException, ParseException { - - Date creationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - Date accessDate1 = formatter.parse("2014-09-10T23:49:44.090+00:00", Locale.ENGLISH); - - OAuth2AccessTokenEntity mockToken1 = mock(OAuth2AccessTokenEntity.class); - when(mockToken1.getId()).thenReturn(1L); - - ApprovedSite site1 = new ApprovedSite(); - site1.setId(1L); - site1.setClientId("foo"); - site1.setCreationDate(creationDate1); - site1.setAccessDate(accessDate1); - site1.setUserId("user1"); - site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); - when(mockToken1.getApprovedSite()).thenReturn(site1); - - Date creationDate2 = formatter.parse("2014-09-11T18:49:44.090+00:00", Locale.ENGLISH); - Date accessDate2 = formatter.parse("2014-09-11T20:49:44.090+00:00", Locale.ENGLISH); - Date timeoutDate2 = formatter.parse("2014-10-01T20:49:44.090+00:00", Locale.ENGLISH); - - ApprovedSite site2 = new ApprovedSite(); - site2.setId(2L); - site2.setClientId("bar"); - site2.setCreationDate(creationDate2); - site2.setAccessDate(accessDate2); - site2.setUserId("user2"); - site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); - site2.setTimeoutDate(timeoutDate2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\",\"creationDate\":\"2014-09-10T22:49:44.090+00:00\",\"accessDate\":\"2014-09-10T23:49:44.090+00:00\"," - + "\"userId\":\"user1\",\"whitelistedSiteId\":null,\"allowedScopes\":[\"openid\",\"phone\"], \"whitelistedSiteId\":1," - + "\"approvedAccessTokens\":[1]}," + - "{\"id\":2,\"clientId\":\"bar\",\"creationDate\":\"2014-09-11T18:49:44.090+00:00\",\"accessDate\":\"2014-09-11T20:49:44.090+00:00\"," - + "\"timeoutDate\":\"2014-10-01T20:49:44.090+00:00\",\"userId\":\"user2\"," - + "\"allowedScopes\":[\"openid\",\"offline_access\",\"email\",\"profile\"]}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(approvedSiteRepository.save(isA(ApprovedSite.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - ApprovedSite _site = (ApprovedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(approvedSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(wlSiteRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 244L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = mock(WhitelistedSite.class); - when(_site.getId()).thenReturn(id++); - return _site; - } - }); - when(tokenRepository.getAccessTokenById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 221L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = mock(OAuth2AccessTokenEntity.class); - when(_token.getId()).thenReturn(id++); - return _token; - } - }); - when(tokenRepository.getAccessTokensForApprovedSite(site1)).thenReturn(Lists.newArrayList(mockToken1)); - - dataService.importData(reader); - //2 for sites, 1 for updating access token ref on #1 - verify(approvedSiteRepository, times(3)).save(capturedApprovedSites.capture()); - - List savedSites = new ArrayList(fakeDb.values()); - - assertThat(savedSites.size(), is(2)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(0).getAccessDate(), equalTo(site1.getAccessDate())); - assertThat(savedSites.get(0).getCreationDate(), equalTo(site1.getCreationDate())); - assertThat(savedSites.get(0).getAllowedScopes(), equalTo(site1.getAllowedScopes())); - assertThat(savedSites.get(0).getTimeoutDate(), equalTo(site1.getTimeoutDate())); - - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(1).getAccessDate(), equalTo(site2.getAccessDate())); - assertThat(savedSites.get(1).getCreationDate(), equalTo(site2.getCreationDate())); - assertThat(savedSites.get(1).getAllowedScopes(), equalTo(site2.getAllowedScopes())); - assertThat(savedSites.get(1).getTimeoutDate(), equalTo(site2.getTimeoutDate())); - } - - @Test - public void testImportAuthenticationHolders() throws IOException { - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"}," - + "\"userAuthentication\":null}}," + - "{\"id\":2,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"}," - + "\"userAuthentication\":null}}" + - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 356L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _holder = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_holder.getId() == null) { - _holder.setId(id++); - } - fakeDb.put(_holder.getId(), _holder); - return _holder; - } - }); - - dataService.importData(reader); - verify(authHolderRepository, times(2)).save(capturedAuthHolders.capture()); - - List savedAuthHolders = capturedAuthHolders.getAllValues(); - - assertThat(savedAuthHolders.size(), is(2)); - assertThat(savedAuthHolders.get(0).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder1.getAuthentication().getOAuth2Request().getClientId())); - assertThat(savedAuthHolders.get(1).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder2.getAuthentication().getOAuth2Request().getClientId())); - } - - @Test - public void testImportSystemScopes() throws IOException { - SystemScope scope1 = new SystemScope(); - scope1.setId(1L); - scope1.setValue("scope1"); - scope1.setDescription("Scope 1"); - scope1.setRestricted(true); - scope1.setDefaultScope(false); - scope1.setIcon("glass"); - - SystemScope scope2 = new SystemScope(); - scope2.setId(2L); - scope2.setValue("scope2"); - scope2.setDescription("Scope 2"); - scope2.setRestricted(false); - scope2.setDefaultScope(false); - scope2.setIcon("ball"); - - SystemScope scope3 = new SystemScope(); - scope3.setId(3L); - scope3.setValue("scope3"); - scope3.setDescription("Scope 3"); - scope3.setRestricted(false); - scope3.setDefaultScope(true); - scope3.setIcon("road"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [" + - - "{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"allowDynReg\":false,\"defaultScope\":false}," + - "{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"allowDynReg\":true,\"defaultScope\":false}," + - "{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"allowDynReg\":true,\"defaultScope\":true}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(sysScopeRepository, times(3)).save(capturedScope.capture()); - - List savedScopes = capturedScope.getAllValues(); - - assertThat(savedScopes.size(), is(3)); - assertThat(savedScopes.get(0).getValue(), equalTo(scope1.getValue())); - assertThat(savedScopes.get(0).getDescription(), equalTo(scope1.getDescription())); - assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon())); - assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope())); - assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted())); - - assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue())); - assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription())); - assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon())); - assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope())); - assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted())); - - assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue())); - assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription())); - assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon())); - assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope())); - assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted())); - - } - - @Test - public void testFixRefreshTokenAuthHolderReferencesOnImport() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(holder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(holder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"}," - + "\"userAuthentication\":null}}," + - "{\"id\":2,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"}," - + "\"userAuthentication\":null}}" + - " ]," + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - final Map fakeRefreshTokenTable = new HashMap<>(); - final Map fakeAuthHolderTable = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeRefreshTokenTable.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeRefreshTokenTable.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 356L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _holder = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_holder.getId() == null) { - _holder.setId(id++); - } - fakeAuthHolderTable.put(_holder.getId(), _holder); - return _holder; - } - }); - when(authHolderRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeAuthHolderTable.get(_id); - } - }); - dataService.importData(reader); - - List savedRefreshTokens = new ArrayList(fakeRefreshTokenTable.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.get(0).getAuthenticationHolder().getId(), equalTo(356L)); - assertThat(savedRefreshTokens.get(1).getAuthenticationHolder().getId(), equalTo(357L)); - } - - @Test(expected = UnsupportedOperationException.class) - public void testExportDisabled() throws IOException { - JsonWriter writer = new JsonWriter(new StringWriter()); - dataService.exportData(writer); - } - -} \ No newline at end of file diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java deleted file mode 100644 index 3876138527..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java +++ /dev/null @@ -1,973 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.service.impl; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.springframework.format.annotation.DateTimeFormat.ISO; -import org.springframework.format.datetime.DateFormatter; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import com.google.common.collect.ImmutableSet; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jwt.JWTParser; - -@RunWith(MockitoJUnitRunner.class) -@SuppressWarnings(value = {"rawtypes", "unchecked"}) -public class TestMITREidDataService_1_1 { - - @Mock - private OAuth2ClientRepository clientRepository; - @Mock - private ApprovedSiteRepository approvedSiteRepository; - @Mock - private WhitelistedSiteRepository wlSiteRepository; - @Mock - private BlacklistedSiteRepository blSiteRepository; - @Mock - private AuthenticationHolderRepository authHolderRepository; - @Mock - private OAuth2TokenRepository tokenRepository; - @Mock - private SystemScopeRepository sysScopeRepository; - - @Captor - private ArgumentCaptor capturedRefreshTokens; - @Captor - private ArgumentCaptor capturedAccessTokens; - @Captor - private ArgumentCaptor capturedClients; - @Captor - private ArgumentCaptor capturedBlacklistedSites; - @Captor - private ArgumentCaptor capturedWhitelistedSites; - @Captor - private ArgumentCaptor capturedApprovedSites; - @Captor - private ArgumentCaptor capturedAuthHolders; - @Captor - private ArgumentCaptor capturedScope; - - @InjectMocks - private MITREidDataService_1_1 dataService; - private DateFormatter formatter; - - @Before - public void prepare() { - formatter = new DateFormatter(); - formatter.setIso(ISO.DATE_TIME); - - Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository, wlSiteRepository, blSiteRepository); - } - - - private class refreshTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2RefreshTokenEntity entity1, OAuth2RefreshTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - - @Test - public void testImportRefreshTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(mockedAuthHolder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(mockedAuthHolder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - - System.err.println(configJson); - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 332L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 131L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder - verify(tokenRepository, times(6)).saveRefreshToken(capturedRefreshTokens.capture()); - - List savedRefreshTokens = new ArrayList(fakeDb.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.size(), is(2)); - - assertThat(savedRefreshTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedRefreshTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedRefreshTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedRefreshTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedRefreshTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedRefreshTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - private class accessTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2AccessTokenEntity entity1, OAuth2AccessTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - @Test - public void testImportAccessTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0")); - token1.setAuthenticationHolder(mockedAuthHolder1); - token1.setScope(ImmutableSet.of("id-token")); - token1.setTokenType("Bearer"); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); - when(mockRefreshToken2.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ")); - token2.setAuthenticationHolder(mockedAuthHolder2); - token2.setRefreshToken(mockRefreshToken2); - token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); - token2.setTokenType("Bearer"); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"refreshTokenId\":null,\"idTokenId\":null,\"scope\":[\"id-token\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"refreshTokenId\":1,\"idTokenId\":1,\"scope\":[\"openid\",\"offline_access\",\"email\",\"profile\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ\"}" + - - " ]" + - "}"; - - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveAccessToken(isA(OAuth2AccessTokenEntity.class))).thenAnswer(new Answer() { - Long id = 324L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = (OAuth2AccessTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getAccessTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 133L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder, 1 times to update refresh token - verify(tokenRepository, times(7)).saveAccessToken(capturedAccessTokens.capture()); - - List savedAccessTokens = new ArrayList(fakeDb.values()); //capturedAccessTokens.getAllValues(); - Collections.sort(savedAccessTokens, new accessTokenIdComparator()); - - assertThat(savedAccessTokens.size(), is(2)); - - assertThat(savedAccessTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedAccessTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedAccessTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedAccessTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedAccessTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedAccessTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - @Test - public void testImportClients() throws IOException { - ClientDetailsEntity client1 = new ClientDetailsEntity(); - client1.setId(1L); - client1.setAccessTokenValiditySeconds(3600); - client1.setClientId("client1"); - client1.setClientSecret("clientsecret1"); - client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); - client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); - client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); - client1.setAllowIntrospection(true); - - ClientDetailsEntity client2 = new ClientDetailsEntity(); - client2.setId(2L); - client2.setAccessTokenValiditySeconds(3600); - client2.setClientId("client2"); - client2.setClientSecret("clientsecret2"); - client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); - client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); - client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); - client2.setAllowIntrospection(false); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [" + - - "{\"id\":1,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client1\",\"secret\":\"clientsecret1\"," - + "\"redirectUris\":[\"http://foo.com/\"]," - + "\"scope\":[\"foo\",\"bar\",\"baz\",\"dolphin\"]," - + "\"grantTypes\":[\"implicit\",\"authorization_code\",\"urn:ietf:params:oauth:grant_type:redelegate\",\"refresh_token\"]," - + "\"allowIntrospection\":true}," + - "{\"id\":2,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client2\",\"secret\":\"clientsecret2\"," - + "\"redirectUris\":[\"http://bar.baz.com/\"]," - + "\"scope\":[\"foo\",\"dolphin\",\"electric-wombat\"]," - + "\"grantTypes\":[\"client_credentials\",\"urn:ietf:params:oauth:grant_type:redelegate\"]," - + "\"allowIntrospection\":false}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(clientRepository, times(2)).saveClient(capturedClients.capture()); - - List savedClients = capturedClients.getAllValues(); - - assertThat(savedClients.size(), is(2)); - - assertThat(savedClients.get(0).getAccessTokenValiditySeconds(), equalTo(client1.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(0).getClientId(), equalTo(client1.getClientId())); - assertThat(savedClients.get(0).getClientSecret(), equalTo(client1.getClientSecret())); - assertThat(savedClients.get(0).getRedirectUris(), equalTo(client1.getRedirectUris())); - assertThat(savedClients.get(0).getScope(), equalTo(client1.getScope())); - assertThat(savedClients.get(0).getGrantTypes(), equalTo(client1.getGrantTypes())); - assertThat(savedClients.get(0).isAllowIntrospection(), equalTo(client1.isAllowIntrospection())); - - assertThat(savedClients.get(1).getAccessTokenValiditySeconds(), equalTo(client2.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(1).getClientId(), equalTo(client2.getClientId())); - assertThat(savedClients.get(1).getClientSecret(), equalTo(client2.getClientSecret())); - assertThat(savedClients.get(1).getRedirectUris(), equalTo(client2.getRedirectUris())); - assertThat(savedClients.get(1).getScope(), equalTo(client2.getScope())); - assertThat(savedClients.get(1).getGrantTypes(), equalTo(client2.getGrantTypes())); - assertThat(savedClients.get(1).isAllowIntrospection(), equalTo(client2.isAllowIntrospection())); - } - - @Test - public void testImportBlacklistedSites() throws IOException { - BlacklistedSite site1 = new BlacklistedSite(); - site1.setId(1L); - site1.setUri("http://foo.com"); - - BlacklistedSite site2 = new BlacklistedSite(); - site2.setId(2L); - site2.setUri("http://bar.com"); - - BlacklistedSite site3 = new BlacklistedSite(); - site3.setId(3L); - site3.setUri("http://baz.com"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [" + - - "{\"id\":1,\"uri\":\"http://foo.com\"}," + - "{\"id\":2,\"uri\":\"http://bar.com\"}," + - "{\"id\":3,\"uri\":\"http://baz.com\"}" + - - " ]" + - "}"; - - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(blSiteRepository, times(3)).save(capturedBlacklistedSites.capture()); - - List savedSites = capturedBlacklistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getUri(), equalTo(site1.getUri())); - assertThat(savedSites.get(1).getUri(), equalTo(site2.getUri())); - assertThat(savedSites.get(2).getUri(), equalTo(site3.getUri())); - } - - @Test - public void testImportWhitelistedSites() throws IOException { - WhitelistedSite site1 = new WhitelistedSite(); - site1.setId(1L); - site1.setClientId("foo"); - - WhitelistedSite site2 = new WhitelistedSite(); - site2.setId(2L); - site2.setClientId("bar"); - - WhitelistedSite site3 = new WhitelistedSite(); - site3.setId(3L); - site3.setClientId("baz"); - //site3.setAllowedScopes(null); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\"}," + - "{\"id\":2,\"clientId\":\"bar\"}," + - "{\"id\":3,\"clientId\":\"baz\"}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(wlSiteRepository.save(isA(WhitelistedSite.class))).thenAnswer(new Answer() { - Long id = 333L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = (WhitelistedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(wlSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - - dataService.importData(reader); - verify(wlSiteRepository, times(3)).save(capturedWhitelistedSites.capture()); - - List savedSites = capturedWhitelistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(2).getClientId(), equalTo(site3.getClientId())); - } - - @Test - public void testImportGrants() throws IOException, ParseException { - - Date creationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - Date accessDate1 = formatter.parse("2014-09-10T23:49:44.090+00:00", Locale.ENGLISH); - - OAuth2AccessTokenEntity mockToken1 = mock(OAuth2AccessTokenEntity.class); - when(mockToken1.getId()).thenReturn(1L); - - ApprovedSite site1 = new ApprovedSite(); - site1.setId(1L); - site1.setClientId("foo"); - site1.setCreationDate(creationDate1); - site1.setAccessDate(accessDate1); - site1.setUserId("user1"); - site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); - when(mockToken1.getApprovedSite()).thenReturn(site1); - - Date creationDate2 = formatter.parse("2014-09-11T18:49:44.090+00:00", Locale.ENGLISH); - Date accessDate2 = formatter.parse("2014-09-11T20:49:44.090+00:00", Locale.ENGLISH); - Date timeoutDate2 = formatter.parse("2014-10-01T20:49:44.090+00:00", Locale.ENGLISH); - - ApprovedSite site2 = new ApprovedSite(); - site2.setId(2L); - site2.setClientId("bar"); - site2.setCreationDate(creationDate2); - site2.setAccessDate(accessDate2); - site2.setUserId("user2"); - site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); - site2.setTimeoutDate(timeoutDate2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\",\"creationDate\":\"2014-09-10T22:49:44.090+00:00\",\"accessDate\":\"2014-09-10T23:49:44.090+00:00\"," - + "\"userId\":\"user1\",\"whitelistedSiteId\":null,\"allowedScopes\":[\"openid\",\"phone\"], \"whitelistedSiteId\":1," - + "\"approvedAccessTokens\":[1]}," + - "{\"id\":2,\"clientId\":\"bar\",\"creationDate\":\"2014-09-11T18:49:44.090+00:00\",\"accessDate\":\"2014-09-11T20:49:44.090+00:00\"," - + "\"timeoutDate\":\"2014-10-01T20:49:44.090+00:00\",\"userId\":\"user2\"," - + "\"allowedScopes\":[\"openid\",\"offline_access\",\"email\",\"profile\"]}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(approvedSiteRepository.save(isA(ApprovedSite.class))).thenAnswer(new Answer() { - Long id = 364L; - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - ApprovedSite _site = (ApprovedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(approvedSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(wlSiteRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 432L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = mock(WhitelistedSite.class); - when(_site.getId()).thenReturn(id++); - return _site; - } - }); - when(tokenRepository.getAccessTokenById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 245L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = mock(OAuth2AccessTokenEntity.class); - when(_token.getId()).thenReturn(id++); - return _token; - } - }); - - dataService.importData(reader); - //2 for sites, 1 for updating access token ref on #1 - verify(approvedSiteRepository, times(3)).save(capturedApprovedSites.capture()); - - List savedSites = new ArrayList(fakeDb.values()); - - assertThat(savedSites.size(), is(2)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(0).getAccessDate(), equalTo(site1.getAccessDate())); - assertThat(savedSites.get(0).getCreationDate(), equalTo(site1.getCreationDate())); - assertThat(savedSites.get(0).getAllowedScopes(), equalTo(site1.getAllowedScopes())); - assertThat(savedSites.get(0).getTimeoutDate(), equalTo(site1.getTimeoutDate())); - - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(1).getAccessDate(), equalTo(site2.getAccessDate())); - assertThat(savedSites.get(1).getCreationDate(), equalTo(site2.getCreationDate())); - assertThat(savedSites.get(1).getAllowedScopes(), equalTo(site2.getAllowedScopes())); - assertThat(savedSites.get(1).getTimeoutDate(), equalTo(site2.getTimeoutDate())); - } - - @Test - public void testImportAuthenticationHolders() throws IOException { - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"}," - + "\"userAuthentication\":null}}," + - "{\"id\":2,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"}," - + "\"userAuthentication\":null}}" + - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 243L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _site = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - - dataService.importData(reader); - verify(authHolderRepository, times(2)).save(capturedAuthHolders.capture()); - - List savedAuthHolders = capturedAuthHolders.getAllValues(); - - assertThat(savedAuthHolders.size(), is(2)); - assertThat(savedAuthHolders.get(0).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder1.getAuthentication().getOAuth2Request().getClientId())); - assertThat(savedAuthHolders.get(1).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder2.getAuthentication().getOAuth2Request().getClientId())); - } - - @Test - public void testImportSystemScopes() throws IOException { - SystemScope scope1 = new SystemScope(); - scope1.setId(1L); - scope1.setValue("scope1"); - scope1.setDescription("Scope 1"); - scope1.setRestricted(true); - scope1.setDefaultScope(false); - scope1.setIcon("glass"); - - SystemScope scope2 = new SystemScope(); - scope2.setId(2L); - scope2.setValue("scope2"); - scope2.setDescription("Scope 2"); - scope2.setRestricted(false); - scope2.setDefaultScope(false); - scope2.setIcon("ball"); - - SystemScope scope3 = new SystemScope(); - scope3.setId(3L); - scope3.setValue("scope3"); - scope3.setDescription("Scope 3"); - scope3.setRestricted(false); - scope3.setDefaultScope(true); - scope3.setIcon("road"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [" + - - "{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"allowDynReg\":false,\"defaultScope\":false}," + - "{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"allowDynReg\":true,\"defaultScope\":false}," + - "{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"allowDynReg\":true,\"defaultScope\":true}" + - - " ]" + - "}"; - - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(sysScopeRepository, times(3)).save(capturedScope.capture()); - - List savedScopes = capturedScope.getAllValues(); - - assertThat(savedScopes.size(), is(3)); - assertThat(savedScopes.get(0).getValue(), equalTo(scope1.getValue())); - assertThat(savedScopes.get(0).getDescription(), equalTo(scope1.getDescription())); - assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon())); - assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope())); - assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted())); - - assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue())); - assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription())); - assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon())); - assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope())); - assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted())); - - assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue())); - assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription())); - assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon())); - assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope())); - assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted())); - - } - - @Test - public void testFixRefreshTokenAuthHolderReferencesOnImport() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(holder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(holder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"}," - + "\"userAuthentication\":null}}," + - "{\"id\":2,\"authentication\":{\"clientAuthorization\":{\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"}," - + "\"userAuthentication\":null}}" + - " ]," + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - System.err.println(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - final Map fakeRefreshTokenTable = new HashMap<>(); - final Map fakeAuthHolderTable = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeRefreshTokenTable.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeRefreshTokenTable.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 356L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _holder = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_holder.getId() == null) { - _holder.setId(id++); - } - fakeAuthHolderTable.put(_holder.getId(), _holder); - return _holder; - } - }); - when(authHolderRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeAuthHolderTable.get(_id); - } - }); - dataService.importData(reader); - - List savedRefreshTokens = new ArrayList(fakeRefreshTokenTable.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.get(0).getAuthenticationHolder().getId(), equalTo(356L)); - assertThat(savedRefreshTokens.get(1).getAuthenticationHolder().getId(), equalTo(357L)); - } - - @Test(expected = UnsupportedOperationException.class) - public void testExportDisabled() throws IOException { - JsonWriter writer = new JsonWriter(new StringWriter()); - dataService.exportData(writer); - } - -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java deleted file mode 100644 index ffb9304fdc..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java +++ /dev/null @@ -1,977 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -import java.io.IOException; -import java.io.StringReader; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.format.annotation.DateTimeFormat.ISO; -import org.springframework.format.datetime.DateFormatter; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import com.google.common.collect.ImmutableSet; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.stream.JsonReader; -import com.nimbusds.jwt.JWTParser; - -@RunWith(MockitoJUnitRunner.class) -@SuppressWarnings(value = {"rawtypes", "unchecked"}) -public class TestMITREidDataService_1_2 { - - private static Logger logger = LoggerFactory.getLogger(TestMITREidDataService_1_2.class); - - @Mock - private OAuth2ClientRepository clientRepository; - @Mock - private ApprovedSiteRepository approvedSiteRepository; - @Mock - private WhitelistedSiteRepository wlSiteRepository; - @Mock - private BlacklistedSiteRepository blSiteRepository; - @Mock - private AuthenticationHolderRepository authHolderRepository; - @Mock - private OAuth2TokenRepository tokenRepository; - @Mock - private SystemScopeRepository sysScopeRepository; - - @Captor - private ArgumentCaptor capturedRefreshTokens; - @Captor - private ArgumentCaptor capturedAccessTokens; - @Captor - private ArgumentCaptor capturedClients; - @Captor - private ArgumentCaptor capturedBlacklistedSites; - @Captor - private ArgumentCaptor capturedWhitelistedSites; - @Captor - private ArgumentCaptor capturedApprovedSites; - @Captor - private ArgumentCaptor capturedAuthHolders; - @Captor - private ArgumentCaptor capturedScope; - - @InjectMocks - private MITREidDataService_1_2 dataService; - private DateFormatter formatter; - - @Before - public void prepare() { - formatter = new DateFormatter(); - formatter.setIso(ISO.DATE_TIME); - - Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository, wlSiteRepository, blSiteRepository); - } - - private class refreshTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2RefreshTokenEntity entity1, OAuth2RefreshTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - - @Test - public void testImportRefreshTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(mockedAuthHolder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(mockedAuthHolder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - - logger.debug(configJson); - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 332L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 131L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder - verify(tokenRepository, times(6)).saveRefreshToken(capturedRefreshTokens.capture()); - - List savedRefreshTokens = new ArrayList(fakeDb.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.size(), is(2)); - - assertThat(savedRefreshTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedRefreshTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedRefreshTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedRefreshTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedRefreshTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedRefreshTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - private class accessTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2AccessTokenEntity entity1, OAuth2AccessTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - @Test - public void testImportAccessTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0")); - token1.setAuthenticationHolder(mockedAuthHolder1); - token1.setScope(ImmutableSet.of("id-token")); - token1.setTokenType("Bearer"); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); - when(mockRefreshToken2.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ")); - token2.setAuthenticationHolder(mockedAuthHolder2); - token2.setRefreshToken(mockRefreshToken2); - token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); - token2.setTokenType("Bearer"); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"refreshTokenId\":null,\"idTokenId\":null,\"scope\":[\"id-token\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"refreshTokenId\":1,\"idTokenId\":1,\"scope\":[\"openid\",\"offline_access\",\"email\",\"profile\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ\"}" + - - " ]" + - "}"; - - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveAccessToken(isA(OAuth2AccessTokenEntity.class))).thenAnswer(new Answer() { - Long id = 324L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = (OAuth2AccessTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getAccessTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 133L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder, 1 times to update refresh token - verify(tokenRepository, times(7)).saveAccessToken(capturedAccessTokens.capture()); - - List savedAccessTokens = new ArrayList(fakeDb.values()); //capturedAccessTokens.getAllValues(); - Collections.sort(savedAccessTokens, new accessTokenIdComparator()); - - assertThat(savedAccessTokens.size(), is(2)); - - assertThat(savedAccessTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedAccessTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedAccessTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedAccessTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedAccessTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedAccessTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - @Test - public void testImportClients() throws IOException { - ClientDetailsEntity client1 = new ClientDetailsEntity(); - client1.setId(1L); - client1.setAccessTokenValiditySeconds(3600); - client1.setClientId("client1"); - client1.setClientSecret("clientsecret1"); - client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); - client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); - client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); - client1.setAllowIntrospection(true); - - ClientDetailsEntity client2 = new ClientDetailsEntity(); - client2.setId(2L); - client2.setAccessTokenValiditySeconds(3600); - client2.setClientId("client2"); - client2.setClientSecret("clientsecret2"); - client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); - client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); - client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); - client2.setAllowIntrospection(false); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [" + - - "{\"id\":1,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client1\",\"secret\":\"clientsecret1\"," - + "\"redirectUris\":[\"http://foo.com/\"]," - + "\"scope\":[\"foo\",\"bar\",\"baz\",\"dolphin\"]," - + "\"grantTypes\":[\"implicit\",\"authorization_code\",\"urn:ietf:params:oauth:grant_type:redelegate\",\"refresh_token\"]," - + "\"allowIntrospection\":true}," + - "{\"id\":2,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client2\",\"secret\":\"clientsecret2\"," - + "\"redirectUris\":[\"http://bar.baz.com/\"]," - + "\"scope\":[\"foo\",\"dolphin\",\"electric-wombat\"]," - + "\"grantTypes\":[\"client_credentials\",\"urn:ietf:params:oauth:grant_type:redelegate\"]," - + "\"allowIntrospection\":false}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(clientRepository, times(2)).saveClient(capturedClients.capture()); - - List savedClients = capturedClients.getAllValues(); - - assertThat(savedClients.size(), is(2)); - - assertThat(savedClients.get(0).getAccessTokenValiditySeconds(), equalTo(client1.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(0).getClientId(), equalTo(client1.getClientId())); - assertThat(savedClients.get(0).getClientSecret(), equalTo(client1.getClientSecret())); - assertThat(savedClients.get(0).getRedirectUris(), equalTo(client1.getRedirectUris())); - assertThat(savedClients.get(0).getScope(), equalTo(client1.getScope())); - assertThat(savedClients.get(0).getGrantTypes(), equalTo(client1.getGrantTypes())); - assertThat(savedClients.get(0).isAllowIntrospection(), equalTo(client1.isAllowIntrospection())); - - assertThat(savedClients.get(1).getAccessTokenValiditySeconds(), equalTo(client2.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(1).getClientId(), equalTo(client2.getClientId())); - assertThat(savedClients.get(1).getClientSecret(), equalTo(client2.getClientSecret())); - assertThat(savedClients.get(1).getRedirectUris(), equalTo(client2.getRedirectUris())); - assertThat(savedClients.get(1).getScope(), equalTo(client2.getScope())); - assertThat(savedClients.get(1).getGrantTypes(), equalTo(client2.getGrantTypes())); - assertThat(savedClients.get(1).isAllowIntrospection(), equalTo(client2.isAllowIntrospection())); - } - - @Test - public void testImportBlacklistedSites() throws IOException { - BlacklistedSite site1 = new BlacklistedSite(); - site1.setId(1L); - site1.setUri("http://foo.com"); - - BlacklistedSite site2 = new BlacklistedSite(); - site2.setId(2L); - site2.setUri("http://bar.com"); - - BlacklistedSite site3 = new BlacklistedSite(); - site3.setId(3L); - site3.setUri("http://baz.com"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [" + - - "{\"id\":1,\"uri\":\"http://foo.com\"}," + - "{\"id\":2,\"uri\":\"http://bar.com\"}," + - "{\"id\":3,\"uri\":\"http://baz.com\"}" + - - " ]" + - "}"; - - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(blSiteRepository, times(3)).save(capturedBlacklistedSites.capture()); - - List savedSites = capturedBlacklistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getUri(), equalTo(site1.getUri())); - assertThat(savedSites.get(1).getUri(), equalTo(site2.getUri())); - assertThat(savedSites.get(2).getUri(), equalTo(site3.getUri())); - } - - @Test - public void testImportWhitelistedSites() throws IOException { - WhitelistedSite site1 = new WhitelistedSite(); - site1.setId(1L); - site1.setClientId("foo"); - - WhitelistedSite site2 = new WhitelistedSite(); - site2.setId(2L); - site2.setClientId("bar"); - - WhitelistedSite site3 = new WhitelistedSite(); - site3.setId(3L); - site3.setClientId("baz"); - //site3.setAllowedScopes(null); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\"}," + - "{\"id\":2,\"clientId\":\"bar\"}," + - "{\"id\":3,\"clientId\":\"baz\"}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(wlSiteRepository.save(isA(WhitelistedSite.class))).thenAnswer(new Answer() { - Long id = 333L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = (WhitelistedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(wlSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - - dataService.importData(reader); - verify(wlSiteRepository, times(3)).save(capturedWhitelistedSites.capture()); - - List savedSites = capturedWhitelistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(2).getClientId(), equalTo(site3.getClientId())); - } - - @Test - public void testImportGrants() throws IOException, ParseException { - - Date creationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - Date accessDate1 = formatter.parse("2014-09-10T23:49:44.090+00:00", Locale.ENGLISH); - - OAuth2AccessTokenEntity mockToken1 = mock(OAuth2AccessTokenEntity.class); - when(mockToken1.getId()).thenReturn(1L); - - ApprovedSite site1 = new ApprovedSite(); - site1.setId(1L); - site1.setClientId("foo"); - site1.setCreationDate(creationDate1); - site1.setAccessDate(accessDate1); - site1.setUserId("user1"); - site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); - when(mockToken1.getApprovedSite()).thenReturn(site1); - - Date creationDate2 = formatter.parse("2014-09-11T18:49:44.090+00:00", Locale.ENGLISH); - Date accessDate2 = formatter.parse("2014-09-11T20:49:44.090+00:00", Locale.ENGLISH); - Date timeoutDate2 = formatter.parse("2014-10-01T20:49:44.090+00:00", Locale.ENGLISH); - - ApprovedSite site2 = new ApprovedSite(); - site2.setId(2L); - site2.setClientId("bar"); - site2.setCreationDate(creationDate2); - site2.setAccessDate(accessDate2); - site2.setUserId("user2"); - site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); - site2.setTimeoutDate(timeoutDate2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\",\"creationDate\":\"2014-09-10T22:49:44.090+00:00\",\"accessDate\":\"2014-09-10T23:49:44.090+00:00\"," - + "\"userId\":\"user1\",\"whitelistedSiteId\":null,\"allowedScopes\":[\"openid\",\"phone\"], \"whitelistedSiteId\":1," - + "\"approvedAccessTokens\":[1]}," + - "{\"id\":2,\"clientId\":\"bar\",\"creationDate\":\"2014-09-11T18:49:44.090+00:00\",\"accessDate\":\"2014-09-11T20:49:44.090+00:00\"," - + "\"timeoutDate\":\"2014-10-01T20:49:44.090+00:00\",\"userId\":\"user2\"," - + "\"allowedScopes\":[\"openid\",\"offline_access\",\"email\",\"profile\"]}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(approvedSiteRepository.save(isA(ApprovedSite.class))).thenAnswer(new Answer() { - Long id = 364L; - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - ApprovedSite _site = (ApprovedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(approvedSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(wlSiteRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 432L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = mock(WhitelistedSite.class); - when(_site.getId()).thenReturn(id++); - return _site; - } - }); - when(tokenRepository.getAccessTokenById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 245L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = mock(OAuth2AccessTokenEntity.class); - when(_token.getId()).thenReturn(id++); - return _token; - } - }); - - dataService.importData(reader); - //2 for sites, 1 for updating access token ref on #1 - verify(approvedSiteRepository, times(3)).save(capturedApprovedSites.capture()); - - List savedSites = new ArrayList(fakeDb.values()); - - assertThat(savedSites.size(), is(2)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(0).getAccessDate(), equalTo(site1.getAccessDate())); - assertThat(savedSites.get(0).getCreationDate(), equalTo(site1.getCreationDate())); - assertThat(savedSites.get(0).getAllowedScopes(), equalTo(site1.getAllowedScopes())); - assertThat(savedSites.get(0).getTimeoutDate(), equalTo(site1.getTimeoutDate())); - - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(1).getAccessDate(), equalTo(site2.getAccessDate())); - assertThat(savedSites.get(1).getCreationDate(), equalTo(site2.getCreationDate())); - assertThat(savedSites.get(1).getAllowedScopes(), equalTo(site2.getAllowedScopes())); - assertThat(savedSites.get(1).getTimeoutDate(), equalTo(site2.getTimeoutDate())); - } - - @Test - public void testImportAuthenticationHolders() throws IOException { - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"," - + "\"savedUserAuthentication\":null}," + - "{\"id\":2,\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"," - + "\"savedUserAuthentication\":null}" + - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 243L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _site = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - - dataService.importData(reader); - verify(authHolderRepository, times(2)).save(capturedAuthHolders.capture()); - - List savedAuthHolders = capturedAuthHolders.getAllValues(); - - assertThat(savedAuthHolders.size(), is(2)); - assertThat(savedAuthHolders.get(0).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder1.getAuthentication().getOAuth2Request().getClientId())); - assertThat(savedAuthHolders.get(1).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder2.getAuthentication().getOAuth2Request().getClientId())); - } - - @Test - public void testImportSystemScopes() throws IOException { - SystemScope scope1 = new SystemScope(); - scope1.setId(1L); - scope1.setValue("scope1"); - scope1.setDescription("Scope 1"); - scope1.setRestricted(true); - scope1.setDefaultScope(false); - scope1.setIcon("glass"); - - SystemScope scope2 = new SystemScope(); - scope2.setId(2L); - scope2.setValue("scope2"); - scope2.setDescription("Scope 2"); - scope2.setRestricted(false); - scope2.setDefaultScope(false); - scope2.setIcon("ball"); - - SystemScope scope3 = new SystemScope(); - scope3.setId(3L); - scope3.setValue("scope3"); - scope3.setDescription("Scope 3"); - scope3.setRestricted(false); - scope3.setDefaultScope(true); - scope3.setIcon("road"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [" + - - "{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"restricted\":true,\"defaultScope\":false}," + - "{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"restricted\":false,\"defaultScope\":false}," + - "{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"restricted\":false,\"defaultScope\":true}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(sysScopeRepository, times(3)).save(capturedScope.capture()); - - List savedScopes = capturedScope.getAllValues(); - - assertThat(savedScopes.size(), is(3)); - assertThat(savedScopes.get(0).getValue(), equalTo(scope1.getValue())); - assertThat(savedScopes.get(0).getDescription(), equalTo(scope1.getDescription())); - assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon())); - assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope())); - assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted())); - - assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue())); - assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription())); - assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon())); - assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope())); - assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted())); - - assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue())); - assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription())); - assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon())); - assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope())); - assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted())); - - } - - @Test - public void testFixRefreshTokenAuthHolderReferencesOnImport() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(holder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(holder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"authentication\":{\"authorizationRequest\":{\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"}," - + "\"userAuthentication\":null}}," + - "{\"id\":2,\"authentication\":{\"authorizationRequest\":{\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"}," - + "\"userAuthentication\":null}}" + - " ]," + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - final Map fakeRefreshTokenTable = new HashMap<>(); - final Map fakeAuthHolderTable = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeRefreshTokenTable.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeRefreshTokenTable.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 356L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _holder = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_holder.getId() == null) { - _holder.setId(id++); - } - fakeAuthHolderTable.put(_holder.getId(), _holder); - return _holder; - } - }); - when(authHolderRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeAuthHolderTable.get(_id); - } - }); - dataService.importData(reader); - - List savedRefreshTokens = new ArrayList(fakeRefreshTokenTable.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.get(0).getAuthenticationHolder().getId(), equalTo(356L)); - assertThat(savedRefreshTokens.get(1).getAuthenticationHolder().getId(), equalTo(357L)); - } - - private Set jsonArrayToStringSet(JsonArray a) { - Set s = new HashSet<>(); - for (JsonElement jsonElement : a) { - s.add(jsonElement.getAsString()); - } - return s; - } - -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java deleted file mode 100644 index 2413cc1884..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java +++ /dev/null @@ -1,1862 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.openid.connect.service.impl; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.isA; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.OAuth2RefreshTokenEntity; -import org.mitre.oauth2.model.PKCEAlgorithm; -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.repository.OAuth2ClientRepository; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.oauth2.repository.SystemScopeRepository; -import org.mitre.openid.connect.model.ApprovedSite; -import org.mitre.openid.connect.model.BlacklistedSite; -import org.mitre.openid.connect.model.WhitelistedSite; -import org.mitre.openid.connect.repository.ApprovedSiteRepository; -import org.mitre.openid.connect.repository.BlacklistedSiteRepository; -import org.mitre.openid.connect.repository.WhitelistedSiteRepository; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.format.annotation.DateTimeFormat.ISO; -import org.springframework.format.datetime.DateFormatter; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.nimbusds.jwt.JWTParser; - -@RunWith(MockitoJUnitRunner.class) -@SuppressWarnings(value = {"rawtypes", "unchecked"}) -public class TestMITREidDataService_1_3 { - - private static Logger logger = LoggerFactory.getLogger(TestMITREidDataService_1_3.class); - - @Mock - private OAuth2ClientRepository clientRepository; - @Mock - private ApprovedSiteRepository approvedSiteRepository; - @Mock - private WhitelistedSiteRepository wlSiteRepository; - @Mock - private BlacklistedSiteRepository blSiteRepository; - @Mock - private AuthenticationHolderRepository authHolderRepository; - @Mock - private OAuth2TokenRepository tokenRepository; - @Mock - private SystemScopeRepository sysScopeRepository; - - @Captor - private ArgumentCaptor capturedRefreshTokens; - @Captor - private ArgumentCaptor capturedAccessTokens; - @Captor - private ArgumentCaptor capturedClients; - @Captor - private ArgumentCaptor capturedBlacklistedSites; - @Captor - private ArgumentCaptor capturedWhitelistedSites; - @Captor - private ArgumentCaptor capturedApprovedSites; - @Captor - private ArgumentCaptor capturedAuthHolders; - @Captor - private ArgumentCaptor capturedScope; - - @InjectMocks - private MITREidDataService_1_3 dataService; - private DateFormatter formatter; - - @Before - public void prepare() { - formatter = new DateFormatter(); - formatter.setIso(ISO.DATE_TIME); - - Mockito.reset(clientRepository, approvedSiteRepository, authHolderRepository, tokenRepository, sysScopeRepository, wlSiteRepository, blSiteRepository); - } - - @Test - public void testExportRefreshTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(mockedAuthHolder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(mockedAuthHolder2); - - Set allRefreshTokens = ImmutableSet.of(token1, token2); - - Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(allRefreshTokens); - Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - - // check our refresh token list (this test) - JsonArray refreshTokens = config.get(MITREidDataService.REFRESHTOKENS).getAsJsonArray(); - - assertThat(refreshTokens.size(), is(2)); - // check for both of our refresh tokens in turn - Set checked = new HashSet<>(); - for (JsonElement e : refreshTokens) { - assertThat(e.isJsonObject(), is(true)); - JsonObject token = e.getAsJsonObject(); - - OAuth2RefreshTokenEntity compare = null; - if (token.get("id").getAsLong() == token1.getId()) { - compare = token1; - } else if (token.get("id").getAsLong() == token2.getId()) { - compare = token2; - } - - if (compare == null) { - fail("Could not find matching id: " + token.get("id").getAsString()); - } else { - assertThat(token.get("id").getAsLong(), equalTo(compare.getId())); - assertThat(token.get("clientId").getAsString(), equalTo(compare.getClient().getClientId())); - assertThat(token.get("expiration").getAsString(), equalTo(formatter.print(compare.getExpiration(), Locale.ENGLISH))); - assertThat(token.get("value").getAsString(), equalTo(compare.getValue())); - assertThat(token.get("authenticationHolderId").getAsLong(), equalTo(compare.getAuthenticationHolder().getId())); - checked.add(compare); - } - } - // make sure all of our refresh tokens were found - assertThat(checked.containsAll(allRefreshTokens), is(true)); - } - - private class refreshTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2RefreshTokenEntity entity1, OAuth2RefreshTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - - @Test - public void testImportRefreshTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(mockedAuthHolder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(mockedAuthHolder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - - logger.debug(configJson); - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 332L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 131L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder - verify(tokenRepository, times(6)).saveRefreshToken(capturedRefreshTokens.capture()); - - List savedRefreshTokens = new ArrayList(fakeDb.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.size(), is(2)); - - assertThat(savedRefreshTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedRefreshTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedRefreshTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedRefreshTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedRefreshTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedRefreshTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - @Test - public void testExportAccessTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0")); - token1.setAuthenticationHolder(mockedAuthHolder1); - token1.setScope(ImmutableSet.of("id-token")); - token1.setTokenType("Bearer"); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); - when(mockRefreshToken2.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ")); - token2.setAuthenticationHolder(mockedAuthHolder2); - token2.setRefreshToken(mockRefreshToken2); - token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); - token2.setTokenType("Bearer"); - - Set allAccessTokens = ImmutableSet.of(token1, token2); - - Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(allAccessTokens); - Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - - // check our access token list (this test) - JsonArray accessTokens = config.get(MITREidDataService.ACCESSTOKENS).getAsJsonArray(); - - assertThat(accessTokens.size(), is(2)); - // check for both of our access tokens in turn - Set checked = new HashSet<>(); - for (JsonElement e : accessTokens) { - assertTrue(e.isJsonObject()); - JsonObject token = e.getAsJsonObject(); - - OAuth2AccessTokenEntity compare = null; - if (token.get("id").getAsLong() == token1.getId().longValue()) { - compare = token1; - } else if (token.get("id").getAsLong() == token2.getId().longValue()) { - compare = token2; - } - - if (compare == null) { - fail("Could not find matching id: " + token.get("id").getAsString()); - } else { - assertThat(token.get("id").getAsLong(), equalTo(compare.getId())); - assertThat(token.get("clientId").getAsString(), equalTo(compare.getClient().getClientId())); - assertThat(token.get("expiration").getAsString(), equalTo(formatter.print(compare.getExpiration(), Locale.ENGLISH))); - assertThat(token.get("value").getAsString(), equalTo(compare.getValue())); - assertThat(token.get("type").getAsString(), equalTo(compare.getTokenType())); - assertThat(token.get("authenticationHolderId").getAsLong(), equalTo(compare.getAuthenticationHolder().getId())); - assertTrue(token.get("scope").isJsonArray()); - assertThat(jsonArrayToStringSet(token.getAsJsonArray("scope")), equalTo(compare.getScope())); - if(token.get("refreshTokenId").isJsonNull()) { - assertNull(compare.getRefreshToken()); - } else { - assertThat(token.get("refreshTokenId").getAsLong(), equalTo(compare.getRefreshToken().getId())); - } - checked.add(compare); - } - } - // make sure all of our access tokens were found - assertThat(checked.containsAll(allAccessTokens), is(true)); - } - - private class accessTokenIdComparator implements Comparator { - @Override - public int compare(OAuth2AccessTokenEntity entity1, OAuth2AccessTokenEntity entity2) { - return entity1.getId().compareTo(entity2.getId()); - } - } - - @Test - public void testImportAccessTokens() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - AuthenticationHolderEntity mockedAuthHolder1 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder1.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token1 = new OAuth2AccessTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0")); - token1.setAuthenticationHolder(mockedAuthHolder1); - token1.setScope(ImmutableSet.of("id-token")); - token1.setTokenType("Bearer"); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - AuthenticationHolderEntity mockedAuthHolder2 = mock(AuthenticationHolderEntity.class); - when(mockedAuthHolder2.getId()).thenReturn(2L); - - OAuth2RefreshTokenEntity mockRefreshToken2 = mock(OAuth2RefreshTokenEntity.class); - when(mockRefreshToken2.getId()).thenReturn(1L); - - OAuth2AccessTokenEntity token2 = new OAuth2AccessTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ")); - token2.setAuthenticationHolder(mockedAuthHolder2); - token2.setRefreshToken(mockRefreshToken2); - token2.setScope(ImmutableSet.of("openid", "offline_access", "email", "profile")); - token2.setTokenType("Bearer"); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"refreshTokenId\":null,\"idTokenId\":null,\"scope\":[\"id-token\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3ODk5NjgsInN1YiI6IjkwMzQyLkFTREZKV0ZBIiwiYXRfaGFzaCI6InptTmt1QmNRSmNYQktNaVpFODZqY0EiLCJhdWQiOlsiY2xpZW50Il0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo4MDgwXC9vcGVuaWQtY29ubmVjdC1zZXJ2ZXItd2ViYXBwXC8iLCJpYXQiOjE0MTI3ODkzNjh9.xkEJ9IMXpH7qybWXomfq9WOOlpGYnrvGPgey9UQ4GLzbQx7JC0XgJK83PmrmBZosvFPCmota7FzI_BtwoZLgAZfFiH6w3WIlxuogoH-TxmYbxEpTHoTsszZppkq9mNgOlArV4jrR9y3TPo4MovsH71dDhS_ck-CvAlJunHlqhs0\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"refreshTokenId\":1,\"idTokenId\":1,\"scope\":[\"openid\",\"offline_access\",\"email\",\"profile\"],\"type\":\"Bearer\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MTI3OTI5NjgsImF1ZCI6WyJjbGllbnQiXSwiaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwODBcL29wZW5pZC1jb25uZWN0LXNlcnZlci13ZWJhcHBcLyIsImp0aSI6IjBmZGE5ZmRiLTYyYzItNGIzZS05OTdiLWU0M2VhMDUwMzNiOSIsImlhdCI6MTQxMjc4OTM2OH0.xgaVpRLYE5MzbgXfE0tZt823tjAm6Oh3_kdR1P2I9jRLR6gnTlBQFlYi3Y_0pWNnZSerbAE8Tn6SJHZ9k-curVG0-ByKichV7CNvgsE5X_2wpEaUzejvKf8eZ-BammRY-ie6yxSkAarcUGMvGGOLbkFcz5CtrBpZhfd75J49BIQ\"}" + - - " ]" + - "}"; - - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(tokenRepository.saveAccessToken(isA(OAuth2AccessTokenEntity.class))).thenAnswer(new Answer() { - Long id = 324L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = (OAuth2AccessTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeDb.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getAccessTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 133L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _auth = mock(AuthenticationHolderEntity.class); - when(_auth.getId()).thenReturn(id); - id++; - return _auth; - } - }); - dataService.importData(reader); - //2 times for token, 2 times to update client, 2 times to update authHolder, 1 times to update refresh token - verify(tokenRepository, times(7)).saveAccessToken(capturedAccessTokens.capture()); - - List savedAccessTokens = new ArrayList(fakeDb.values()); //capturedAccessTokens.getAllValues(); - Collections.sort(savedAccessTokens, new accessTokenIdComparator()); - - assertThat(savedAccessTokens.size(), is(2)); - - assertThat(savedAccessTokens.get(0).getClient().getClientId(), equalTo(token1.getClient().getClientId())); - assertThat(savedAccessTokens.get(0).getExpiration(), equalTo(token1.getExpiration())); - assertThat(savedAccessTokens.get(0).getValue(), equalTo(token1.getValue())); - - assertThat(savedAccessTokens.get(1).getClient().getClientId(), equalTo(token2.getClient().getClientId())); - assertThat(savedAccessTokens.get(1).getExpiration(), equalTo(token2.getExpiration())); - assertThat(savedAccessTokens.get(1).getValue(), equalTo(token2.getValue())); - } - - @Test - public void testExportClients() throws IOException { - ClientDetailsEntity client1 = new ClientDetailsEntity(); - client1.setId(1L); - client1.setAccessTokenValiditySeconds(3600); - client1.setClientId("client1"); - client1.setClientSecret("clientsecret1"); - client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); - client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); - client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); - client1.setAllowIntrospection(true); - - ClientDetailsEntity client2 = new ClientDetailsEntity(); - client2.setId(2L); - client2.setAccessTokenValiditySeconds(3600); - client2.setClientId("client2"); - client2.setClientSecret("clientsecret2"); - client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); - client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); - client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); - client2.setAllowIntrospection(false); - client2.setCodeChallengeMethod(PKCEAlgorithm.S256); - - Set allClients = ImmutableSet.of(client1, client2); - - Mockito.when(clientRepository.getAllClients()).thenReturn(allClients); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - - // check our client list (this test) - JsonArray clients = config.get(MITREidDataService.CLIENTS).getAsJsonArray(); - - assertThat(clients.size(), is(2)); - // check for both of our clients in turn - Set checked = new HashSet<>(); - for (JsonElement e : clients) { - assertThat(e.isJsonObject(), is(true)); - JsonObject client = e.getAsJsonObject(); - - ClientDetailsEntity compare = null; - if (client.get("clientId").getAsString().equals(client1.getClientId())) { - compare = client1; - } else if (client.get("clientId").getAsString().equals(client2.getClientId())) { - compare = client2; - } - - if (compare == null) { - fail("Could not find matching clientId: " + client.get("clientId").getAsString()); - } else { - assertThat(client.get("clientId").getAsString(), equalTo(compare.getClientId())); - assertThat(client.get("secret").getAsString(), equalTo(compare.getClientSecret())); - assertThat(client.get("accessTokenValiditySeconds").getAsInt(), equalTo(compare.getAccessTokenValiditySeconds())); - assertThat(client.get("allowIntrospection").getAsBoolean(), equalTo(compare.isAllowIntrospection())); - assertThat(jsonArrayToStringSet(client.get("redirectUris").getAsJsonArray()), equalTo(compare.getRedirectUris())); - assertThat(jsonArrayToStringSet(client.get("scope").getAsJsonArray()), equalTo(compare.getScope())); - assertThat(jsonArrayToStringSet(client.get("grantTypes").getAsJsonArray()), equalTo(compare.getGrantTypes())); - assertThat((client.has("codeChallengeMethod") && !client.get("codeChallengeMethod").isJsonNull()) ? PKCEAlgorithm.parse(client.get("codeChallengeMethod").getAsString()) : null, equalTo(compare.getCodeChallengeMethod())); - checked.add(compare); - } - } - // make sure all of our clients were found - assertThat(checked.containsAll(allClients), is(true)); - } - - @Test - public void testImportClients() throws IOException { - ClientDetailsEntity client1 = new ClientDetailsEntity(); - client1.setId(1L); - client1.setAccessTokenValiditySeconds(3600); - client1.setClientId("client1"); - client1.setClientSecret("clientsecret1"); - client1.setRedirectUris(ImmutableSet.of("http://foo.com/")); - client1.setScope(ImmutableSet.of("foo", "bar", "baz", "dolphin")); - client1.setGrantTypes(ImmutableSet.of("implicit", "authorization_code", "urn:ietf:params:oauth:grant_type:redelegate", "refresh_token")); - client1.setAllowIntrospection(true); - - ClientDetailsEntity client2 = new ClientDetailsEntity(); - client2.setId(2L); - client2.setAccessTokenValiditySeconds(3600); - client2.setClientId("client2"); - client2.setClientSecret("clientsecret2"); - client2.setRedirectUris(ImmutableSet.of("http://bar.baz.com/")); - client2.setScope(ImmutableSet.of("foo", "dolphin", "electric-wombat")); - client2.setGrantTypes(ImmutableSet.of("client_credentials", "urn:ietf:params:oauth:grant_type:redelegate")); - client2.setAllowIntrospection(false); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [" + - - "{\"id\":1,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client1\",\"secret\":\"clientsecret1\"," - + "\"redirectUris\":[\"http://foo.com/\"]," - + "\"scope\":[\"foo\",\"bar\",\"baz\",\"dolphin\"]," - + "\"grantTypes\":[\"implicit\",\"authorization_code\",\"urn:ietf:params:oauth:grant_type:redelegate\",\"refresh_token\"]," - + "\"allowIntrospection\":true}," + - "{\"id\":2,\"accessTokenValiditySeconds\":3600,\"clientId\":\"client2\",\"secret\":\"clientsecret2\"," - + "\"redirectUris\":[\"http://bar.baz.com/\"]," - + "\"scope\":[\"foo\",\"dolphin\",\"electric-wombat\"]," - + "\"grantTypes\":[\"client_credentials\",\"urn:ietf:params:oauth:grant_type:redelegate\"]," - + "\"allowIntrospection\":false}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(clientRepository, times(2)).saveClient(capturedClients.capture()); - - List savedClients = capturedClients.getAllValues(); - - assertThat(savedClients.size(), is(2)); - - assertThat(savedClients.get(0).getAccessTokenValiditySeconds(), equalTo(client1.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(0).getClientId(), equalTo(client1.getClientId())); - assertThat(savedClients.get(0).getClientSecret(), equalTo(client1.getClientSecret())); - assertThat(savedClients.get(0).getRedirectUris(), equalTo(client1.getRedirectUris())); - assertThat(savedClients.get(0).getScope(), equalTo(client1.getScope())); - assertThat(savedClients.get(0).getGrantTypes(), equalTo(client1.getGrantTypes())); - assertThat(savedClients.get(0).isAllowIntrospection(), equalTo(client1.isAllowIntrospection())); - - assertThat(savedClients.get(1).getAccessTokenValiditySeconds(), equalTo(client2.getAccessTokenValiditySeconds())); - assertThat(savedClients.get(1).getClientId(), equalTo(client2.getClientId())); - assertThat(savedClients.get(1).getClientSecret(), equalTo(client2.getClientSecret())); - assertThat(savedClients.get(1).getRedirectUris(), equalTo(client2.getRedirectUris())); - assertThat(savedClients.get(1).getScope(), equalTo(client2.getScope())); - assertThat(savedClients.get(1).getGrantTypes(), equalTo(client2.getGrantTypes())); - assertThat(savedClients.get(1).isAllowIntrospection(), equalTo(client2.isAllowIntrospection())); - } - - @Test - public void testExportBlacklistedSites() throws IOException { - BlacklistedSite site1 = new BlacklistedSite(); - site1.setId(1L); - site1.setUri("http://foo.com"); - - BlacklistedSite site2 = new BlacklistedSite(); - site2.setId(2L); - site2.setUri("http://bar.com"); - - BlacklistedSite site3 = new BlacklistedSite(); - site3.setId(3L); - site3.setUri("http://baz.com"); - - Set allBlacklistedSites = ImmutableSet.of(site1, site2, site3); - - Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(blSiteRepository.getAll()).thenReturn(allBlacklistedSites); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - // check our scope list (this test) - JsonArray sites = config.get(MITREidDataService.BLACKLISTEDSITES).getAsJsonArray(); - - assertThat(sites.size(), is(3)); - // check for both of our sites in turn - Set checked = new HashSet<>(); - for (JsonElement e : sites) { - assertThat(e.isJsonObject(), is(true)); - JsonObject site = e.getAsJsonObject(); - - BlacklistedSite compare = null; - if (site.get("id").getAsLong() == site1.getId().longValue()) { - compare = site1; - } else if (site.get("id").getAsLong() == site2.getId().longValue()) { - compare = site2; - } else if (site.get("id").getAsLong() == site3.getId().longValue()) { - compare = site3; - } - - if (compare == null) { - fail("Could not find matching blacklisted site id: " + site.get("id").getAsString()); - } else { - assertThat(site.get("uri").getAsString(), equalTo(compare.getUri())); - checked.add(compare); - } - } - // make sure all of our clients were found - assertThat(checked.containsAll(allBlacklistedSites), is(true)); - - } - - @Test - public void testImportBlacklistedSites() throws IOException { - BlacklistedSite site1 = new BlacklistedSite(); - site1.setId(1L); - site1.setUri("http://foo.com"); - - BlacklistedSite site2 = new BlacklistedSite(); - site2.setId(2L); - site2.setUri("http://bar.com"); - - BlacklistedSite site3 = new BlacklistedSite(); - site3.setId(3L); - site3.setUri("http://baz.com"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [" + - - "{\"id\":1,\"uri\":\"http://foo.com\"}," + - "{\"id\":2,\"uri\":\"http://bar.com\"}," + - "{\"id\":3,\"uri\":\"http://baz.com\"}" + - - " ]" + - "}"; - - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(blSiteRepository, times(3)).save(capturedBlacklistedSites.capture()); - - List savedSites = capturedBlacklistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getUri(), equalTo(site1.getUri())); - assertThat(savedSites.get(1).getUri(), equalTo(site2.getUri())); - assertThat(savedSites.get(2).getUri(), equalTo(site3.getUri())); - } - - @Test - public void testExportWhitelistedSites() throws IOException { - WhitelistedSite site1 = new WhitelistedSite(); - site1.setId(1L); - site1.setClientId("foo"); - - WhitelistedSite site2 = new WhitelistedSite(); - site2.setId(2L); - site2.setClientId("bar"); - - WhitelistedSite site3 = new WhitelistedSite(); - site3.setId(3L); - site3.setClientId("baz"); - - Set allWhitelistedSites = ImmutableSet.of(site1, site2, site3); - - Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(allWhitelistedSites); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - // check our scope list (this test) - JsonArray sites = config.get(MITREidDataService.WHITELISTEDSITES).getAsJsonArray(); - - assertThat(sites.size(), is(3)); - // check for both of our sites in turn - Set checked = new HashSet<>(); - for (JsonElement e : sites) { - assertThat(e.isJsonObject(), is(true)); - JsonObject site = e.getAsJsonObject(); - - WhitelistedSite compare = null; - if (site.get("id").getAsLong() == site1.getId().longValue()) { - compare = site1; - } else if (site.get("id").getAsLong() == site2.getId().longValue()) { - compare = site2; - } else if (site.get("id").getAsLong() == site3.getId().longValue()) { - compare = site3; - } - - if (compare == null) { - fail("Could not find matching whitelisted site id: " + site.get("id").getAsString()); - } else { - assertThat(site.get("clientId").getAsString(), equalTo(compare.getClientId())); - checked.add(compare); - } - } - // make sure all of our clients were found - assertThat(checked.containsAll(allWhitelistedSites), is(true)); - - } - - @Test - public void testImportWhitelistedSites() throws IOException { - WhitelistedSite site1 = new WhitelistedSite(); - site1.setId(1L); - site1.setClientId("foo"); - - WhitelistedSite site2 = new WhitelistedSite(); - site2.setId(2L); - site2.setClientId("bar"); - - WhitelistedSite site3 = new WhitelistedSite(); - site3.setId(3L); - site3.setClientId("baz"); - //site3.setAllowedScopes(null); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\"}," + - "{\"id\":2,\"clientId\":\"bar\"}," + - "{\"id\":3,\"clientId\":\"baz\"}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(wlSiteRepository.save(isA(WhitelistedSite.class))).thenAnswer(new Answer() { - Long id = 333L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = (WhitelistedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(wlSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - - dataService.importData(reader); - verify(wlSiteRepository, times(3)).save(capturedWhitelistedSites.capture()); - - List savedSites = capturedWhitelistedSites.getAllValues(); - - assertThat(savedSites.size(), is(3)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(2).getClientId(), equalTo(site3.getClientId())); - } - - @Test - public void testExportGrants() throws IOException, ParseException { - - Date creationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - Date accessDate1 = formatter.parse("2014-09-10T23:49:44.090+00:00", Locale.ENGLISH); - - OAuth2AccessTokenEntity mockToken1 = mock(OAuth2AccessTokenEntity.class); - when(mockToken1.getId()).thenReturn(1L); - - ApprovedSite site1 = new ApprovedSite(); - site1.setId(1L); - site1.setClientId("foo"); - site1.setCreationDate(creationDate1); - site1.setAccessDate(accessDate1); - site1.setUserId("user1"); - site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); - when(mockToken1.getApprovedSite()).thenReturn(site1); - - Date creationDate2 = formatter.parse("2014-09-11T18:49:44.090+00:00", Locale.ENGLISH); - Date accessDate2 = formatter.parse("2014-09-11T20:49:44.090+00:00", Locale.ENGLISH); - Date timeoutDate2 = formatter.parse("2014-10-01T20:49:44.090+00:00", Locale.ENGLISH); - - ApprovedSite site2 = new ApprovedSite(); - site2.setId(2L); - site2.setClientId("bar"); - site2.setCreationDate(creationDate2); - site2.setAccessDate(accessDate2); - site2.setUserId("user2"); - site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); - site2.setTimeoutDate(timeoutDate2); - - Set allApprovedSites = ImmutableSet.of(site1, site2); - - Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(allApprovedSites); - Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - Mockito.when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - // check our scope list (this test) - JsonArray sites = config.get(MITREidDataService.GRANTS).getAsJsonArray(); - - assertThat(sites.size(), is(2)); - // check for both of our sites in turn - Set checked = new HashSet<>(); - for (JsonElement e : sites) { - assertThat(e.isJsonObject(), is(true)); - JsonObject site = e.getAsJsonObject(); - - ApprovedSite compare = null; - if (site.get("id").getAsLong() == site1.getId().longValue()) { - compare = site1; - } else if (site.get("id").getAsLong() == site2.getId().longValue()) { - compare = site2; - } - - if (compare == null) { - fail("Could not find matching whitelisted site id: " + site.get("id").getAsString()); - } else { - assertThat(site.get("clientId").getAsString(), equalTo(compare.getClientId())); - assertThat(site.get("creationDate").getAsString(), equalTo(formatter.print(compare.getCreationDate(), Locale.ENGLISH))); - assertThat(site.get("accessDate").getAsString(), equalTo(formatter.print(compare.getAccessDate(), Locale.ENGLISH))); - if(site.get("timeoutDate").isJsonNull()) { - assertNull(compare.getTimeoutDate()); - } else { - assertThat(site.get("timeoutDate").getAsString(), equalTo(formatter.print(compare.getTimeoutDate(), Locale.ENGLISH))); - } - assertThat(site.get("userId").getAsString(), equalTo(compare.getUserId())); - assertThat(jsonArrayToStringSet(site.getAsJsonArray("allowedScopes")), equalTo(compare.getAllowedScopes())); - checked.add(compare); - } - } - // make sure all of our clients were found - assertThat(checked.containsAll(allApprovedSites), is(true)); - } - - @Test - public void testImportGrants() throws IOException, ParseException { - - Date creationDate1 = formatter.parse("2014-09-10T22:49:44.090+00:00", Locale.ENGLISH); - Date accessDate1 = formatter.parse("2014-09-10T23:49:44.090+00:00", Locale.ENGLISH); - - OAuth2AccessTokenEntity mockToken1 = mock(OAuth2AccessTokenEntity.class); - when(mockToken1.getId()).thenReturn(1L); - - ApprovedSite site1 = new ApprovedSite(); - site1.setId(1L); - site1.setClientId("foo"); - site1.setCreationDate(creationDate1); - site1.setAccessDate(accessDate1); - site1.setUserId("user1"); - site1.setAllowedScopes(ImmutableSet.of("openid", "phone")); - when(mockToken1.getApprovedSite()).thenReturn(site1); - - Date creationDate2 = formatter.parse("2014-09-11T18:49:44.090+00:00", Locale.ENGLISH); - Date accessDate2 = formatter.parse("2014-09-11T20:49:44.090+00:00", Locale.ENGLISH); - Date timeoutDate2 = formatter.parse("2014-10-01T20:49:44.090+00:00", Locale.ENGLISH); - - ApprovedSite site2 = new ApprovedSite(); - site2.setId(2L); - site2.setClientId("bar"); - site2.setCreationDate(creationDate2); - site2.setAccessDate(accessDate2); - site2.setUserId("user2"); - site2.setAllowedScopes(ImmutableSet.of("openid", "offline_access", "email", "profile")); - site2.setTimeoutDate(timeoutDate2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [" + - - "{\"id\":1,\"clientId\":\"foo\",\"creationDate\":\"2014-09-10T22:49:44.090+00:00\",\"accessDate\":\"2014-09-10T23:49:44.090+00:00\"," - + "\"userId\":\"user1\",\"whitelistedSiteId\":null,\"allowedScopes\":[\"openid\",\"phone\"], \"whitelistedSiteId\":1," - + "\"approvedAccessTokens\":[1]}," + - "{\"id\":2,\"clientId\":\"bar\",\"creationDate\":\"2014-09-11T18:49:44.090+00:00\",\"accessDate\":\"2014-09-11T20:49:44.090+00:00\"," - + "\"timeoutDate\":\"2014-10-01T20:49:44.090+00:00\",\"userId\":\"user2\"," - + "\"allowedScopes\":[\"openid\",\"offline_access\",\"email\",\"profile\"]}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(approvedSiteRepository.save(isA(ApprovedSite.class))).thenAnswer(new Answer() { - Long id = 364L; - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - ApprovedSite _site = (ApprovedSite) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - when(approvedSiteRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public ApprovedSite answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeDb.get(_id); - } - }); - when(wlSiteRepository.getById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 432L; - @Override - public WhitelistedSite answer(InvocationOnMock invocation) throws Throwable { - WhitelistedSite _site = mock(WhitelistedSite.class); - when(_site.getId()).thenReturn(id++); - return _site; - } - }); - when(tokenRepository.getAccessTokenById(isNull(Long.class))).thenAnswer(new Answer() { - Long id = 245L; - @Override - public OAuth2AccessTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2AccessTokenEntity _token = mock(OAuth2AccessTokenEntity.class); - when(_token.getId()).thenReturn(id++); - return _token; - } - }); - - dataService.importData(reader); - //2 for sites, 1 for updating access token ref on #1 - verify(approvedSiteRepository, times(3)).save(capturedApprovedSites.capture()); - - List savedSites = new ArrayList(fakeDb.values()); - - assertThat(savedSites.size(), is(2)); - - assertThat(savedSites.get(0).getClientId(), equalTo(site1.getClientId())); - assertThat(savedSites.get(0).getAccessDate(), equalTo(site1.getAccessDate())); - assertThat(savedSites.get(0).getCreationDate(), equalTo(site1.getCreationDate())); - assertThat(savedSites.get(0).getAllowedScopes(), equalTo(site1.getAllowedScopes())); - assertThat(savedSites.get(0).getTimeoutDate(), equalTo(site1.getTimeoutDate())); - - assertThat(savedSites.get(1).getClientId(), equalTo(site2.getClientId())); - assertThat(savedSites.get(1).getAccessDate(), equalTo(site2.getAccessDate())); - assertThat(savedSites.get(1).getCreationDate(), equalTo(site2.getCreationDate())); - assertThat(savedSites.get(1).getAllowedScopes(), equalTo(site2.getAllowedScopes())); - assertThat(savedSites.get(1).getTimeoutDate(), equalTo(site2.getTimeoutDate())); - } - - @Test - public void testExportAuthenticationHolders() throws IOException { - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = new UsernamePasswordAuthenticationToken("user1", "pass1", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, null); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - List allAuthHolders = ImmutableList.of(holder1, holder2); - - when(clientRepository.getAllClients()).thenReturn(new HashSet()); - when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - when(blSiteRepository.getAll()).thenReturn(new HashSet()); - when(authHolderRepository.getAll()).thenReturn(allAuthHolders); - when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - when(sysScopeRepository.getAll()).thenReturn(new HashSet()); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - - // check our holder list (this test) - JsonArray holders = config.get(MITREidDataService.AUTHENTICATIONHOLDERS).getAsJsonArray(); - - assertThat(holders.size(), is(2)); - // check for both of our clients in turn - Set checked = new HashSet<>(); - for (JsonElement e : holders) { - assertThat(e.isJsonObject(), is(true)); - JsonObject holder = e.getAsJsonObject(); - - AuthenticationHolderEntity compare = null; - if (holder.get("id").getAsLong() == holder1.getId()) { - compare = holder1; - } else if (holder.get("id").getAsLong() == holder2.getId()) { - compare = holder2; - } - - if (compare == null) { - fail("Could not find matching authentication holder id: " + holder.get("id").getAsString()); - } else { - assertTrue(holder.get("clientId").getAsString().equals(compare.getClientId())); - assertTrue(holder.get("approved").getAsBoolean() == compare.isApproved()); - assertTrue(holder.get("redirectUri").getAsString().equals(compare.getRedirectUri())); - if (compare.getUserAuth() != null) { - assertTrue(holder.get("savedUserAuthentication").isJsonObject()); - JsonObject savedAuth = holder.get("savedUserAuthentication").getAsJsonObject(); - assertTrue(savedAuth.get("name").getAsString().equals(compare.getUserAuth().getName())); - assertTrue(savedAuth.get("authenticated").getAsBoolean() == compare.getUserAuth().isAuthenticated()); - assertTrue(savedAuth.get("sourceClass").getAsString().equals(compare.getUserAuth().getSourceClass())); - } - checked.add(compare); - } - } - // make sure all of our clients were found - assertThat(checked.containsAll(allAuthHolders), is(true)); - } - - @Test - public void testImportAuthenticationHolders() throws IOException { - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"," - + "\"savedUserAuthentication\":null}," + - "{\"id\":2,\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"," - + "\"savedUserAuthentication\":null}" + - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - final Map fakeDb = new HashMap<>(); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 243L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _site = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_site.getId() == null) { - _site.setId(id++); - } - fakeDb.put(_site.getId(), _site); - return _site; - } - }); - - dataService.importData(reader); - verify(authHolderRepository, times(2)).save(capturedAuthHolders.capture()); - - List savedAuthHolders = capturedAuthHolders.getAllValues(); - - assertThat(savedAuthHolders.size(), is(2)); - assertThat(savedAuthHolders.get(0).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder1.getAuthentication().getOAuth2Request().getClientId())); - assertThat(savedAuthHolders.get(1).getAuthentication().getOAuth2Request().getClientId(), equalTo(holder2.getAuthentication().getOAuth2Request().getClientId())); - } - - @Test - public void testExportSystemScopes() throws IOException { - SystemScope scope1 = new SystemScope(); - scope1.setId(1L); - scope1.setValue("scope1"); - scope1.setDescription("Scope 1"); - scope1.setRestricted(true); - scope1.setDefaultScope(false); - scope1.setIcon("glass"); - - SystemScope scope2 = new SystemScope(); - scope2.setId(2L); - scope2.setValue("scope2"); - scope2.setDescription("Scope 2"); - scope2.setRestricted(false); - scope2.setDefaultScope(false); - scope2.setIcon("ball"); - - SystemScope scope3 = new SystemScope(); - scope3.setId(3L); - scope3.setValue("scope3"); - scope3.setDescription("Scope 3"); - scope3.setRestricted(false); - scope3.setDefaultScope(true); - scope3.setIcon("road"); - - Set allScopes = ImmutableSet.of(scope1, scope2, scope3); - - Mockito.when(clientRepository.getAllClients()).thenReturn(new HashSet()); - Mockito.when(approvedSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(wlSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(blSiteRepository.getAll()).thenReturn(new HashSet()); - Mockito.when(authHolderRepository.getAll()).thenReturn(new ArrayList()); - Mockito.when(tokenRepository.getAllAccessTokens()).thenReturn(new HashSet()); - Mockito.when(tokenRepository.getAllRefreshTokens()).thenReturn(new HashSet()); - Mockito.when(sysScopeRepository.getAll()).thenReturn(allScopes); - - // do the data export - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - dataService.exportData(writer); - writer.endObject(); - writer.close(); - - // parse the output as a JSON object for testing - JsonElement elem = new JsonParser().parse(stringWriter.toString()); - JsonObject root = elem.getAsJsonObject(); - - // make sure the root is there - assertThat(root.has(MITREidDataService.MITREID_CONNECT_1_3), is(true)); - - JsonObject config = root.get(MITREidDataService.MITREID_CONNECT_1_3).getAsJsonObject(); - - // make sure all the root elements are there - assertThat(config.has(MITREidDataService.CLIENTS), is(true)); - assertThat(config.has(MITREidDataService.GRANTS), is(true)); - assertThat(config.has(MITREidDataService.WHITELISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.BLACKLISTEDSITES), is(true)); - assertThat(config.has(MITREidDataService.REFRESHTOKENS), is(true)); - assertThat(config.has(MITREidDataService.ACCESSTOKENS), is(true)); - assertThat(config.has(MITREidDataService.SYSTEMSCOPES), is(true)); - assertThat(config.has(MITREidDataService.AUTHENTICATIONHOLDERS), is(true)); - - // make sure the root elements are all arrays - assertThat(config.get(MITREidDataService.CLIENTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.GRANTS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.WHITELISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.BLACKLISTEDSITES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.REFRESHTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.ACCESSTOKENS).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.SYSTEMSCOPES).isJsonArray(), is(true)); - assertThat(config.get(MITREidDataService.AUTHENTICATIONHOLDERS).isJsonArray(), is(true)); - - - // check our scope list (this test) - JsonArray scopes = config.get(MITREidDataService.SYSTEMSCOPES).getAsJsonArray(); - - assertThat(scopes.size(), is(3)); - // check for both of our clients in turn - Set checked = new HashSet<>(); - for (JsonElement e : scopes) { - assertThat(e.isJsonObject(), is(true)); - JsonObject scope = e.getAsJsonObject(); - - SystemScope compare = null; - if (scope.get("value").getAsString().equals(scope1.getValue())) { - compare = scope1; - } else if (scope.get("value").getAsString().equals(scope2.getValue())) { - compare = scope2; - } else if (scope.get("value").getAsString().equals(scope3.getValue())) { - compare = scope3; - } - - if (compare == null) { - fail("Could not find matching scope value: " + scope.get("value").getAsString()); - } else { - assertThat(scope.get("value").getAsString(), equalTo(compare.getValue())); - assertThat(scope.get("description").getAsString(), equalTo(compare.getDescription())); - assertThat(scope.get("icon").getAsString(), equalTo(compare.getIcon())); - assertThat(scope.get("restricted").getAsBoolean(), equalTo(compare.isRestricted())); - assertThat(scope.get("defaultScope").getAsBoolean(), equalTo(compare.isDefaultScope())); - checked.add(compare); - } - } - // make sure all of our clients were found - assertThat(checked.containsAll(allScopes), is(true)); - - } - - @Test - public void testImportSystemScopes() throws IOException { - SystemScope scope1 = new SystemScope(); - scope1.setId(1L); - scope1.setValue("scope1"); - scope1.setDescription("Scope 1"); - scope1.setRestricted(true); - scope1.setDefaultScope(false); - scope1.setIcon("glass"); - - SystemScope scope2 = new SystemScope(); - scope2.setId(2L); - scope2.setValue("scope2"); - scope2.setDescription("Scope 2"); - scope2.setRestricted(false); - scope2.setDefaultScope(false); - scope2.setIcon("ball"); - - SystemScope scope3 = new SystemScope(); - scope3.setId(3L); - scope3.setValue("scope3"); - scope3.setDescription("Scope 3"); - scope3.setRestricted(false); - scope3.setDefaultScope(true); - scope3.setIcon("road"); - - String configJson = "{" + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [], " + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [" + - - "{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"restricted\":true,\"defaultScope\":false}," + - "{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"restricted\":false,\"defaultScope\":false}," + - "{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"restricted\":false,\"defaultScope\":true}" + - - " ]" + - "}"; - - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - - dataService.importData(reader); - verify(sysScopeRepository, times(3)).save(capturedScope.capture()); - - List savedScopes = capturedScope.getAllValues(); - - assertThat(savedScopes.size(), is(3)); - assertThat(savedScopes.get(0).getValue(), equalTo(scope1.getValue())); - assertThat(savedScopes.get(0).getDescription(), equalTo(scope1.getDescription())); - assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon())); - assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope())); - assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted())); - - assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue())); - assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription())); - assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon())); - assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope())); - assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted())); - - assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue())); - assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription())); - assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon())); - assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope())); - assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted())); - - } - - @Test - public void testFixRefreshTokenAuthHolderReferencesOnImport() throws IOException, ParseException { - - String expiration1 = "2014-09-10T22:49:44.090+00:00"; - Date expirationDate1 = formatter.parse(expiration1, Locale.ENGLISH); - - ClientDetailsEntity mockedClient1 = mock(ClientDetailsEntity.class); - when(mockedClient1.getClientId()).thenReturn("mocked_client_1"); - - OAuth2Request req1 = new OAuth2Request(new HashMap(), "client1", new ArrayList(), - true, new HashSet(), new HashSet(), "http://foo.com", - new HashSet(), null); - Authentication mockAuth1 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth1 = new OAuth2Authentication(req1, mockAuth1); - - AuthenticationHolderEntity holder1 = new AuthenticationHolderEntity(); - holder1.setId(1L); - holder1.setAuthentication(auth1); - - OAuth2RefreshTokenEntity token1 = new OAuth2RefreshTokenEntity(); - token1.setId(1L); - token1.setClient(mockedClient1); - token1.setExpiration(expirationDate1); - token1.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.")); - token1.setAuthenticationHolder(holder1); - - String expiration2 = "2015-01-07T18:31:50.079+00:00"; - Date expirationDate2 = formatter.parse(expiration2, Locale.ENGLISH); - - ClientDetailsEntity mockedClient2 = mock(ClientDetailsEntity.class); - when(mockedClient2.getClientId()).thenReturn("mocked_client_2"); - - OAuth2Request req2 = new OAuth2Request(new HashMap(), "client2", new ArrayList(), - true, new HashSet(), new HashSet(), "http://bar.com", - new HashSet(), null); - Authentication mockAuth2 = mock(Authentication.class, withSettings().serializable()); - OAuth2Authentication auth2 = new OAuth2Authentication(req2, mockAuth2); - - AuthenticationHolderEntity holder2 = new AuthenticationHolderEntity(); - holder2.setId(2L); - holder2.setAuthentication(auth2); - - OAuth2RefreshTokenEntity token2 = new OAuth2RefreshTokenEntity(); - token2.setId(2L); - token2.setClient(mockedClient2); - token2.setExpiration(expirationDate2); - token2.setJwt(JWTParser.parse("eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.")); - token2.setAuthenticationHolder(holder2); - - String configJson = "{" + - "\"" + MITREidDataService.SYSTEMSCOPES + "\": [], " + - "\"" + MITREidDataService.ACCESSTOKENS + "\": [], " + - "\"" + MITREidDataService.CLIENTS + "\": [], " + - "\"" + MITREidDataService.GRANTS + "\": [], " + - "\"" + MITREidDataService.WHITELISTEDSITES + "\": [], " + - "\"" + MITREidDataService.BLACKLISTEDSITES + "\": [], " + - "\"" + MITREidDataService.AUTHENTICATIONHOLDERS + "\": [" + - - "{\"id\":1,\"authentication\":{\"authorizationRequest\":{\"clientId\":\"client1\",\"redirectUri\":\"http://foo.com\"}," - + "\"userAuthentication\":null}}," + - "{\"id\":2,\"authentication\":{\"authorizationRequest\":{\"clientId\":\"client2\",\"redirectUri\":\"http://bar.com\"}," - + "\"userAuthentication\":null}}" + - " ]," + - "\"" + MITREidDataService.REFRESHTOKENS + "\": [" + - - "{\"id\":1,\"clientId\":\"mocked_client_1\",\"expiration\":\"2014-09-10T22:49:44.090+00:00\"," - + "\"authenticationHolderId\":1,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJmOTg4OWQyOS0xMTk1LTQ4ODEtODgwZC1lZjVlYzAwY2Y4NDIifQ.\"}," + - "{\"id\":2,\"clientId\":\"mocked_client_2\",\"expiration\":\"2015-01-07T18:31:50.079+00:00\"," - + "\"authenticationHolderId\":2,\"value\":\"eyJhbGciOiJub25lIn0.eyJqdGkiOiJlYmEyYjc3My0xNjAzLTRmNDAtOWQ3MS1hMGIxZDg1OWE2MDAifQ.\"}" + - - " ]" + - "}"; - logger.debug(configJson); - - JsonReader reader = new JsonReader(new StringReader(configJson)); - final Map fakeRefreshTokenTable = new HashMap<>(); - final Map fakeAuthHolderTable = new HashMap<>(); - when(tokenRepository.saveRefreshToken(isA(OAuth2RefreshTokenEntity.class))).thenAnswer(new Answer() { - Long id = 343L; - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - OAuth2RefreshTokenEntity _token = (OAuth2RefreshTokenEntity) invocation.getArguments()[0]; - if(_token.getId() == null) { - _token.setId(id++); - } - fakeRefreshTokenTable.put(_token.getId(), _token); - return _token; - } - }); - when(tokenRepository.getRefreshTokenById(anyLong())).thenAnswer(new Answer() { - @Override - public OAuth2RefreshTokenEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeRefreshTokenTable.get(_id); - } - }); - when(clientRepository.getClientByClientId(anyString())).thenAnswer(new Answer() { - @Override - public ClientDetailsEntity answer(InvocationOnMock invocation) throws Throwable { - String _clientId = (String) invocation.getArguments()[0]; - ClientDetailsEntity _client = mock(ClientDetailsEntity.class); - when(_client.getClientId()).thenReturn(_clientId); - return _client; - } - }); - when(authHolderRepository.save(isA(AuthenticationHolderEntity.class))).thenAnswer(new Answer() { - Long id = 356L; - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - AuthenticationHolderEntity _holder = (AuthenticationHolderEntity) invocation.getArguments()[0]; - if(_holder.getId() == null) { - _holder.setId(id++); - } - fakeAuthHolderTable.put(_holder.getId(), _holder); - return _holder; - } - }); - when(authHolderRepository.getById(anyLong())).thenAnswer(new Answer() { - @Override - public AuthenticationHolderEntity answer(InvocationOnMock invocation) throws Throwable { - Long _id = (Long) invocation.getArguments()[0]; - return fakeAuthHolderTable.get(_id); - } - }); - dataService.importData(reader); - - List savedRefreshTokens = new ArrayList(fakeRefreshTokenTable.values()); //capturedRefreshTokens.getAllValues(); - Collections.sort(savedRefreshTokens, new refreshTokenIdComparator()); - - assertThat(savedRefreshTokens.get(0).getAuthenticationHolder().getId(), equalTo(356L)); - assertThat(savedRefreshTokens.get(1).getAuthenticationHolder().getId(), equalTo(357L)); - } - - private Set jsonArrayToStringSet(JsonArray a) { - Set s = new HashSet<>(); - for (JsonElement jsonElement : a) { - s.add(jsonElement.getAsString()); - } - return s; - } - -} diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/token/TestConnectTokenEnhancer.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/token/TestConnectTokenEnhancer.java deleted file mode 100644 index 7e1acbfd99..0000000000 --- a/openid-connect-server/src/test/java/org/mitre/openid/connect/token/TestConnectTokenEnhancer.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * Portions copyright 2011-2013 The MITRE Corporation - * - * 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.mitre.openid.connect.token; - -import java.text.ParseException; - -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.OIDCTokenService; -import org.mitre.openid.connect.service.UserInfoService; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.OAuth2Request; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; - -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet.Builder; - -@RunWith(MockitoJUnitRunner.class) -public class TestConnectTokenEnhancer { - - private static final String CLIENT_ID = "client"; - private static final String KEY_ID = "key"; - - private ConfigurationPropertiesBean configBean = new ConfigurationPropertiesBean(); - - @Mock - private JWTSigningAndValidationService jwtService; - - @Mock - private ClientDetailsEntityService clientService; - - @Mock - private UserInfoService userInfoService; - - @Mock - private OIDCTokenService connectTokenService; - - @Mock - private OAuth2Authentication authentication; - - private OAuth2Request request = new OAuth2Request(CLIENT_ID) { }; - - @InjectMocks - private ConnectTokenEnhancer enhancer = new ConnectTokenEnhancer(); - - @Before - public void prepare() { - configBean.setIssuer("https://auth.example.org/"); - enhancer.setConfigBean(configBean); - - ClientDetailsEntity client = new ClientDetailsEntity(); - client.setClientId(CLIENT_ID); - Mockito.when(clientService.loadClientByClientId(Mockito.anyString())).thenReturn(client); - Mockito.when(authentication.getOAuth2Request()).thenReturn(request); - Mockito.when(jwtService.getDefaultSigningAlgorithm()).thenReturn(JWSAlgorithm.RS256); - Mockito.when(jwtService.getDefaultSignerKeyId()).thenReturn(KEY_ID); - } - - @Test - public void invokesCustomClaimsHook() throws ParseException { - configure(enhancer = new ConnectTokenEnhancer() { - @Override - protected void addCustomAccessTokenClaims(Builder builder, OAuth2AccessTokenEntity token, - OAuth2Authentication authentication) { - builder.claim("test", "foo"); - } - }); - - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - - OAuth2AccessTokenEntity enhanced = (OAuth2AccessTokenEntity) enhancer.enhance(token, authentication); - Assert.assertEquals("foo", enhanced.getJwt().getJWTClaimsSet().getClaim("test")); - } - - private void configure(ConnectTokenEnhancer e) { - e.setConfigBean(configBean); - e.setJwtService(jwtService); - e.setClientService(clientService); - } -} diff --git a/pom.xml b/pom.xml index 0bedc701f1..ce2c083d89 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.mitre openid-connect-parent - 2.0.0.cnaf-20260603 + 2.1.0.cnaf-20260701 MITREid Connect pom diff --git a/uma-server-webapp/pom.xml b/uma-server-webapp/pom.xml deleted file mode 100644 index a1db8a2739..0000000000 --- a/uma-server-webapp/pom.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - 4.0.0 - - org.mitre - openid-connect-parent - 1.3.5-SNAPSHOT - .. - - uma-server-webapp - war - UMA Server Webapp - Deployable package of the User Managed Access (UMA) server extension to MITREid Connect - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java-version} - ${java-version} - - - - org.appfuse.plugins - warpath-maven-plugin - true - - - - add-classes - - - - - - org.apache.maven.plugins - maven-war-plugin - - uma-server-webapp - - - org.mitre - openid-connect-server-webapp - - - false - - - - org.eclipse.jetty - jetty-maven-plugin - - ${project.build.directory}/uma-server-webapp.war - - /uma-server-webapp - - - - - - - - org.mitre - openid-connect-server-webapp - war - - - org.mitre - openid-connect-server-webapp - warpath - - - org.mitre - uma-server - - - org.mitre - openid-connect-client - - - diff --git a/uma-server-webapp/pom.xml.versionsBackup b/uma-server-webapp/pom.xml.versionsBackup deleted file mode 100644 index 436fafedd3..0000000000 --- a/uma-server-webapp/pom.xml.versionsBackup +++ /dev/null @@ -1,121 +0,0 @@ - - - - 4.0.0 - - org.mitre - openid-connect-parent - 1.2.7-SNAPSHOT - .. - - uma-server-webapp - war - UMA Server Webapp - Deployable package of the User Managed Access (UMA) server extension to MITREid Connect - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java-version} - ${java-version} - - - - org.appfuse.plugins - warpath-maven-plugin - true - - - - add-classes - - - - - - org.apache.maven.plugins - maven-war-plugin - - - - org.mitre - openid-connect-server-webapp - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.appfuse.plugins - - - warpath-maven-plugin - - - [3.5.0,) - - - add-classes - - - - - - - - - - - - - - - - org.mitre - openid-connect-server-webapp - war - - - org.mitre - openid-connect-server-webapp - warpath - - - org.mitre - uma-server - - - org.mitre - openid-connect-client - - - diff --git a/uma-server-webapp/src/main/resources/db/hsql/clients.sql b/uma-server-webapp/src/main/resources/db/hsql/clients.sql deleted file mode 100755 index 8d41bcad94..0000000000 --- a/uma-server-webapp/src/main/resources/db/hsql/clients.sql +++ /dev/null @@ -1,77 +0,0 @@ --- --- Turn off autocommit and start a transaction so that we can use the temp tables --- - -SET AUTOCOMMIT FALSE; - -START TRANSACTION; - --- --- Insert client information into the temporary tables. To add clients to the HSQL database, edit things here. --- - -INSERT INTO client_details_TEMP (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES - ('client', 'secret', 'Test Client', false, null, 3600, 600, true), - ('rs', 'secret', 'Test UMA RS', false, null, null, 600, false), - ('c', 'secret', 'Test UMA Client', false, null, null, 600, false); - -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES - ('client', 'openid'), - ('client', 'profile'), - ('client', 'email'), - ('client', 'address'), - ('client', 'phone'), - ('client', 'offline_access'), - ('rs', 'uma_protection'), - ('c', 'uma_authorization'); - -INSERT INTO client_redirect_uri_TEMP (owner_id, redirect_uri) VALUES - ('client', 'http://localhost/'), - ('client', 'http://localhost:8080/'); - -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES - ('client', 'authorization_code'), - ('client', 'urn:ietf:params:oauth:grant_type:redelegate'), - ('client', 'implicit'), - ('client', 'refresh_token'), - ('rs', 'authorization_code'), - ('rs', 'implicit'), - ('c', 'authorization_code'), - ('c', 'implicit'); - --- --- Merge the temporary clients safely into the database. This is a two-step process to keep clients from being created on every startup with a persistent store. --- - -MERGE INTO client_details - USING (SELECT client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection FROM client_details_TEMP) AS vals(client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) - ON vals.client_id = client_details.client_id - WHEN NOT MATCHED THEN - INSERT (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES(client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection); - -MERGE INTO client_scope - USING (SELECT id, scope FROM client_scope_TEMP, client_details WHERE client_details.client_id = client_scope_TEMP.owner_id) AS vals(id, scope) - ON vals.id = client_scope.owner_id AND vals.scope = client_scope.scope - WHEN NOT MATCHED THEN - INSERT (owner_id, scope) values (vals.id, vals.scope); - -MERGE INTO client_redirect_uri - USING (SELECT id, redirect_uri FROM client_redirect_uri_TEMP, client_details WHERE client_details.client_id = client_redirect_uri_TEMP.owner_id) AS vals(id, redirect_uri) - ON vals.id = client_redirect_uri.owner_id AND vals.redirect_uri = client_redirect_uri.redirect_uri - WHEN NOT MATCHED THEN - INSERT (owner_id, redirect_uri) values (vals.id, vals.redirect_uri); - -MERGE INTO client_grant_type - USING (SELECT id, grant_type FROM client_grant_type_TEMP, client_details WHERE client_details.client_id = client_grant_type_TEMP.owner_id) AS vals(id, grant_type) - ON vals.id = client_grant_type.owner_id AND vals.grant_type = client_grant_type.grant_type - WHEN NOT MATCHED THEN - INSERT (owner_id, grant_type) values (vals.id, vals.grant_type); - --- --- Close the transaction and turn autocommit back on --- - -COMMIT; - -SET AUTOCOMMIT TRUE; - diff --git a/uma-server-webapp/src/main/resources/db/hsql/scopes.sql b/uma-server-webapp/src/main/resources/db/hsql/scopes.sql deleted file mode 100755 index c3ea0b1133..0000000000 --- a/uma-server-webapp/src/main/resources/db/hsql/scopes.sql +++ /dev/null @@ -1,35 +0,0 @@ --- --- Turn off autocommit and start a transaction so that we can use the temp tables --- - -SET AUTOCOMMIT FALSE; - -START TRANSACTION; - --- --- Insert scope information into the temporary tables. --- - -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope) VALUES - ('openid', 'log in using your identity', 'user', false, true), - ('profile', 'basic profile information', 'list-alt', false, true), - ('email', 'email address', 'envelope', false, true), - ('address', 'physical address', 'home', false, true), - ('phone', 'telephone number', 'bell', false, true), - ('offline_access', 'offline access', 'time', false, false), - ('uma_protection', 'manage protected resources', 'briefcase', false, false), - ('uma_authorization', 'request access to protected resources', 'share', false, false); - --- --- Merge the temporary scopes safely into the database. This is a two-step process to keep scopes from being created on every startup with a persistent store. --- - -MERGE INTO system_scope - USING (SELECT scope, description, icon, restricted, default_scope FROM system_scope_TEMP) AS vals(scope, description, icon, restricted, default_scope) - ON vals.scope = system_scope.scope - WHEN NOT MATCHED THEN - INSERT (scope, description, icon, restricted, default_scope) VALUES(vals.scope, vals.description, vals.icon, vals.restricted, vals.default_scope); - -COMMIT; - -SET AUTOCOMMIT TRUE; diff --git a/uma-server-webapp/src/main/resources/db/mysql/clients.sql b/uma-server-webapp/src/main/resources/db/mysql/clients.sql deleted file mode 100755 index 02444c4732..0000000000 --- a/uma-server-webapp/src/main/resources/db/mysql/clients.sql +++ /dev/null @@ -1,69 +0,0 @@ --- --- Turn off autocommit and start a transaction so that we can use the temp tables --- - -SET AUTOCOMMIT = 0; - -START TRANSACTION; - --- --- Insert client information into the temporary tables. To add clients to the HSQL database, edit things here. --- - -INSERT INTO client_details_TEMP (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES - ('client', 'secret', 'Test Client', false, null, 3600, 600, true), - ('rs', 'secret', 'Test UMA RS', false, null, null, 600, false), - ('c', 'secret', 'Test UMA Client', false, null, null, 600, false); - -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES - ('client', 'openid'), - ('client', 'profile'), - ('client', 'email'), - ('client', 'address'), - ('client', 'phone'), - ('client', 'offline_access'), - ('rs', 'uma_protection'), - ('c', 'uma_authorization'); - -INSERT INTO client_redirect_uri_TEMP (owner_id, redirect_uri) VALUES - ('client', 'http://localhost/'), - ('client', 'http://localhost:8080/'); - -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES - ('client', 'authorization_code'), - ('client', 'urn:ietf:params:oauth:grant_type:redelegate'), - ('client', 'implicit'), - ('client', 'refresh_token'), - ('rs', 'authorization_code'), - ('rs', 'implicit'), - ('c', 'authorization_code'), - ('c', 'implicit'); - --- --- Merge the temporary clients safely into the database. This is a two-step process to keep clients from being created on every startup with a persistent store. --- - -INSERT INTO client_details (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) - SELECT client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection FROM client_details_TEMP - ON DUPLICATE KEY UPDATE client_details.client_id = client_details.client_id; - -INSERT INTO client_scope (owner_id, scope) - SELECT id, scope FROM client_scope_TEMP, client_details WHERE client_details.client_id = client_scope_TEMP.owner_id - ON DUPLICATE KEY UPDATE client_scope.owner_id = client_scope.owner_id; - -INSERT INTO client_redirect_uri (owner_id, redirect_uri) - SELECT id, redirect_uri FROM client_redirect_uri_TEMP, client_details WHERE client_details.client_id = client_redirect_uri_TEMP.owner_id - ON DUPLICATE KEY UPDATE client_redirect_uri.owner_id = client_redirect_uri.owner_id; - -INSERT INTO client_grant_type (owner_id, grant_type) - SELECT id, grant_type FROM client_grant_type_TEMP, client_details WHERE client_details.client_id = client_grant_type_TEMP.owner_id - ON DUPLICATE KEY UPDATE client_grant_type.owner_id = client_grant_type.owner_id; - --- --- Close the transaction and turn autocommit back on --- - -COMMIT; - -SET AUTOCOMMIT = 1; - diff --git a/uma-server-webapp/src/main/resources/db/mysql/scopes.sql b/uma-server-webapp/src/main/resources/db/mysql/scopes.sql deleted file mode 100755 index bdcc0f6e30..0000000000 --- a/uma-server-webapp/src/main/resources/db/mysql/scopes.sql +++ /dev/null @@ -1,33 +0,0 @@ --- --- Turn off autocommit and start a transaction so that we can use the temp tables --- - -SET AUTOCOMMIT = 0; - -START TRANSACTION; - --- --- Insert scope information into the temporary tables. --- - -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('openid', 'log in using your identity', 'user', false, true, false, null), - ('profile', 'basic profile information', 'list-alt', false, true, false, null), - ('email', 'email address', 'envelope', false, true, false, null), - ('address', 'physical address', 'home', false, true, false, null), - ('phone', 'telephone number', 'bell', false, true, false, null), - ('offline_access', 'offline access', 'time', false, false, false, null), - ('uma_protection', 'manage protected resources', 'briefcase', false, false, false, null), - ('uma_authorization', 'request access to protected resources', 'share', false, false, false, null); - --- --- Merge the temporary scopes safely into the database. This is a two-step process to keep scopes from being created on every startup with a persistent store. --- - -INSERT INTO system_scope (scope, description, icon, restricted, default_scope, structured, structured_param_description) - SELECT scope, description, icon, restricted, default_scope, structured, structured_param_description FROM system_scope_TEMP - ON DUPLICATE KEY UPDATE system_scope.scope = system_scope.scope; - -COMMIT; - -SET AUTOCOMMIT = 1; diff --git a/uma-server-webapp/src/main/resources/db/oracle/clients_oracle.sql b/uma-server-webapp/src/main/resources/db/oracle/clients_oracle.sql deleted file mode 100755 index 783ff2d3a4..0000000000 --- a/uma-server-webapp/src/main/resources/db/oracle/clients_oracle.sql +++ /dev/null @@ -1,61 +0,0 @@ --- --- Insert client information into the temporary tables. To add clients to the Oracle database, edit things here. --- - -INSERT INTO client_details_TEMP (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES - ('client', 'secret', 'Test Client', 0, null, 3600, 600, 1); -INSERT INTO client_details_TEMP (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES - ('rs', 'secret', 'Test UMA RS', false, null, null, 600, false); -INSERT INTO client_details_TEMP (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES - ('c', 'secret', 'Test UMA Client', false, null, null, 600, false); - -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('client', 'openid'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('client', 'profile'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('client', 'email'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('client', 'address'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('client', 'phone'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('client', 'offline_access'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('rs', 'uma_protection'); -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES ('c', 'uma_authorization'); - -INSERT INTO client_redirect_uri_TEMP (owner_id, redirect_uri) VALUES ('client', 'http://localhost/'); -INSERT INTO client_redirect_uri_TEMP (owner_id, redirect_uri) VALUES ('client', 'http://localhost:8080/'); - -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('client', 'authorization_code'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('client', 'urn:ietf:params:oauth:grant_type:redelegate'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('client', 'implicit'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('client', 'refresh_token'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('rs', 'authorization_code'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('rs', 'implicit'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('c', 'authorization_code'); -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES ('c', 'implicit'); - --- --- Merge the temporary clients safely into the database. This is a two-step process to keep clients from being created on every startup with a persistent store. --- - -MERGE INTO client_details - USING (SELECT client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection FROM client_details_TEMP) vals - ON (vals.client_id = client_details.client_id) - WHEN NOT MATCHED THEN - INSERT (id, client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, - id_token_validity_seconds, allow_introspection) VALUES(client_details_seq.nextval, vals.client_id, vals.client_secret, vals.client_name, vals.dynamically_registered, - vals.refresh_token_validity_seconds, vals.access_token_validity_seconds, vals.id_token_validity_seconds, vals.allow_introspection); - -MERGE INTO client_scope - USING (SELECT id, scope FROM client_scope_TEMP, client_details WHERE client_details.client_id = client_scope_TEMP.owner_id) vals - ON (vals.id = client_scope.owner_id AND vals.scope = client_scope.scope) - WHEN NOT MATCHED THEN - INSERT (owner_id, scope) values (vals.id, vals.scope); - -MERGE INTO client_redirect_uri - USING (SELECT id, redirect_uri FROM client_redirect_uri_TEMP, client_details WHERE client_details.client_id = client_redirect_uri_TEMP.owner_id) vals - ON (vals.id = client_redirect_uri.owner_id AND vals.redirect_uri = client_redirect_uri.redirect_uri) - WHEN NOT MATCHED THEN - INSERT (owner_id, redirect_uri) values (vals.id, vals.redirect_uri); - -MERGE INTO client_grant_type - USING (SELECT id, grant_type FROM client_grant_type_TEMP, client_details WHERE client_details.client_id = client_grant_type_TEMP.owner_id) vals - ON (vals.id = client_grant_type.owner_id AND vals.grant_type = client_grant_type.grant_type) - WHEN NOT MATCHED THEN - INSERT (owner_id, grant_type) values (vals.id, vals.grant_type); diff --git a/uma-server-webapp/src/main/resources/db/oracle/scopes_oracle.sql b/uma-server-webapp/src/main/resources/db/oracle/scopes_oracle.sql deleted file mode 100755 index a52e021dea..0000000000 --- a/uma-server-webapp/src/main/resources/db/oracle/scopes_oracle.sql +++ /dev/null @@ -1,31 +0,0 @@ --- --- Insert scope information into the temporary tables. --- - -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('openid', 'log in using your identity', 'user', 0, 1, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('profile', 'basic profile information', 'list-alt', 0, 1, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('email', 'email address', 'envelope', 0, 1, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('address', 'physical address', 'home', 0, 1, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('phone', 'telephone number', 'bell', 0, 1, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('offline_access', 'offline access', 'time', 0, 0, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('uma_protection', 'manage protected resources', 'briefcase', 0, 0, 0, null); -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('uma_authorization', 'request access to protected resources', 'share', 0, 0, 0, null); - --- --- Merge the temporary scopes safely into the database. This is a two-step process to keep scopes from being created on every startup with a persistent store. --- - -MERGE INTO system_scope - USING (SELECT scope, description, icon, restricted, default_scope, structured, structured_param_description FROM system_scope_TEMP) vals - ON (vals.scope = system_scope.scope) - WHEN NOT MATCHED THEN - INSERT (id, scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES(system_scope_seq.nextval, vals.scope, - vals.description, vals.icon, vals.restricted, vals.default_scope, vals.structured, vals.structured_param_description); diff --git a/uma-server-webapp/src/main/resources/db/psql/clients.sql b/uma-server-webapp/src/main/resources/db/psql/clients.sql deleted file mode 100755 index d4c75e7fe6..0000000000 --- a/uma-server-webapp/src/main/resources/db/psql/clients.sql +++ /dev/null @@ -1,74 +0,0 @@ --- --- Turn off autocommit and start a transaction so that we can use the temp tables --- - ---SET AUTOCOMMIT = OFF; - -START TRANSACTION; - --- --- Insert client information into the temporary tables. To add clients to the HSQL database, edit things here. --- - -INSERT INTO client_details_TEMP (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) VALUES - ('client', 'secret', 'Test Client', false, null, 3600, 600, true), - ('rs', 'secret', 'Test UMA RS', false, null, null, 600, false), - ('c', 'secret', 'Test UMA Client', false, null, null, 600, false); - -INSERT INTO client_scope_TEMP (owner_id, scope) VALUES - ('client', 'openid'), - ('client', 'profile'), - ('client', 'email'), - ('client', 'address'), - ('client', 'phone'), - ('client', 'offline_access'), - ('rs', 'uma_protection'), - ('c', 'uma_authorization'); - -INSERT INTO client_redirect_uri_TEMP (owner_id, redirect_uri) VALUES - ('client', 'http://localhost/'), - ('client', 'http://localhost:8080/'); - -INSERT INTO client_grant_type_TEMP (owner_id, grant_type) VALUES - ('client', 'authorization_code'), - ('client', 'urn:ietf:params:oauth:grant_type:redelegate'), - ('client', 'implicit'), - ('client', 'refresh_token'), - ('rs', 'authorization_code'), - ('rs', 'implicit'), - ('c', 'authorization_code'), - ('c', 'implicit'); - --- --- Merge the temporary clients safely into the database. This is a two-step process to keep clients from being created on every startup with a persistent store. --- - -INSERT INTO client_details (client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection) - SELECT client_id, client_secret, client_name, dynamically_registered, refresh_token_validity_seconds, access_token_validity_seconds, id_token_validity_seconds, allow_introspection FROM client_details_TEMP - ON CONFLICT - DO NOTHING; - -INSERT INTO client_scope (scope) - SELECT scope FROM client_scope_TEMP, client_details WHERE client_details.client_id = client_scope_TEMP.owner_id - ON CONFLICT - DO NOTHING; - -INSERT INTO client_redirect_uri (redirect_uri) - SELECT redirect_uri FROM client_redirect_uri_TEMP, client_details WHERE client_details.client_id = client_redirect_uri_TEMP.owner_id - ON CONFLICT - DO NOTHING; - -INSERT INTO client_grant_type (grant_type) - SELECT grant_type FROM client_grant_type_TEMP, client_details WHERE client_details.client_id = client_grant_type_TEMP.owner_id - ON CONFLICT - DO NOTHING; - --- --- Close the transaction and turn autocommit back on --- - -COMMIT; - ---SET AUTOCOMMIT = ON; - - diff --git a/uma-server-webapp/src/main/resources/db/psql/scopes.sql b/uma-server-webapp/src/main/resources/db/psql/scopes.sql deleted file mode 100755 index 8b2611b832..0000000000 --- a/uma-server-webapp/src/main/resources/db/psql/scopes.sql +++ /dev/null @@ -1,33 +0,0 @@ --- --- Turn off autocommit and start a transaction so that we can use the temp tables --- - ---SET AUTOCOMMIT = OFF; - -START TRANSACTION; - --- --- Insert scope information into the temporary tables. --- - -INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES - ('openid', 'log in using your identity', 'user', false, true, false, null), - ('profile', 'basic profile information', 'list-alt', false, true, false, null), - ('email', 'email address', 'envelope', false, true, false, null), - ('address', 'physical address', 'home', false, true, false, null), - ('phone', 'telephone number', 'bell', false, true, false, null), - ('offline_access', 'offline access', 'time', false, false, false, null); - --- --- Merge the temporary scopes safely into the database. This is a two-step process to keep scopes from being created on every startup with a persistent store. --- - -INSERT INTO system_scope (scope, description, icon, restricted, default_scope, structured, structured_param_description) - SELECT scope, description, icon, restricted, default_scope, structured, structured_param_description FROM system_scope_TEMP - ON CONFLICT(scope) - DO NOTHING; - -COMMIT; - ---SET AUTOCOMMIT = ON; - diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/endpoint-config.xml b/uma-server-webapp/src/main/webapp/WEB-INF/endpoint-config.xml deleted file mode 100644 index 7c645d23a8..0000000000 --- a/uma-server-webapp/src/main/webapp/WEB-INF/endpoint-config.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/server-config.xml b/uma-server-webapp/src/main/webapp/WEB-INF/server-config.xml deleted file mode 100644 index 92685552c6..0000000000 --- a/uma-server-webapp/src/main/webapp/WEB-INF/server-config.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - uma - messages - - - - - - - - - - - - diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/tags/actionmenu.tag b/uma-server-webapp/src/main/webapp/WEB-INF/tags/actionmenu.tag deleted file mode 100644 index 47df4a3615..0000000000 --- a/uma-server-webapp/src/main/webapp/WEB-INF/tags/actionmenu.tag +++ /dev/null @@ -1,21 +0,0 @@ -<%@ tag language="java" pageEncoding="UTF-8"%> -<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> -<%@ taglib prefix="security" - uri="http://www.springframework.org/security/tags"%> - - -
  • -
  • -
  • -
  • -
  • -
    - -
  • -
  • -
  • -
  • -
  • - -
  • -
  • \ No newline at end of file diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/ui-config.xml b/uma-server-webapp/src/main/webapp/WEB-INF/ui-config.xml deleted file mode 100644 index 2cd7bfc33b..0000000000 --- a/uma-server-webapp/src/main/webapp/WEB-INF/ui-config.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - resources/js/client.js - resources/js/grant.js - resources/js/scope.js - resources/js/whitelist.js - resources/js/dynreg.js - resources/js/rsreg.js - resources/js/token.js - resources/js/blacklist.js - resources/js/profile.js - resources/js/policy.js - - - - - - diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/user-context.xml b/uma-server-webapp/src/main/webapp/WEB-INF/user-context.xml deleted file mode 100644 index 4a2f7bb0d3..0000000000 --- a/uma-server-webapp/src/main/webapp/WEB-INF/user-context.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - openid - profile - email - phone - address - - - - - - #{configBean.issuer + "openid_connect_login"} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/uma-server-webapp/src/main/webapp/WEB-INF/views/external_login.jsp b/uma-server-webapp/src/main/webapp/WEB-INF/views/external_login.jsp deleted file mode 100644 index 897afdaaa1..0000000000 --- a/uma-server-webapp/src/main/webapp/WEB-INF/views/external_login.jsp +++ /dev/null @@ -1,42 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> -<%@ taglib prefix="o" tagdir="/WEB-INF/tags"%> - - -
    -
    -
    - -

    Log In

    - -

    Enter your email address to log in

    - -
    -
    - -
    -
    - - -
    -
    - -
    - -
    -
    -
    - - - \ No newline at end of file diff --git a/uma-server-webapp/src/main/webapp/resources/js/locale/en/uma.json b/uma-server-webapp/src/main/webapp/resources/js/locale/en/uma.json deleted file mode 100644 index 69ff2e1869..0000000000 --- a/uma-server-webapp/src/main/webapp/resources/js/locale/en/uma.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "admin": { - "policies": "Manage Protected Resource Policies" - }, - "policy" : { - "resource-sets": "Resource Sets", - "edit-policies": "Edit Policies", - "new-policy": "New Policy", - "edit-policy": "Edit Policy", - "loading-policies": "Policies", - "loading-policy": "Policy", - "loading-rs": "Resource Set", - "rs-table": { - "confirm": "Are you sure you want to delete this resource set?", - "no-resource-sets": "There are no resource sets registered. Introduce a protected to this authorization server to let it register some.", - "scopes": "Scopes", - "shared-with": "Shared with:", - "shared-nobody": "NOBODY", - "shared-nobody-tooltip": "This resource is not accessible by anyone else, edit the policies and share it with someone.", - "sharing": "Sharing Policies" - }, - "policy-table": { - "new": "Add New Policy", - "return": "Return to list", - "edit": "Edit Policy", - "confirm": "Are you sure you want to delete this policy?", - "delete": "Delete", - "no-policies": "There are no policies for this resource set: This resource set is inaccessible by others.", - "required-claims": "Required Claims", - "required-claims-info": "Users that you share this resource will with need to be able to present the following claims in order to access the resource.", - "remove": "Remove", - "issuers": "Issuers", - "claim": "Claim", - "value": "Value" - }, - "policy-form": { - "email-address": "email address", - "share-email": "Share with email address", - "new": "New Policy", - "edit": "Edit Policy", - "claim-name": "claim name", - "friendly-claim-name": "friendly claim name", - "claim-value": "claim value", - "value-type-text": "Text", - "value-type-number": "Number", - "clear-all": "Clear all claims", - "clear-all-confirm": "Are you sure you want to clear all claims from this policy?" - }, - "webfinger-error": "Error", - "webfinger-error-description": "The server was unable to find an identity provider for __email__.", - "advanced-error": "Error", - "advanced-error-description": "There was an error saving your advanced claim. Did you fill in all required fields?" - }, - "sidebar": { - "personal": { - "resource_policies": "Manage Protected Resource Policies" - } - } -} \ No newline at end of file diff --git a/uma-server-webapp/src/main/webapp/resources/js/locale/zh/uma.json b/uma-server-webapp/src/main/webapp/resources/js/locale/zh/uma.json deleted file mode 100644 index e2444c4ea1..0000000000 --- a/uma-server-webapp/src/main/webapp/resources/js/locale/zh/uma.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "admin": { - "policies": "管理受保护资源的政策" - }, - "policy" : { - "resource-sets": "资源集", - "edit-policies": "编辑政策", - "new-policy": "新建政策", - "edit-policy": "编辑政策", - "loading-policies": "政策", - "loading-policy": "政策", - "loading-rs": "资源集", - "rs-table": { - "confirm": "确定要删除该资源?", - "no-resource-sets": "尚未有已注册的资源集。您可在此授权服务器中注册一个。", - "scopes": "范围", - "shared-with": "共享给:", - "shared-nobody": "不共享", - "shared-nobody-tooltip": "此资源别人无法访问,请编辑政策使其与其他人共享。", - "sharing": "共享政策" - }, - "policy-table": { - "new": "新建政策", - "return": "返回到列表", - "edit": "编辑政策", - "confirm": "确定要删除该政策?", - "delete": "删除", - "no-policies": "此资源集尚未有政策:别人无法访问此资源集。", - "required-claims": "必须的声明", - "required-claims-info": "与您共享此资源的用户必须具备以下声明,才能访问该资源。", - "remove": "移除", - "issuers": "签发者", - "claim": "声明项", - "value": "值" - }, - "policy-form": { - "email-address": "email地址", - "share-email": "连带email地址共享", - "new": "新建政策", - "edit": "编辑政策", - "claim-name": "声明项名称", - "friendly-claim-name": "声明的显示名", - "claim-value": "声明的值", - "value-type-text": "文本", - "value-type-number": "数字", - "clear-all": "清除全部声明", - "clear-all-confirm": "您是否要从此政策中清除全部声明?" - }, - "webfinger-error": "错误", - "webfinger-error-description": "服务器无法找到__email__的身份提供者。", - "advanced-error": "错误", - "advanced-error-description": "保存高级声明时出错。您是否填写了全部必填项?" - }, - "sidebar": { - "personal": { - "resource_policies": "管理受保护资源的政策" - } - } -} \ No newline at end of file diff --git a/uma-server-webapp/src/main/webapp/resources/js/locale/zh_CN/uma.json b/uma-server-webapp/src/main/webapp/resources/js/locale/zh_CN/uma.json deleted file mode 100644 index e2444c4ea1..0000000000 --- a/uma-server-webapp/src/main/webapp/resources/js/locale/zh_CN/uma.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "admin": { - "policies": "管理受保护资源的政策" - }, - "policy" : { - "resource-sets": "资源集", - "edit-policies": "编辑政策", - "new-policy": "新建政策", - "edit-policy": "编辑政策", - "loading-policies": "政策", - "loading-policy": "政策", - "loading-rs": "资源集", - "rs-table": { - "confirm": "确定要删除该资源?", - "no-resource-sets": "尚未有已注册的资源集。您可在此授权服务器中注册一个。", - "scopes": "范围", - "shared-with": "共享给:", - "shared-nobody": "不共享", - "shared-nobody-tooltip": "此资源别人无法访问,请编辑政策使其与其他人共享。", - "sharing": "共享政策" - }, - "policy-table": { - "new": "新建政策", - "return": "返回到列表", - "edit": "编辑政策", - "confirm": "确定要删除该政策?", - "delete": "删除", - "no-policies": "此资源集尚未有政策:别人无法访问此资源集。", - "required-claims": "必须的声明", - "required-claims-info": "与您共享此资源的用户必须具备以下声明,才能访问该资源。", - "remove": "移除", - "issuers": "签发者", - "claim": "声明项", - "value": "值" - }, - "policy-form": { - "email-address": "email地址", - "share-email": "连带email地址共享", - "new": "新建政策", - "edit": "编辑政策", - "claim-name": "声明项名称", - "friendly-claim-name": "声明的显示名", - "claim-value": "声明的值", - "value-type-text": "文本", - "value-type-number": "数字", - "clear-all": "清除全部声明", - "clear-all-confirm": "您是否要从此政策中清除全部声明?" - }, - "webfinger-error": "错误", - "webfinger-error-description": "服务器无法找到__email__的身份提供者。", - "advanced-error": "错误", - "advanced-error-description": "保存高级声明时出错。您是否填写了全部必填项?" - }, - "sidebar": { - "personal": { - "resource_policies": "管理受保护资源的政策" - } - } -} \ No newline at end of file diff --git a/uma-server-webapp/src/main/webapp/resources/js/locale/zh_TW/uma.json b/uma-server-webapp/src/main/webapp/resources/js/locale/zh_TW/uma.json deleted file mode 100644 index 5232328326..0000000000 --- a/uma-server-webapp/src/main/webapp/resources/js/locale/zh_TW/uma.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "admin": { - "policies": "管理受保護資源的政策" - }, - "policy" : { - "resource-sets": "資源集", - "edit-policies": "編輯政策", - "new-policy": "新建政策", - "edit-policy": "編輯政策", - "loading-policies": "政策", - "loading-policy": "政策", - "loading-rs": "資源集", - "rs-table": { - "confirm": "確定要刪除該資源?", - "no-resource-sets": "尚未有已注冊的資源集。您可在此授權伺服器中注冊一個。", - "scopes": "范圍", - "shared-with": "共享給:", - "shared-nobody": "不共享", - "shared-nobody-tooltip": "此資源別人無法訪問,請編輯政策使其與其他人共享。", - "sharing": "共享政策" - }, - "policy-table": { - "new": "新建政策", - "return": "返回到列表", - "edit": "編輯政策", - "confirm": "確定要刪除該政策?", - "delete": "刪除", - "no-policies": "此資源集尚未有政策:別人無法訪問此資源集。", - "required-claims": "必須的聲明", - "required-claims-info": "與您共享此資源的用戶必須具備以下聲明,才能訪問該資源。", - "remove": "移除", - "issuers": "簽發者", - "claim": "聲明項", - "value": "值" - }, - "policy-form": { - "email-address": "email地址", - "share-email": "連帶email地址共享", - "new": "新建政策", - "edit": "編輯政策", - "claim-name": "聲明項名稱", - "friendly-claim-name": "聲明的顯示名", - "claim-value": "聲明的值", - "value-type-text": "文本", - "value-type-number": "數字", - "clear-all": "清除全部聲明", - "clear-all-confirm": "您是否要從此政策中清除全部聲明?" - }, - "webfinger-error": "錯誤", - "webfinger-error-description": "伺服器無法找到__email__的身份提供者。", - "advanced-error": "錯誤", - "advanced-error-description": "保存高級聲明時出錯。您是否填寫了全部必填項?" - }, - "sidebar": { - "personal": { - "resource_policies": "管理受保護資源的政策" - } - } -} \ No newline at end of file diff --git a/uma-server-webapp/src/main/webapp/resources/js/policy.js b/uma-server-webapp/src/main/webapp/resources/js/policy.js deleted file mode 100644 index 6a3b6420c0..0000000000 --- a/uma-server-webapp/src/main/webapp/resources/js/policy.js +++ /dev/null @@ -1,786 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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. - *******************************************************************************/ - -var ResourceSetModel = Backbone.Model.extend({ - urlRoot: 'api/resourceset' -}); - -var ResourceSetCollection = Backbone.Collection.extend({ - model: ResourceSetModel, - url: 'api/resourceset' -}); - -var PolicyModel = Backbone.Model.extend({ - urlRoot: function() { - return 'api/resourceset/' + this.options.rsid + '/policy/'; - }, - initialize: function(model, options) { - this.options = options; - } -}); - -var PolicyCollection = Backbone.Collection.extend({ - model: PolicyModel, - url: function() { - return 'api/resourceset/' + this.options.rsid + '/policy/'; - }, - initialize: function(models, options) { - this.options = options; - } -}); - -var ResourceSetListView = Backbone.View.extend({ - tagName: 'span', - - initialize:function (options) { - this.options = options; - }, - - load:function(callback) { - if (this.model.isFetched && - this.options.clientList.isFetched && - this.options.systemScopeList.isFetched) { - callback(); - return; - } - - $('#loadingbox').sheet('show'); - $('#loading').html( - '' + $.t('policy.resource-sets') + ' ' + - '' + $.t('common.clients') + ' ' + - '' + $.t('common.scopes') + ' ' - ); - - $.when(this.model.fetchIfNeeded({success:function(e) {$('#loading-resourcesets').addClass('label-success');}}), - this.options.clientList.fetchIfNeeded({success:function(e) {$('#loading-clients').addClass('label-success');}}), - this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}})) - .done(function() { - $('#loadingbox').sheet('hide'); - callback(); - }); - }, - - events: { - "click .refresh-table":"refreshTable" - }, - - render:function (eventName) { - $(this.el).html($('#tmpl-resource-set-table').html()); - - var _self = this; - - _.each(this.model.models, function (resourceSet) { - - // look up client - var client = this.options.clientList.getByClientId(resourceSet.get('clientId')); - - // if there's no client ID, this is an error! - if (client != null) { - var view = new ResourceSetView({model: resourceSet, client: client, systemScopeList: _self.options.systemScopeList}); - view.parentView = _self; - $('#resource-set-table', this.el).append(view.render().el); - } - - }, this); - - this.togglePlaceholder(); - $(this.el).i18n(); - return this; - }, - - togglePlaceholder:function() { - if (this.model.length > 0) { - $('#resource-set-table', this.el).show(); - $('#resource-set-table-empty', this.el).hide(); - } else { - $('#resource-set-table', this.el).hide(); - $('#resource-set-table-empty', this.el).show(); - } - }, - - refreshTable:function(e) { - e.preventDefault(); - var _self = this; - $('#loadingbox').sheet('show'); - $('#loading').html( - '' + $.t('policy.resource-sets') + ' ' + - '' + $.t('common.clients') + ' ' + - '' + $.t('common.scopes') + ' ' - ); - - $.when(this.model.fetch({success:function(e) {$('#loading-resourcesets').addClass('label-success');}}), - this.options.clientList.fetch({success:function(e) {$('#loading-clients').addClass('label-success');}}), - this.options.systemScopeList.fetch({success:function(e) {$('#loading-scopes').addClass('label-success');}})) - .done(function() { - $('#loadingbox').sheet('hide'); - _self.render(); - }); - } - - -}); - - -var ResourceSetView = Backbone.View.extend({ - tagName: 'tr', - - initialize:function(options) { - this.options = options; - if (!this.template) { - this.template = _.template($('#tmpl-resource-set').html()); - } - - if (!this.scopeTemplate) { - this.scopeTemplate = _.template($('#tmpl-scope-list').html()); - } - - if (!this.moreInfoTemplate) { - this.moreInfoTemplate = _.template($('#tmpl-client-more-info-block').html()); - } - - this.model.bind('change', this.render, this); - }, - - render:function(eventName) { - - var json = {rs: this.model.toJSON(), client: this.options.client.toJSON()}; - - this.$el.html(this.template(json)); - - $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList})); - - $('.client-more-info-block', this.el).html(this.moreInfoTemplate({client: this.options.client.toJSON()})); - - $(this.el).i18n(); - return this; - }, - - events:{ - 'click .btn-edit': 'editPolicies', - 'click .btn-delete': 'deleteResourceSet', - 'click .toggleMoreInformation': 'toggleMoreInformation' - }, - - editPolicies:function(e) { - e.preventDefault(); - app.navigate('user/policy/' + this.model.get('id'), {trigger: true}); - }, - - deleteResourceSet:function(e) { - e.preventDefault(); - - if (confirm($.t('policy.rs-table.confirm'))) { - var _self = this; - - this.model.destroy({ - dataType: false, processData: false, - success:function () { - _self.$el.fadeTo("fast", 0.00, function () { //fade - $(this).slideUp("fast", function () { //slide up - $(this).remove(); //then remove from the DOM - _self.parentView.togglePlaceholder(); - }); - }); - }, - error:function (error, response) { - console.log("An error occurred when deleting a resource set"); - - //Pull out the response text. - var responseJson = JSON.parse(response.responseText); - - //Display an alert with an error message - $('#modalAlert div.modal-header').html(responseJson.error); - $('#modalAlert div.modal-body').html(responseJson.error_description); - - $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog - "backdrop" : "static", - "keyboard" : true, - "show" : true // ensure the modal is shown immediately - }); - } - }); - - _self.parentView.delegateEvents(); - } - - return false; - - }, - - toggleMoreInformation:function(e) { - e.preventDefault(); - if ($('.moreInformation', this.el).is(':visible')) { - // hide it - $('.moreInformation', this.el).hide('fast'); - $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-right'); - $('.moreInformationContainer', this.el).removeClass('alert').removeClass('alert-info').addClass('muted'); - - } else { - // show it - $('.moreInformation', this.el).show('fast'); - $('.toggleMoreInformation i', this.el).attr('class', 'icon-chevron-down'); - $('.moreInformationContainer', this.el).addClass('alert').addClass('alert-info').removeClass('muted'); - } - }, - -}); - -var PolicyListView = Backbone.View.extend({ - tagName: 'span', - - initialize:function(options) { - this.options = options; - }, - - load:function(callback) { - if (this.model.isFetched && - this.options.rs.isFetched && - this.options.systemScopeList.isFetched) { - callback(); - return; - } - - $('#loadingbox').sheet('show'); - $('#loading').html( - '' + $.t('policy.loading-policies') + ' ' + - '' + $.t('policy.loading-rs') + ' ' + - '' + $.t("common.scopes") + ' ' - ); - - $.when(this.model.fetchIfNeeded({success:function(e) {$('#loading-policies').addClass('label-success');}}), - this.options.rs.fetchIfNeeded({success:function(e) {$('#loading-rs').addClass('label-success');}}), - this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}})) - .done(function() { - $('#loadingbox').sheet('hide'); - callback(); - }); - }, - - events:{ - 'click .btn-add':'addPolicy', - 'click .btn-cancel':'cancel' - }, - - cancel:function(e) { - e.preventDefault(); - app.navigate('user/policy', {trigger: true}); - }, - - togglePlaceholder:function() { - if (this.model.length > 0) { - $('#policy-info', this.el).show(); - $('#policy-table', this.el).show(); - $('#policy-table-empty', this.el).hide(); - } else { - $('#policy-info', this.el).hide(); - $('#policy-table', this.el).hide(); - $('#policy-table-empty', this.el).show(); - } - }, - - addPolicy:function(e) { - e.preventDefault(); - app.navigate('user/policy/' + this.options.rs.get('id') +'/new', {trigger: true}); - }, - - render:function (eventName) { - $(this.el).html($('#tmpl-policy-table').html()); - - var _self = this; - - _.each(this.model.models, function (policy) { - - var view = new PolicyView({model: policy, systemScopeList: _self.options.systemScopeList, rs: _self.options.rs}); - view.parentView = _self; - $('#policy-table', this.el).append(view.render().el); - - }, this); - - this.togglePlaceholder(); - $(this.el).i18n(); - return this; - } -}); - - -var PolicyView = Backbone.View.extend({ - tagName: 'tr', - - initialize:function(options) { - this.options = options; - - if (!this.template) { - this.template = _.template($('#tmpl-policy').html()); - } - - if (!this.scopeTemplate) { - this.scopeTemplate = _.template($('#tmpl-scope-list').html()); - } - - - }, - - events:{ - 'click .btn-edit':'editPolicy', - 'click .btn-remove':'removePolicy' - }, - - editPolicy:function(e) { - e.preventDefault(); - app.navigate('user/policy/' + this.options.rs.get("id") + '/' + this.model.get('id'), {trigger: true}); - }, - - removePolicy:function(e) { - e.preventDefault(); - - if (confirm($.t('policy.policy-table.confirm'))) { - var _self = this; - this.model.destroy({ - dataType: false, processData: false, - success:function () { - _self.$el.fadeTo("fast", 0.00, function () { //fade - $(this).slideUp("fast", function () { //slide up - $(this).remove(); //then remove from the DOM - _self.parentView.togglePlaceholder(); - }); - }); - }, - error:function (error, response) { - console.log("An error occurred when deleting a client"); - - //Pull out the response text. - var responseJson = JSON.parse(response.responseText); - - //Display an alert with an error message - $('#modalAlert div.modal-header').html(responseJson.error); - $('#modalAlert div.modal-body').html(responseJson.error_description); - - $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog - "backdrop" : "static", - "keyboard" : true, - "show" : true // ensure the modal is shown immediately - }); - } - }); - - _self.parentView.delegateEvents(); - } - }, - - render:function (eventName) { - var json = this.model.toJSON(); - - this.$el.html(this.template(json)); - - $('.scope-list', this.el).html(this.scopeTemplate({scopes: this.model.get('scopes'), systemScopes: this.options.systemScopeList})); - - $(this.el).i18n(); - return this; - } - - -}); - - -var PolicyFormView = Backbone.View.extend({ - tagName: 'div', - - initialize:function(options) { - this.options = options; - - if (!this.template) { - this.template = _.template($('#tmpl-policy-form').html()); - } - - this.issuerCollection = new Backbone.Collection(); - - }, - - events:{ - 'click .btn-share': 'addWebfingerClaim', - 'click .btn-share-advanced': 'addAdvancedClaim', - 'click .btn-clear': 'clearAllClaims', - 'click .btn-save': 'savePolicy', - 'click .btn-cancel': 'cancel' - }, - - load:function(callback) { - if (this.model.isFetched && - this.options.rs.isFetched && - this.options.systemScopeList.isFetched) { - callback(); - return; - } - - $('#loadingbox').sheet('show'); - $('#loading').html( - '' + $.t('policy.loading-policy') + ' ' + - '' + $.t('policy.loading-rs') + ' ' + - '' + $.t("common.scopes") + ' ' - ); - - $.when(this.model.fetchIfNeeded({success:function(e) {$('#loading-policies').addClass('label-success');}}), - this.options.rs.fetchIfNeeded({success:function(e) {$('#loading-rs').addClass('label-success');}}), - this.options.systemScopeList.fetchIfNeeded({success:function(e) {$('#loading-scopes').addClass('label-success');}})) - .done(function() { - $('#loadingbox').sheet('hide'); - callback(); - }); - }, - - addWebfingerClaim:function(e) { - e.preventDefault(); - - // post to the webfinger helper and get the response back - - var _self = this; - - var email = $('#email', this.el).val(); - - $('#loadingbox').sheet('show'); - $('#loading').html( - 'Looking up identity provider...' - ); - - var base = $('base').attr('href'); - $.getJSON(base + '/api/emailsearch?' + $.param({'identifier': email}), function(data) { - - // grab the current state of the scopes checkboxes just in case - var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get(); - - _self.model.set({ - scopes: scopes, - claimsRequired: data - }, {trigger: false}); - - _self.render(); - - $('#loadingbox').sheet('hide'); - - }).error(function(jqXHR, textStatus, errorThrown) { - console.log("An error occurred when doing a webfinger lookup", errorThrown); - - $('#loadingbox').sheet('hide'); - - //Display an alert with an error message - $('#modalAlert div.modal-header').html($.t('policy.webfinger-error')); - $('#modalAlert div.modal-body').html($.t('policy.webfinger-error-description', {email: email})); - - $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog - "backdrop" : "static", - "keyboard" : true, - "show" : true // ensure the modal is shown immediately - }); - }); - - }, - - addAdvancedClaim:function(e) { - e.preventDefault(); - - var name = $('#name', this.el).val(); - var friendly = $('#friendly-name', this.el).val(); - var rawValue = $('#value', this.el).val(); - var valueType = $('#value-type', this.el).val(); - var value = null; - if (valueType == 'number') { - value = Number(rawValue); - } else if (valueType == 'boolean') { - value = (rawValue.toLowerCase() == 'true'); - } else if (valueType == 'json') { - value = JSON.parse(rawValue); - } else { - // treat it as a string, the default - value = rawValue; - } - - var issuers = this.issuerCollection.pluck('item'); - - console.log(name, friendly, rawValue, valueType, value, issuers); - - if (!_.isEmpty(issuers) - && name - && value) { - // we've got a valid claim, add it to our set - // grab the current state of the scopes checkboxes just in case - var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get(); - - var claimsRequired = this.model.get('claimsRequired'); - if (!claimsRequired) { - claimsRequired = []; - } - claimsRequired.push({ - name: name, - friendlyName: friendly, - value: value, - issuer: issuers - }); - - this.model.set({ - scopes: scopes, - claimsRequired: claimsRequired - }, {trigger: false}); - - $('#name', this.el).val(''); - $('#friendly-name', this.el).val(''); - $('#value', this.el).val(''); - $('#value-type', this.el).val('text'); - - this.render(); - - // re-select the advanced tab - $('a[data-target="#policy-advanced-tab"]', this.el).tab('show') - - } else { - // something is missing - $('#loadingbox').sheet('hide'); - - //Display an alert with an error message - $('#modalAlert div.modal-header').html($.t('policy.advanced-error')); - $('#modalAlert div.modal-body').html($.t('policy.advanced-error-description')); - - $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog - "backdrop" : "static", - "keyboard" : true, - "show" : true // ensure the modal is shown immediately - }); - } - }, - - clearAllClaims:function(e) { - e.preventDefault(); - - if (confirm($.t('policy.policy-form.clear-all-confirm'))) { - - var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get(); - - var claimsRequired = []; - - this.model.set({ - scopes: scopes, - claimsRequired: claimsRequired - }, {trigger: false}); - - this.render(); - } - }, - - savePolicy:function(e) { - e.preventDefault(); - - // get all the scopes that are checked - var scopes = $('#scopes input[type="checkbox"]:checked').map(function(idx, elem) { return $(elem).val(); }).get(); - - var valid = this.model.set({ - scopes: scopes - }); - - if (valid) { - - var _self = this; - this.model.save({}, { - success:function() { - app.systemScopeList.add(_self.model); - - // refresh the associated RS - _self.options.rs.fetch({success: function() { - app.navigate('user/policy/' + _self.options.rs.get('id'), {trigger: true}); - }}); - - }, - error:function(error, response) { - - //Pull out the response text. - var responseJson = JSON.parse(response.responseText); - - //Display an alert with an error message - $('#modalAlert div.modal-header').html(responseJson.error); - $('#modalAlert div.modal-body').html(responseJson.error_description); - - $("#modalAlert").modal({ // wire up the actual modal functionality and show the dialog - "backdrop" : "static", - "keyboard" : true, - "show" : true // ensure the modal is shown immediately - }); - } - }); - } - - return false; - - }, - - cancel:function(e) { - e.preventDefault(); - app.navigate('user/policy/' + this.options.rs.get('id'), {trigger: true}); - }, - - render:function (eventName) { - var json = this.model.toJSON(); - var rs = this.options.rs.toJSON(); - - this.$el.html(this.template({policy: json, rs: rs})); - - // build and bind issuer view - var issuerView = new ListWidgetView({ - placeholder: $.t('policy.policy-form.issuer-placeholder'), - helpBlockText: $.t('policy.policy-form.issuer-help'), - collection: this.issuerCollection}); - $("#issuers .controls",this.el).html(issuerView.render().el); - - $(this.el).i18n(); - - return this; - } -}); - - -ui.routes.push({path: "user/policy", name: "policy", callback: - function() { - - this.breadCrumbView.collection.reset(); - this.breadCrumbView.collection.add([ - {text:$.t('admin.home'), href:""}, - {text:$.t('policy.resource-sets'), href:"manage/#user/policy"} - ]); - - this.updateSidebar('user/policy'); - - var view = new ResourceSetListView({model: this.resourceSetList, clientList: this.clientList, systemScopeList: this.systemScopeList}); - - view.load(function() { - $('#content').html(view.render().el); - setPageTitle($.t('policy.resource-sets')); - }); - - } -}); - -ui.routes.push({path: "user/policy/:rsid", name: "editPolicies", callback: - function(rsid) { - - this.breadCrumbView.collection.reset(); - this.breadCrumbView.collection.add([ - {text:$.t('admin.home'), href:""}, - {text:$.t('policy.resource-sets'), href:"manage/#user/policy"}, - {text:$.t('policy.edit-policies'), href:"manage/#user/policy/" + rsid} - ]); - - this.updateSidebar('user/policy'); - - var rs = this.resourceSetList.get(rsid); - var policies = null; - if (rs == null) { - // need to load it directly - policies = new PolicyCollection([], {rsid: rsid}); - rs = new ResourceSetModel({id: rsid}); - this.resourceSetList.add(rs); // it will be loaded below, don't need to load it again in the future - } else { - // the resource set is loaded, preload the claims - policies = new PolicyCollection(rs.get('policies'), {rsid: rsid}); - policies.isFetched = true; - } - - var view = new PolicyListView({model: policies, rs: rs, systemScopeList: this.systemScopeList}); - - view.load(function() { - $('#content').html(view.render().el); - setPageTitle($.t('policy.edit-policy')); - }); - - } -}); - -ui.routes.push({path: "user/policy/:rsid/new", name: "newPolicy", callback: - function(rsid) { - - this.breadCrumbView.collection.reset(); - this.breadCrumbView.collection.add([ - {text:$.t('admin.home'), href:""}, - {text:$.t('policy.resource-sets'), href:"manage/#user/policy"}, - {text:$.t('policy.edit-policies'), href:"manage/#user/policy/" + rsid}, - {text:$.t('policy.new-policy'), href:"manage/#user/policy/" + rsid + "/new"} - ]); - - this.updateSidebar('user/policy'); - - var policy = policy = new PolicyModel({}, {rsid: rsid}); - - var rs = this.resourceSetList.get(rsid); - if (rs == null) { - // need to load it directly - rs = new ResourceSetModel({id: rsid}); - this.resourceSetList.add(rs); // it will be loaded below, don't need to load it again in the future - } - - var view = new PolicyFormView({model: policy, rs: rs, systemScopeList: this.systemScopeList}); - - view.load(function() { - $('#content').html(view.render().el); - setPageTitle($.t('policy.edit-policy')); - }); - } -}); - -ui.routes.push({path: "user/policy/:rsid/:pid", name: "editPolicy", callback: - function(rsid, pid) { - this.breadCrumbView.collection.reset(); - this.breadCrumbView.collection.add([ - {text:$.t('admin.home'), href:""}, - {text:$.t('policy.resource-sets'), href:"manage/#user/policy"}, - {text:$.t('policy.edit-policies'), href:"manage/#user/policy/" + rsid}, - {text:$.t('policy.edit-policy'), href:"manage/#user/policy/" + rsid + "/" + pid} - ]); - - this.updateSidebar('user/policy'); - - var rs = this.resourceSetList.get(rsid); - var policy = null; - if (rs == null) { - // need to load it directly - policy = new PolicyModel({id: pid}, {rsid: rsid}); - rs = new ResourceSetModel({id: rsid}); - this.resourceSetList.add(rs); // it will be loaded below, don't need to load it again in the future - } else { - // the resource set is loaded, preload the claims - _.each(rs.get('policies'), function(p) { - if (p.id == pid) { - policy = new PolicyModel(p, {rsid: rsid}); - policy.isFetched = true; - } - }); - if (policy == null) { - // need to load it directly - policy = new PolicyModel({id: pid}, {rsid: rsid}); - } - } - - var view = new PolicyFormView({model: policy, rs: rs, systemScopeList: this.systemScopeList}); - - view.load(function() { - $('#content').html(view.render().el); - setPageTitle($.t('policy.edit-policy')); - }); - - - } -}); - -ui.templates.push('resources/template/policy.html'); - -ui.init.push(function(app) { - app.resourceSetList = new ResourceSetCollection(); -}); diff --git a/uma-server-webapp/src/main/webapp/resources/template/policy.html b/uma-server-webapp/src/main/webapp/resources/template/policy.html deleted file mode 100644 index 576da1b1ad..0000000000 --- a/uma-server-webapp/src/main/webapp/resources/template/policy.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/uma-server/pom.xml b/uma-server/pom.xml deleted file mode 100644 index 515c7200f5..0000000000 --- a/uma-server/pom.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - 4.0.0 - - org.mitre - openid-connect-parent - 1.3.5-SNAPSHOT - .. - - uma-server - UMA Server Library - User Managed Access (UMA) extension of the MITREid Connect server - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java-version} - ${java-version} - - - - - - - org.mitre - openid-connect-server - - - org.mitre - openid-connect-client - - - diff --git a/uma-server/pom.xml.versionsBackup b/uma-server/pom.xml.versionsBackup deleted file mode 100644 index f7d805b060..0000000000 --- a/uma-server/pom.xml.versionsBackup +++ /dev/null @@ -1,51 +0,0 @@ - - - - 4.0.0 - - org.mitre - openid-connect-parent - 1.2.7-SNAPSHOT - .. - - uma-server - UMA Server Library - User Managed Access (UMA) extension of the MITREid Connect server - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java-version} - ${java-version} - - - - - - - org.mitre - openid-connect-server - - - org.mitre - openid-connect-client - - - \ No newline at end of file diff --git a/uma-server/src/main/java/org/mitre/uma/repository/impl/JpaPermissionRepository.java b/uma-server/src/main/java/org/mitre/uma/repository/impl/JpaPermissionRepository.java deleted file mode 100644 index 6f460d200d..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/repository/impl/JpaPermissionRepository.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.repository.impl; - -import java.util.Collection; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; - -import org.mitre.uma.model.Permission; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.repository.PermissionRepository; -import org.mitre.util.jpa.JpaUtil; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author jricher - * - */ -@Repository -public class JpaPermissionRepository implements PermissionRepository { - - @PersistenceContext(unitName="defaultPersistenceUnit") - private EntityManager em; - - @Override - @Transactional(value="defaultTransactionManager") - public PermissionTicket save(PermissionTicket p) { - return JpaUtil.saveOrUpdate(p.getId(), em, p); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.PermissionRepository#getByTicket(java.lang.String) - */ - @Override - public PermissionTicket getByTicket(String ticket) { - TypedQuery query = em.createNamedQuery(PermissionTicket.QUERY_TICKET, PermissionTicket.class); - query.setParameter(PermissionTicket.PARAM_TICKET, ticket); - return JpaUtil.getSingleResult(query.getResultList()); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.PermissionRepository#getAll() - */ - @Override - public Collection getAll() { - TypedQuery query = em.createNamedQuery(PermissionTicket.QUERY_ALL, PermissionTicket.class); - return query.getResultList(); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.PermissionRepository#saveRawPermission(org.mitre.uma.model.Permission) - */ - @Override - @Transactional(value="defaultTransactionManager") - public Permission saveRawPermission(Permission p) { - return JpaUtil.saveOrUpdate(p.getId(), em, p); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.PermissionRepository#getById(java.lang.Long) - */ - @Override - public Permission getById(Long permissionId) { - return em.find(Permission.class, permissionId); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.PermissionRepository#getPermissionTicketsForResourceSet(org.mitre.uma.model.ResourceSet) - */ - @Override - public Collection getPermissionTicketsForResourceSet(ResourceSet rs) { - TypedQuery query = em.createNamedQuery(PermissionTicket.QUERY_BY_RESOURCE_SET, PermissionTicket.class); - query.setParameter(PermissionTicket.PARAM_RESOURCE_SET_ID, rs.getId()); - return query.getResultList(); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.PermissionRepository#remove(org.mitre.uma.model.PermissionTicket) - */ - @Override - @Transactional(value="defaultTransactionManager") - public void remove(PermissionTicket ticket) { - PermissionTicket found = getByTicket(ticket.getTicket()); - if (found != null) { - em.remove(found); - } - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/repository/impl/JpaResourceSetRepository.java b/uma-server/src/main/java/org/mitre/uma/repository/impl/JpaResourceSetRepository.java deleted file mode 100644 index e19236c399..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/repository/impl/JpaResourceSetRepository.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.repository.impl; - -import java.util.Collection; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; - -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.repository.ResourceSetRepository; -import org.mitre.util.jpa.JpaUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author jricher - * - */ -@Repository -public class JpaResourceSetRepository implements ResourceSetRepository { - - @PersistenceContext(unitName="defaultPersistenceUnit") - private EntityManager em; - private static Logger logger = LoggerFactory.getLogger(JpaResourceSetRepository.class); - - @Override - @Transactional(value="defaultTransactionManager") - public ResourceSet save(ResourceSet rs) { - return JpaUtil.saveOrUpdate(rs.getId(), em, rs); - } - - @Override - public ResourceSet getById(Long id) { - return em.find(ResourceSet.class, id); - } - - @Override - @Transactional(value="defaultTransactionManager") - public void remove(ResourceSet rs) { - ResourceSet found = getById(rs.getId()); - if (found != null) { - em.remove(found); - } else { - logger.info("Tried to remove unknown resource set: " + rs.getId()); - } - } - - @Override - public Collection getAllForOwner(String owner) { - TypedQuery query = em.createNamedQuery(ResourceSet.QUERY_BY_OWNER, ResourceSet.class); - query.setParameter(ResourceSet.PARAM_OWNER, owner); - return query.getResultList(); - } - - @Override - public Collection getAllForOwnerAndClient(String owner, String clientId) { - TypedQuery query = em.createNamedQuery(ResourceSet.QUERY_BY_OWNER_AND_CLIENT, ResourceSet.class); - query.setParameter(ResourceSet.PARAM_OWNER, owner); - query.setParameter(ResourceSet.PARAM_CLIENTID, clientId); - return query.getResultList(); - } - - @Override - public Collection getAll() { - TypedQuery query = em.createNamedQuery(ResourceSet.QUERY_ALL, ResourceSet.class); - return query.getResultList(); - } - - /* (non-Javadoc) - * @see org.mitre.uma.repository.ResourceSetRepository#getAllForClient(org.mitre.oauth2.model.ClientDetailsEntity) - */ - @Override - public Collection getAllForClient(String clientId) { - TypedQuery query = em.createNamedQuery(ResourceSet.QUERY_BY_CLIENT, ResourceSet.class); - query.setParameter(ResourceSet.PARAM_CLIENTID, clientId); - return query.getResultList(); - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java b/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java deleted file mode 100644 index 8b9c379e48..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultPermissionService.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import java.sql.Date; -import java.util.Set; -import java.util.UUID; - -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.uma.model.Permission; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.repository.PermissionRepository; -import org.mitre.uma.service.PermissionService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException; -import org.springframework.stereotype.Service; - -/** - * @author jricher - * - */ -@Service -public class DefaultPermissionService implements PermissionService { - - @Autowired - private PermissionRepository repository; - - @Autowired - private SystemScopeService scopeService; - - private Long permissionExpirationSeconds = 60L * 60L; // 1 hr - - /* (non-Javadoc) - * @see org.mitre.uma.service.PermissionService#create(org.mitre.uma.model.ResourceSet, java.util.Set) - */ - @Override - public PermissionTicket createTicket(ResourceSet resourceSet, Set scopes) { - - // check to ensure that the scopes requested are a subset of those in the resource set - - if (!scopeService.scopesMatch(resourceSet.getScopes(), scopes)) { - throw new InsufficientScopeException("Scopes of resource set are not enough for requested permission."); - } - - Permission perm = new Permission(); - perm.setResourceSet(resourceSet); - perm.setScopes(scopes); - - PermissionTicket ticket = new PermissionTicket(); - ticket.setPermission(perm); - ticket.setTicket(UUID.randomUUID().toString()); - ticket.setExpiration(new Date(System.currentTimeMillis() + permissionExpirationSeconds * 1000L)); - - return repository.save(ticket); - - } - - /* (non-Javadoc) - * @see org.mitre.uma.service.PermissionService#getByTicket(java.lang.String) - */ - @Override - public PermissionTicket getByTicket(String ticket) { - return repository.getByTicket(ticket); - } - - /* (non-Javadoc) - * @see org.mitre.uma.service.PermissionService#updateTicket(org.mitre.uma.model.PermissionTicket) - */ - @Override - public PermissionTicket updateTicket(PermissionTicket ticket) { - if (ticket.getId() != null) { - return repository.save(ticket); - } else { - return null; - } - - } - - - -} diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultResourceSetService.java b/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultResourceSetService.java deleted file mode 100644 index a5c3e5ec4b..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultResourceSetService.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import java.util.Collection; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.Policy; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.repository.PermissionRepository; -import org.mitre.uma.repository.ResourceSetRepository; -import org.mitre.uma.service.ResourceSetService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Service; - -/** - * @author jricher - * - */ -@Service -@Primary -public class DefaultResourceSetService implements ResourceSetService { - - private static final Logger logger = LoggerFactory.getLogger(DefaultResourceSetService.class); - - @Autowired - private ResourceSetRepository repository; - - @Autowired - private OAuth2TokenRepository tokenRepository; - - @Autowired - private PermissionRepository ticketRepository; - - @Override - public ResourceSet saveNew(ResourceSet rs) { - - if (rs.getId() != null) { - throw new IllegalArgumentException("Can't save a new resource set with an ID already set to it."); - } - - if (!checkScopeConsistency(rs)) { - throw new IllegalArgumentException("Can't save a resource set with inconsistent claims."); - } - - ResourceSet saved = repository.save(rs); - - return saved; - - } - - @Override - public ResourceSet getById(Long id) { - return repository.getById(id); - } - - @Override - public ResourceSet update(ResourceSet oldRs, ResourceSet newRs) { - - if (oldRs.getId() == null || newRs.getId() == null - || !oldRs.getId().equals(newRs.getId())) { - - throw new IllegalArgumentException("Resource set IDs mismatched"); - - } - - if (!checkScopeConsistency(newRs)) { - throw new IllegalArgumentException("Can't save a resource set with inconsistent claims."); - } - - newRs.setOwner(oldRs.getOwner()); // preserve the owner tag across updates - newRs.setClientId(oldRs.getClientId()); // preserve the client id across updates - - ResourceSet saved = repository.save(newRs); - - return saved; - - } - - @Override - public void remove(ResourceSet rs) { - // find all the access tokens issued against this resource set and revoke them - Collection tokens = tokenRepository.getAccessTokensForResourceSet(rs); - for (OAuth2AccessTokenEntity token : tokens) { - tokenRepository.removeAccessToken(token); - } - - // find all outstanding tickets issued against this resource set and revoke them too - Collection tickets = ticketRepository.getPermissionTicketsForResourceSet(rs); - for (PermissionTicket ticket : tickets) { - ticketRepository.remove(ticket); - } - - repository.remove(rs); - } - - @Override - public Collection getAllForOwner(String owner) { - return repository.getAllForOwner(owner); - } - - @Override - public Collection getAllForOwnerAndClient(String owner, String clientId) { - return repository.getAllForOwnerAndClient(owner, clientId); - } - - private boolean checkScopeConsistency(ResourceSet rs) { - if (rs.getPolicies() == null) { - // nothing to check, no problem! - return true; - } - for (Policy policy : rs.getPolicies()) { - if (!rs.getScopes().containsAll(policy.getScopes())) { - return false; - } - } - // we've checked everything, we're good - return true; - } - - /* (non-Javadoc) - * @see org.mitre.uma.service.ResourceSetService#getAllForClient(org.mitre.oauth2.model.ClientDetailsEntity) - */ - @Override - public Collection getAllForClient(ClientDetailsEntity client) { - return repository.getAllForClient(client.getClientId()); - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultUmaTokenService.java b/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultUmaTokenService.java deleted file mode 100644 index 62bd24eac0..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/service/impl/DefaultUmaTokenService.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import java.util.Date; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -import org.mitre.jwt.signer.service.JWTSigningAndValidationService; -import org.mitre.oauth2.model.AuthenticationHolderEntity; -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.repository.AuthenticationHolderRepository; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.uma.model.Permission; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.Policy; -import org.mitre.uma.service.UmaTokenService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Service; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; - -/** - * @author jricher - * - */ -@Service("defaultUmaTokenService") -public class DefaultUmaTokenService implements UmaTokenService { - - @Autowired - private AuthenticationHolderRepository authenticationHolderRepository; - - @Autowired - private OAuth2TokenEntityService tokenService; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private ConfigurationPropertiesBean config; - - @Autowired - private JWTSigningAndValidationService jwtService; - - - @Override - public OAuth2AccessTokenEntity createRequestingPartyToken(OAuth2Authentication o2auth, PermissionTicket ticket, Policy policy) { - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setAuthentication(o2auth); - authHolder = authenticationHolderRepository.save(authHolder); - - token.setAuthenticationHolder(authHolder); - - ClientDetailsEntity client = clientService.loadClientByClientId(o2auth.getOAuth2Request().getClientId()); - token.setClient(client); - - Set ticketScopes = ticket.getPermission().getScopes(); - Set policyScopes = policy.getScopes(); - - Permission perm = new Permission(); - perm.setResourceSet(ticket.getPermission().getResourceSet()); - perm.setScopes(new HashSet<>(Sets.intersection(ticketScopes, policyScopes))); - - token.setPermissions(Sets.newHashSet(perm)); - - JWTClaimsSet.Builder claims = new JWTClaimsSet.Builder(); - - claims.audience(Lists.newArrayList(ticket.getPermission().getResourceSet().getId().toString())); - claims.issuer(config.getIssuer()); - claims.jwtID(UUID.randomUUID().toString()); - - if (config.getRqpTokenLifeTime() != null) { - Date exp = new Date(System.currentTimeMillis() + config.getRqpTokenLifeTime() * 1000L); - - claims.expirationTime(exp); - token.setExpiration(exp); - } - - - JWSAlgorithm signingAlgorithm = jwtService.getDefaultSigningAlgorithm(); - JWSHeader header = new JWSHeader(signingAlgorithm, null, null, null, null, null, null, null, null, null, - jwtService.getDefaultSignerKeyId(), - null, null); - SignedJWT signed = new SignedJWT(header, claims.build()); - - jwtService.signJwt(signed); - - token.setJwt(signed); - - tokenService.saveAccessToken(token); - - return token; - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/JpaRegisteredClientService.java b/uma-server/src/main/java/org/mitre/uma/service/impl/JpaRegisteredClientService.java deleted file mode 100644 index 8ceb548e8c..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/service/impl/JpaRegisteredClientService.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import java.util.Collection; - -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; - -import org.mitre.oauth2.model.RegisteredClient; -import org.mitre.openid.connect.client.service.RegisteredClientService; -import org.mitre.uma.model.SavedRegisteredClient; -import org.mitre.uma.service.SavedRegisteredClientService; -import org.mitre.util.jpa.JpaUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * @author jricher - * - */ -@Service -public class JpaRegisteredClientService implements RegisteredClientService, SavedRegisteredClientService{ - - @PersistenceContext(unitName="defaultPersistenceUnit") - private EntityManager em; - - /* (non-Javadoc) - * @see org.mitre.openid.connect.client.service.RegisteredClientService#getByIssuer(java.lang.String) - */ - @Override - public RegisteredClient getByIssuer(String issuer) { - SavedRegisteredClient saved = getSavedRegisteredClientFromStorage(issuer); - - if (saved == null) { - return null; - } else { - return saved.getRegisteredClient(); - } - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.client.service.RegisteredClientService#save(java.lang.String, org.mitre.oauth2.model.RegisteredClient) - */ - @Override - @Transactional(value="defaultTransactionManager") - public void save(String issuer, RegisteredClient client) { - - - SavedRegisteredClient saved = getSavedRegisteredClientFromStorage(issuer); - - if (saved == null) { - saved = new SavedRegisteredClient(); - saved.setIssuer(issuer); - } - - saved.setRegisteredClient(client); - - em.persist(saved); - - } - - private SavedRegisteredClient getSavedRegisteredClientFromStorage(String issuer) { - TypedQuery query = em.createQuery("SELECT c from SavedRegisteredClient c where c.issuer = :issuer", SavedRegisteredClient.class); - query.setParameter("issuer", issuer); - - SavedRegisteredClient saved = JpaUtil.getSingleResult(query.getResultList()); - return saved; - } - - /** - * @return - */ - @Override - public Collection getAll() { - TypedQuery query = em.createQuery("SELECT c from SavedRegisteredClient c", SavedRegisteredClient.class); - return query.getResultList(); - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java b/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java deleted file mode 100644 index 7d480bf619..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/service/impl/MatchAllClaimsOnAnyPolicy.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import java.util.Collection; -import java.util.HashSet; - -import org.mitre.uma.model.Claim; -import org.mitre.uma.model.ClaimProcessingResult; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.Policy; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ClaimsProcessingService; -import org.springframework.stereotype.Service; - -/** - * Tests if all the claims in the required set have a matching - * value in the supplied set. - * - * @author jricher - * - */ -@Service("matchAllClaimsOnAnyPolicy") -public class MatchAllClaimsOnAnyPolicy implements ClaimsProcessingService { - - /* (non-Javadoc) - * @see org.mitre.uma.service.ClaimsProcessingService#claimsAreSatisfied(java.util.Collection, java.util.Collection) - */ - @Override - public ClaimProcessingResult claimsAreSatisfied(ResourceSet rs, PermissionTicket ticket) { - Collection allUnmatched = new HashSet<>(); - for (Policy policy : rs.getPolicies()) { - Collection unmatched = checkIndividualClaims(policy.getClaimsRequired(), ticket.getClaimsSupplied()); - if (unmatched.isEmpty()) { - // we found something that's satisfied the claims, let's go with it! - return new ClaimProcessingResult(policy); - } else { - // otherwise add it to the stack to send back - allUnmatched.addAll(unmatched); - } - } - - // otherwise, tell the caller that we'll need some set of these fulfilled somehow - return new ClaimProcessingResult(allUnmatched); - } - - private Collection checkIndividualClaims(Collection claimsRequired, Collection claimsSupplied) { - - Collection claimsUnmatched = new HashSet<>(claimsRequired); - - // see if each of the required claims has a counterpart in the supplied claims set - for (Claim required : claimsRequired) { - for (Claim supplied : claimsSupplied) { - - if (required.getIssuer().containsAll(supplied.getIssuer())) { - // it's from the right issuer - - if (required.getName().equals(supplied.getName()) && - required.getValue().equals(supplied.getValue())) { - - // the claim matched, pull it from the set - claimsUnmatched.remove(required); - - } - - } - } - } - - // if there's anything left then the claims aren't satisfied, return the leftovers - return claimsUnmatched; - - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/service/impl/UmaDataServiceExtension_1_3.java b/uma-server/src/main/java/org/mitre/uma/service/impl/UmaDataServiceExtension_1_3.java deleted file mode 100644 index 6e9fba180f..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/service/impl/UmaDataServiceExtension_1_3.java +++ /dev/null @@ -1,715 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import static org.mitre.util.JsonUtils.readSet; - -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.model.RegisteredClient; -import org.mitre.oauth2.repository.OAuth2TokenRepository; -import org.mitre.openid.connect.ClientDetailsEntityJsonProcessor; -import org.mitre.openid.connect.service.MITREidDataService; -import org.mitre.openid.connect.service.MITREidDataServiceExtension; -import org.mitre.openid.connect.service.MITREidDataServiceMaps; -import org.mitre.openid.connect.service.impl.MITREidDataServiceSupport; -import org.mitre.uma.model.Claim; -import org.mitre.uma.model.Permission; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.Policy; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.model.SavedRegisteredClient; -import org.mitre.uma.repository.PermissionRepository; -import org.mitre.uma.repository.ResourceSetRepository; -import org.mitre.uma.service.SavedRegisteredClientService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonToken; -import com.google.gson.stream.JsonWriter; - -/** - * @author jricher - * - */ -@Service("umaDataExtension_1_3") -public class UmaDataServiceExtension_1_3 extends MITREidDataServiceSupport implements MITREidDataServiceExtension { - - private static final String THIS_VERSION = MITREidDataService.MITREID_CONNECT_1_3; - - private static final String REGISTERED_CLIENT = "registeredClient"; - private static final String URI = "uri"; - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String VALUE = "value"; - private static final String CLIENT_ID = "clientId"; - private static final String EXPIRATION = "expiration"; - private static final String ID = "id"; - private static final String ICON_URI = "iconUri"; - private static final String OWNER = "owner"; - private static final String POLICIES = "policies"; - private static final String SCOPES = "scopes"; - private static final String CLAIMS_REQUIRED = "claimsRequired"; - private static final String ISSUER = "issuer"; - private static final String CLAIM_TOKEN_FORMAT = "claimTokenFormat"; - private static final String CLAIM_TYPE = "claimType"; - private static final String FRIENDLY_NAME = "friendlyName"; - private static final String PERMISSIONS = "permissions"; - private static final String RESOURCE_SET = "resourceSet"; - private static final String PERMISSION_TICKETS = "permissionTickets"; - private static final String PERMISSION = "permission"; - private static final String TICKET = "ticket"; - private static final String CLAIMS_SUPPLIED = "claimsSupplied"; - private static final String SAVED_REGISTERED_CLIENTS = "savedRegisteredClients"; - private static final String RESOURCE_SETS = "resourceSets"; - private static final String TOKEN_PERMISSIONS = "tokenPermissions"; - private static final String TOKEN_ID = "tokenId"; - - private static final Logger logger = LoggerFactory.getLogger(UmaDataServiceExtension_1_3.class); - - - - @Autowired - private SavedRegisteredClientService registeredClientService; - @Autowired - private ResourceSetRepository resourceSetRepository; - @Autowired - private PermissionRepository permissionRepository; - @Autowired - private OAuth2TokenRepository tokenRepository; - - private Map> tokenToPermissionRefs = new HashMap<>(); - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataServiceExtension#supportsVersion(java.lang.String) - */ - @Override - public boolean supportsVersion(String version) { - return THIS_VERSION.equals(version); - - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataServiceExtension#exportExtensionData(com.google.gson.stream.JsonWriter) - */ - @Override - public void exportExtensionData(JsonWriter writer) throws IOException { - writer.name(SAVED_REGISTERED_CLIENTS); - writer.beginArray(); - writeSavedRegisteredClients(writer); - writer.endArray(); - - writer.name(RESOURCE_SETS); - writer.beginArray(); - writeResourceSets(writer); - writer.endArray(); - - writer.name(PERMISSION_TICKETS); - writer.beginArray(); - writePermissionTickets(writer); - writer.endArray(); - - writer.name(TOKEN_PERMISSIONS); - writer.beginArray(); - writeTokenPermissions(writer); - writer.endArray(); - } - - /** - * @param writer - * @throws IOException - */ - private void writeTokenPermissions(JsonWriter writer) throws IOException { - for (OAuth2AccessTokenEntity token : tokenRepository.getAllAccessTokens()) { - if (!token.getPermissions().isEmpty()) { // skip tokens that don't have the permissions structure attached - writer.beginObject(); - writer.name(TOKEN_ID).value(token.getId()); - writer.name(PERMISSIONS); - writer.beginArray(); - for (Permission p : token.getPermissions()) { - writer.beginObject(); - writer.name(RESOURCE_SET).value(p.getResourceSet().getId()); - writer.name(SCOPES); - writer.beginArray(); - for (String s : p.getScopes()) { - writer.value(s); - } - writer.endArray(); - writer.endObject(); - } - writer.endArray(); - - writer.endObject(); - } - } - } - - /** - * @param writer - * @throws IOException - */ - private void writePermissionTickets(JsonWriter writer) throws IOException { - for (PermissionTicket ticket : permissionRepository.getAll()) { - writer.beginObject(); - - writer.name(CLAIMS_SUPPLIED); - writer.beginArray(); - for (Claim claim : ticket.getClaimsSupplied()) { - writer.beginObject(); - - writer.name(ISSUER); - writer.beginArray(); - for (String issuer : claim.getIssuer()) { - writer.value(issuer); - } - writer.endArray(); - writer.name(CLAIM_TOKEN_FORMAT); - writer.beginArray(); - for (String format : claim.getClaimTokenFormat()) { - writer.value(format); - } - writer.endArray(); - writer.name(CLAIM_TYPE).value(claim.getClaimType()); - writer.name(FRIENDLY_NAME).value(claim.getFriendlyName()); - writer.name(NAME).value(claim.getName()); - writer.name(VALUE).value(claim.getValue().toString()); - writer.endObject(); - } - writer.endArray(); - - writer.name(EXPIRATION).value(toUTCString(ticket.getExpiration())); - - writer.name(PERMISSION); - writer.beginObject(); - Permission p = ticket.getPermission(); - writer.name(RESOURCE_SET).value(p.getResourceSet().getId()); - writer.name(SCOPES); - writer.beginArray(); - for (String s : p.getScopes()) { - writer.value(s); - } - writer.endArray(); - writer.endObject(); - - writer.name(TICKET).value(ticket.getTicket()); - - writer.endObject(); - } - - - } - - /** - * @param writer - * @throws IOException - */ - private void writeResourceSets(JsonWriter writer) throws IOException { - for (ResourceSet rs : resourceSetRepository.getAll()) { - writer.beginObject(); - writer.name(ID).value(rs.getId()); - writer.name(CLIENT_ID).value(rs.getClientId()); - writer.name(ICON_URI).value(rs.getIconUri()); - writer.name(NAME).value(rs.getName()); - writer.name(TYPE).value(rs.getType()); - writer.name(URI).value(rs.getUri()); - writer.name(OWNER).value(rs.getOwner()); - writer.name(POLICIES); - writer.beginArray(); - for (Policy policy : rs.getPolicies()) { - writer.beginObject(); - writer.name(NAME).value(policy.getName()); - writer.name(SCOPES); - writer.beginArray(); - for (String scope : policy.getScopes()) { - writer.value(scope); - } - writer.endArray(); - writer.name(CLAIMS_REQUIRED); - writer.beginArray(); - for (Claim claim : policy.getClaimsRequired()) { - writer.beginObject(); - - writer.name(ISSUER); - writer.beginArray(); - for (String issuer : claim.getIssuer()) { - writer.value(issuer); - } - writer.endArray(); - writer.name(CLAIM_TOKEN_FORMAT); - writer.beginArray(); - for (String format : claim.getClaimTokenFormat()) { - writer.value(format); - } - writer.endArray(); - writer.name(CLAIM_TYPE).value(claim.getClaimType()); - writer.name(FRIENDLY_NAME).value(claim.getFriendlyName()); - writer.name(NAME).value(claim.getName()); - writer.name(VALUE).value(claim.getValue().toString()); - writer.endObject(); - } - writer.endArray(); - writer.endObject(); - } - writer.endArray(); - writer.name(SCOPES); - writer.beginArray(); - for (String scope : rs.getScopes()) { - writer.value(scope); - } - writer.endArray(); - writer.endObject(); - logger.debug("Finished writing resource set {}", rs.getId()); - } - - } - - /** - * @param writer - */ - private void writeSavedRegisteredClients(JsonWriter writer) throws IOException { - for (SavedRegisteredClient src : registeredClientService.getAll()) { - writer.beginObject(); - writer.name(ISSUER).value(src.getIssuer()); - writer.name(REGISTERED_CLIENT).value(src.getRegisteredClient().getSource().toString()); - writer.endObject(); - logger.debug("Wrote saved registered client {}", src.getId()); - } - logger.info("Done writing saved registered clients"); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataServiceExtension#importExtensionData(com.google.gson.stream.JsonReader) - */ - @Override - public boolean importExtensionData(String name, JsonReader reader) throws IOException { - if (name.equals(SAVED_REGISTERED_CLIENTS)) { - readSavedRegisteredClients(reader); - return true; - } else if (name.equals(RESOURCE_SETS)) { - readResourceSets(reader); - return true; - } else if (name.equals(PERMISSION_TICKETS)) { - readPermissionTickets(reader); - return true; - } else if (name.equals(TOKEN_PERMISSIONS)) { - readTokenPermissions(reader); - return true; - } else { - return false; - } - } - - /** - * @param reader - */ - private void readTokenPermissions(JsonReader reader) throws IOException { - reader.beginArray(); - while(reader.hasNext()) { - reader.beginObject(); - Long tokenId = null; - Set permissions = new HashSet<>(); - while (reader.hasNext()) { - switch(reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (name.equals(TOKEN_ID)) { - tokenId = reader.nextLong(); - } else if (name.equals(PERMISSIONS)) { - reader.beginArray(); - while (reader.hasNext()) { - Permission p = new Permission(); - Long rsid = null; - Set scope = new HashSet<>(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String pname = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (pname.equals(RESOURCE_SET)) { - rsid = reader.nextLong(); - } else if (pname.equals(SCOPES)) { - scope = readSet(reader); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - p.setScopes(scope); - Permission saved = permissionRepository.saveRawPermission(p); - permissionToResourceRefs.put(saved.getId(), rsid); - permissions.add(saved.getId()); - } - reader.endArray(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - tokenToPermissionRefs.put(tokenId, permissions); - } - reader.endArray(); - - } - - private Map permissionToResourceRefs = new HashMap<>(); - - /** - * @param reader - */ - private void readPermissionTickets(JsonReader reader) throws IOException { - JsonParser parser = new JsonParser(); - reader.beginArray(); - while (reader.hasNext()) { - PermissionTicket ticket = new PermissionTicket(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(CLAIMS_SUPPLIED)) { - Set claimsSupplied = new HashSet<>(); - reader.beginArray(); - while (reader.hasNext()) { - Claim c = new Claim(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String cname = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (cname.equals(ISSUER)) { - c.setIssuer(readSet(reader)); - } else if (cname.equals(CLAIM_TOKEN_FORMAT)) { - c.setClaimTokenFormat(readSet(reader)); - } else if (cname.equals(CLAIM_TYPE)) { - c.setClaimType(reader.nextString()); - } else if (cname.equals(FRIENDLY_NAME)) { - c.setFriendlyName(reader.nextString()); - } else if (cname.equals(NAME)) { - c.setName(reader.nextString()); - } else if (cname.equals(VALUE)) { - JsonElement e = parser.parse(reader.nextString()); - c.setValue(e); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - claimsSupplied.add(c); - } - reader.endArray(); - ticket.setClaimsSupplied(claimsSupplied); - } else if (name.equals(EXPIRATION)) { - ticket.setExpiration(utcToDate(reader.nextString())); - } else if (name.equals(PERMISSION)) { - Permission p = new Permission(); - Long rsid = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String pname = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (pname.equals(RESOURCE_SET)) { - rsid = reader.nextLong(); - } else if (pname.equals(SCOPES)) { - p.setScopes(readSet(reader)); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Permission saved = permissionRepository.saveRawPermission(p); - permissionToResourceRefs.put(saved.getId(), rsid); - ticket.setPermission(saved); - } else if (name.equals(TICKET)) { - ticket.setTicket(reader.nextString()); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - permissionRepository.save(ticket); - } - reader.endArray(); - } - - - private Map resourceSetOldToNewIdMap = new HashMap<>(); - - /** - * @param reader - */ - private void readResourceSets(JsonReader reader) throws IOException { - JsonParser parser = new JsonParser(); - reader.beginArray(); - while (reader.hasNext()) { - Long oldId = null; - ResourceSet rs = new ResourceSet(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ID)) { - oldId = reader.nextLong(); - } else if (name.equals(CLIENT_ID)) { - rs.setClientId(reader.nextString()); - } else if (name.equals(ICON_URI)) { - rs.setIconUri(reader.nextString()); - } else if (name.equals(NAME)) { - rs.setName(reader.nextString()); - } else if (name.equals(TYPE)) { - rs.setType(reader.nextString()); - } else if (name.equals(URI)) { - rs.setUri(reader.nextString()); - } else if (name.equals(OWNER)) { - rs.setOwner(reader.nextString()); - } else if (name.equals(POLICIES)) { - Set policies = new HashSet<>(); - reader.beginArray(); - while (reader.hasNext()) { - Policy p = new Policy(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String pname = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (pname.equals(NAME)) { - p.setName(reader.nextString()); - } else if (pname.equals(SCOPES)) { - p.setScopes(readSet(reader)); - } else if (pname.equals(CLAIMS_REQUIRED)) { - Set claimsRequired = new HashSet<>(); - reader.beginArray(); - while (reader.hasNext()) { - Claim c = new Claim(); - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String cname = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (cname.equals(ISSUER)) { - c.setIssuer(readSet(reader)); - } else if (cname.equals(CLAIM_TOKEN_FORMAT)) { - c.setClaimTokenFormat(readSet(reader)); - } else if (cname.equals(CLAIM_TYPE)) { - c.setClaimType(reader.nextString()); - } else if (cname.equals(FRIENDLY_NAME)) { - c.setFriendlyName(reader.nextString()); - } else if (cname.equals(NAME)) { - c.setName(reader.nextString()); - } else if (cname.equals(VALUE)) { - JsonElement e = parser.parse(reader.nextString()); - c.setValue(e); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - claimsRequired.add(c); - } - reader.endArray(); - p.setClaimsRequired(claimsRequired); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - policies.add(p); - } - reader.endArray(); - rs.setPolicies(policies); - } else if (name.equals(SCOPES)) { - rs.setScopes(readSet(reader)); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - Long newId = resourceSetRepository.save(rs).getId(); - resourceSetOldToNewIdMap.put(oldId, newId); - } - reader.endArray(); - logger.info("Done reading resource sets"); - } - - /** - * @param reader - */ - private void readSavedRegisteredClients(JsonReader reader) throws IOException{ - reader.beginArray(); - while (reader.hasNext()) { - String issuer = null; - String clientString = null; - reader.beginObject(); - while (reader.hasNext()) { - switch (reader.peek()) { - case END_OBJECT: - continue; - case NAME: - String name = reader.nextName(); - if (reader.peek() == JsonToken.NULL) { - reader.skipValue(); - } else if (name.equals(ISSUER)) { - issuer = reader.nextString(); - } else if (name.equals(REGISTERED_CLIENT)) { - clientString = reader.nextString(); - } else { - logger.debug("Found unexpected entry"); - reader.skipValue(); - } - break; - default: - logger.debug("Found unexpected entry"); - reader.skipValue(); - continue; - } - } - reader.endObject(); - RegisteredClient client = ClientDetailsEntityJsonProcessor.parseRegistered(clientString); - registeredClientService.save(issuer, client); - logger.debug("Saved registered client"); - } - reader.endArray(); - logger.info("Done reading saved registered clients"); - } - - /* (non-Javadoc) - * @see org.mitre.openid.connect.service.MITREidDataServiceExtension#fixExtensionObjectReferences() - */ - @Override - public void fixExtensionObjectReferences(MITREidDataServiceMaps maps) { - for (Long permissionId : permissionToResourceRefs.keySet()) { - Long oldResourceId = permissionToResourceRefs.get(permissionId); - Long newResourceId = resourceSetOldToNewIdMap.get(oldResourceId); - Permission p = permissionRepository.getById(permissionId); - ResourceSet rs = resourceSetRepository.getById(newResourceId); - p.setResourceSet(rs); - permissionRepository.saveRawPermission(p); - logger.debug("Mapping rsid " + oldResourceId + " to " + newResourceId + " for permission " + permissionId); - } - for (Long tokenId : tokenToPermissionRefs.keySet()) { - Long newTokenId = maps.getAccessTokenOldToNewIdMap().get(tokenId); - OAuth2AccessTokenEntity token = tokenRepository.getAccessTokenById(newTokenId); - - Set permissions = new HashSet<>(); - for (Long permissionId : tokenToPermissionRefs.get(tokenId)) { - Permission p = permissionRepository.getById(permissionId); - permissions.add(p); - } - - token.setPermissions(permissions); - tokenRepository.saveAccessToken(token); - } - permissionToResourceRefs.clear(); - resourceSetOldToNewIdMap.clear(); - tokenToPermissionRefs.clear(); - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/util/ExternalLoginAuthoritiesMapper.java b/uma-server/src/main/java/org/mitre/uma/util/ExternalLoginAuthoritiesMapper.java deleted file mode 100644 index 9626eba04a..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/util/ExternalLoginAuthoritiesMapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.util; - -import java.util.Collection; - -import org.mitre.openid.connect.client.OIDCAuthoritiesMapper; -import org.mitre.openid.connect.model.UserInfo; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; - -import com.google.common.collect.Sets; -import com.nimbusds.jwt.JWT; - -/** - * Utility class to map all external logins to the ROLE_EXTERNAL_USER authority - * to prevent them from accessing other parts of the server. - * - * @author jricher - * - */ -public class ExternalLoginAuthoritiesMapper implements OIDCAuthoritiesMapper { - - private static final GrantedAuthority ROLE_EXTERNAL_USER = new SimpleGrantedAuthority("ROLE_EXTERNAL_USER"); - - @Override - public Collection mapAuthorities(JWT idToken, UserInfo userInfo) { - return Sets.newHashSet(ROLE_EXTERNAL_USER); - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/view/ResourceSetEntityAbbreviatedView.java b/uma-server/src/main/java/org/mitre/uma/view/ResourceSetEntityAbbreviatedView.java deleted file mode 100644 index 9f581fb67c..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/view/ResourceSetEntityAbbreviatedView.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.view; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.uma.model.ResourceSet; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.web.servlet.view.AbstractView; - -import com.google.common.base.Strings; -import com.google.gson.ExclusionStrategy; -import com.google.gson.FieldAttributes; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import com.google.gson.LongSerializationPolicy; - -@Component(ResourceSetEntityAbbreviatedView.VIEWNAME) -public class ResourceSetEntityAbbreviatedView extends AbstractView { - private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class); - - public static final String VIEWNAME = "resourceSetEntityAbbreviatedView"; - - public static final String LOCATION = "location"; - - @Autowired - private ConfigurationPropertiesBean config; - - private Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - @Override - public boolean shouldSkipField(FieldAttributes f) { - - return false; - } - - @Override - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }) - .serializeNulls() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .setLongSerializationPolicy(LongSerializationPolicy.STRING) - .create(); - - @Override - protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { - - response.setContentType("application/json"); - - - HttpStatus code = (HttpStatus) model.get(HttpCodeView.CODE); - if (code == null) { - code = HttpStatus.OK; // default to 200 - } - - response.setStatus(code.value()); - - String location = (String) model.get(LOCATION); - if (!Strings.isNullOrEmpty(location)) { - response.setHeader(HttpHeaders.LOCATION, location); - } - - try { - - Writer out = response.getWriter(); - ResourceSet rs = (ResourceSet) model.get(JsonEntityView.ENTITY); - - JsonObject o = new JsonObject(); - - o.addProperty("_id", rs.getId().toString()); // set the ID to a string - o.addProperty("user_access_policy_uri", config.getIssuer() + "manage/user/policy/" + rs.getId()); - - - gson.toJson(o, out); - - } catch (IOException e) { - - logger.error("IOException in ResourceSetEntityView.java: ", e); - - } - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/view/ResourceSetEntityView.java b/uma-server/src/main/java/org/mitre/uma/view/ResourceSetEntityView.java deleted file mode 100644 index e34e474313..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/view/ResourceSetEntityView.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.view; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.uma.model.ResourceSet; -import org.mitre.util.JsonUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.web.servlet.view.AbstractView; - -import com.google.common.base.Strings; -import com.google.gson.ExclusionStrategy; -import com.google.gson.FieldAttributes; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import com.google.gson.LongSerializationPolicy; - -@Component(ResourceSetEntityView.VIEWNAME) -public class ResourceSetEntityView extends AbstractView { - private static Logger logger = LoggerFactory.getLogger(JsonEntityView.class); - - public static final String VIEWNAME = "resourceSetEntityView"; - - @Autowired - private ConfigurationPropertiesBean config; - - private Gson gson = new GsonBuilder() - .setExclusionStrategies(new ExclusionStrategy() { - - @Override - public boolean shouldSkipField(FieldAttributes f) { - - return false; - } - - @Override - public boolean shouldSkipClass(Class clazz) { - // skip the JPA binding wrapper - if (clazz.equals(BeanPropertyBindingResult.class)) { - return true; - } - return false; - } - - }) - .serializeNulls() - .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .setLongSerializationPolicy(LongSerializationPolicy.STRING) - .create(); - - @Override - protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) { - - response.setContentType("application/json"); - - - HttpStatus code = (HttpStatus) model.get("code"); - if (code == null) { - code = HttpStatus.OK; // default to 200 - } - - response.setStatus(code.value()); - - String location = (String) model.get("location"); - if (!Strings.isNullOrEmpty(location)) { - response.setHeader(HttpHeaders.LOCATION, location); - } - - try { - - Writer out = response.getWriter(); - ResourceSet rs = (ResourceSet) model.get("entity"); - - JsonObject o = new JsonObject(); - - o.addProperty("_id", rs.getId().toString()); // send the id as a string - o.addProperty("user_access_policy_uri", config.getIssuer() + "manage/resource/" + rs.getId()); - o.addProperty("name", rs.getName()); - o.addProperty("uri", rs.getUri()); - o.addProperty("type", rs.getType()); - o.add("scopes", JsonUtils.getAsArray(rs.getScopes())); - o.addProperty("icon_uri", rs.getIconUri()); - - gson.toJson(o, out); - - } catch (IOException e) { - - logger.error("IOException in ResourceSetEntityView.java: ", e); - - } - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/AuthorizationRequestEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/AuthorizationRequestEndpoint.java deleted file mode 100644 index 04f8378445..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/AuthorizationRequestEndpoint.java +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - -import java.util.Map; - -import org.mitre.oauth2.model.OAuth2AccessTokenEntity; -import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.oauth2.web.AuthenticationUtilities; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.mitre.uma.model.Claim; -import org.mitre.uma.model.ClaimProcessingResult; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ClaimsProcessingService; -import org.mitre.uma.service.PermissionService; -import org.mitre.uma.service.UmaTokenService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.common.collect.ImmutableMap; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; - -/** - * @author jricher - * - */ -@Controller -@RequestMapping("/" + AuthorizationRequestEndpoint.URL) -public class AuthorizationRequestEndpoint { - // Logger for this class - private static final Logger logger = LoggerFactory.getLogger(AuthorizationRequestEndpoint.class); - - public static final String RPT = "rpt"; - public static final String TICKET = "ticket"; - public static final String URL = "authz_request"; - - @Autowired - private PermissionService permissionService; - - @Autowired - private OAuth2TokenEntityService tokenService; - - @Autowired - private ClaimsProcessingService claimsProcessingService; - - @Autowired - private UmaTokenService umaTokenService; - - @RequestMapping(method = RequestMethod.POST, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String authorizationRequest(@RequestBody String jsonString, Model m, Authentication auth) { - - AuthenticationUtilities.ensureOAuthScope(auth, SystemScopeService.UMA_AUTHORIZATION_SCOPE); - - JsonParser parser = new JsonParser(); - JsonElement e = parser.parse(jsonString); - - if (e.isJsonObject()) { - JsonObject o = e.getAsJsonObject(); - - if (o.has(TICKET)) { - - OAuth2AccessTokenEntity incomingRpt = null; - if (o.has(RPT)) { - String rptValue = o.get(RPT).getAsString(); - incomingRpt = tokenService.readAccessToken(rptValue); - } - - String ticketValue = o.get(TICKET).getAsString(); - - PermissionTicket ticket = permissionService.getByTicket(ticketValue); - - if (ticket != null) { - // found the ticket, see if it's any good - - ResourceSet rs = ticket.getPermission().getResourceSet(); - - if (rs.getPolicies() == null || rs.getPolicies().isEmpty()) { - // the required claims are empty, this resource has no way to be authorized - - m.addAttribute(JsonErrorView.ERROR, "not_authorized"); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, "This resource set can not be accessed."); - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return JsonErrorView.VIEWNAME; - } else { - // claims weren't empty or missing, we need to check against what we have - - ClaimProcessingResult result = claimsProcessingService.claimsAreSatisfied(rs, ticket); - - - if (result.isSatisfied()) { - // the service found what it was looking for, issue a token - - // we need to downscope this based on the required set that was matched if it was matched - OAuth2Authentication o2auth = (OAuth2Authentication) auth; - - OAuth2AccessTokenEntity token = umaTokenService.createRequestingPartyToken(o2auth, ticket, result.getMatched()); - - // if we have an inbound RPT, throw it out because we're replacing it - if (incomingRpt != null) { - tokenService.revokeAccessToken(incomingRpt); - } - - Map entity = ImmutableMap.of("rpt", token.getValue()); - - m.addAttribute(JsonEntityView.ENTITY, entity); - - return JsonEntityView.VIEWNAME; - - } else { - - // if we got here, the claim didn't match, forward the user to the claim gathering endpoint - JsonObject entity = new JsonObject(); - - entity.addProperty(JsonErrorView.ERROR, "need_info"); - JsonObject details = new JsonObject(); - - JsonObject rpClaims = new JsonObject(); - rpClaims.addProperty("redirect_user", true); - rpClaims.addProperty("ticket", ticketValue); - JsonArray req = new JsonArray(); - for (Claim claim : result.getUnmatched()) { - JsonObject c = new JsonObject(); - c.addProperty("name", claim.getName()); - c.addProperty("friendly_name", claim.getFriendlyName()); - c.addProperty("claim_type", claim.getClaimType()); - JsonArray f = new JsonArray(); - for (String format : claim.getClaimTokenFormat()) { - f.add(new JsonPrimitive(format)); - } - c.add("claim_token_format", f); - JsonArray i = new JsonArray(); - for (String issuer : claim.getIssuer()) { - i.add(new JsonPrimitive(issuer)); - } - c.add("issuer", i); - req.add(c); - } - rpClaims.add("required_claims", req); - details.add("requesting_party_claims", rpClaims); - entity.add("error_details", details); - - m.addAttribute(JsonEntityView.ENTITY, entity); - return JsonEntityView.VIEWNAME; - } - - - } - } else { - // ticket wasn't found, return an error - m.addAttribute(HttpStatus.BAD_REQUEST); - m.addAttribute(JsonErrorView.ERROR, "invalid_ticket"); - return JsonErrorView.VIEWNAME; - } - - } else { - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Missing JSON elements."); - return JsonErrorView.VIEWNAME; - } - - - } else { - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Malformed JSON request."); - return JsonErrorView.VIEWNAME; - } - - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java deleted file mode 100644 index 52061e4ebf..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/ClaimsCollectionEndpoint.java +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - -import java.util.Set; - -import org.mitre.oauth2.model.ClientDetailsEntity; -import org.mitre.oauth2.service.ClientDetailsEntityService; -import org.mitre.openid.connect.model.OIDCAuthenticationToken; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.uma.model.Claim; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.service.PermissionService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.util.UriComponentsBuilder; - -import com.google.common.base.Strings; -import com.google.common.collect.Sets; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; - -/** - * - * Collect claims interactively from the end user. - * - * @author jricher - * - */ -@Controller -@PreAuthorize("hasRole('ROLE_EXTERNAL_USER')") -@RequestMapping("/" + ClaimsCollectionEndpoint.URL) -public class ClaimsCollectionEndpoint { - // Logger for this class - private static final Logger logger = LoggerFactory.getLogger(ClaimsCollectionEndpoint.class); - - public static final String URL = "rqp_claims"; - - @Autowired - private ClientDetailsEntityService clientService; - - @Autowired - private PermissionService permissionService; - - - @RequestMapping(method = RequestMethod.GET) - public String collectClaims(@RequestParam("client_id") String clientId, @RequestParam(value = "redirect_uri", required = false) String redirectUri, - @RequestParam("ticket") String ticketValue, @RequestParam(value = "state", required = false) String state, - Model m, OIDCAuthenticationToken auth) { - - - ClientDetailsEntity client = clientService.loadClientByClientId(clientId); - - PermissionTicket ticket = permissionService.getByTicket(ticketValue); - - if (client == null || ticket == null) { - logger.info("Client or ticket not found: " + clientId + " :: " + ticketValue); - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - // we've got a client and ticket, let's attach the claims that we have from the token and userinfo - - // subject - Set claimsSupplied = Sets.newHashSet(ticket.getClaimsSupplied()); - - String issuer = auth.getIssuer(); - UserInfo userInfo = auth.getUserInfo(); - - claimsSupplied.add(mkClaim(issuer, "sub", new JsonPrimitive(auth.getSub()))); - if (userInfo.getEmail() != null) { - claimsSupplied.add(mkClaim(issuer, "email", new JsonPrimitive(userInfo.getEmail()))); - } - if (userInfo.getEmailVerified() != null) { - claimsSupplied.add(mkClaim(issuer, "email_verified", new JsonPrimitive(userInfo.getEmailVerified()))); - } - if (userInfo.getPhoneNumber() != null) { - claimsSupplied.add(mkClaim(issuer, "phone_number", new JsonPrimitive(auth.getUserInfo().getPhoneNumber()))); - } - if (userInfo.getPhoneNumberVerified() != null) { - claimsSupplied.add(mkClaim(issuer, "phone_number_verified", new JsonPrimitive(auth.getUserInfo().getPhoneNumberVerified()))); - } - if (userInfo.getPreferredUsername() != null) { - claimsSupplied.add(mkClaim(issuer, "preferred_username", new JsonPrimitive(auth.getUserInfo().getPreferredUsername()))); - } - if (userInfo.getProfile() != null) { - claimsSupplied.add(mkClaim(issuer, "profile", new JsonPrimitive(auth.getUserInfo().getProfile()))); - } - - ticket.setClaimsSupplied(claimsSupplied); - - PermissionTicket updatedTicket = permissionService.updateTicket(ticket); - - if (Strings.isNullOrEmpty(redirectUri)) { - if (client.getClaimsRedirectUris().size() == 1) { - redirectUri = client.getClaimsRedirectUris().iterator().next(); // get the first (and only) redirect URI to use here - logger.info("No redirect URI passed in, using registered value: " + redirectUri); - } else { - throw new RedirectMismatchException("Unable to find redirect URI and none passed in."); - } - } else { - if (!client.getClaimsRedirectUris().contains(redirectUri)) { - throw new RedirectMismatchException("Claims redirect did not match the registered values."); - } - } - - UriComponentsBuilder template = UriComponentsBuilder.fromUriString(redirectUri); - template.queryParam("authorization_state", "claims_submitted"); - if (!Strings.isNullOrEmpty(state)) { - template.queryParam("state", state); - } - - String uriString = template.toUriString(); - logger.info("Redirecting to " + uriString); - - return "redirect:" + uriString; - } - - - private Claim mkClaim(String issuer, String name, JsonElement value) { - Claim c = new Claim(); - c.setIssuer(Sets.newHashSet(issuer)); - c.setName(name); - c.setValue(value); - return c; - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/PermissionRegistrationEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/PermissionRegistrationEndpoint.java deleted file mode 100644 index a3b6601294..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/PermissionRegistrationEndpoint.java +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - -import static org.mitre.oauth2.web.AuthenticationUtilities.ensureOAuthScope; -import static org.mitre.util.JsonUtils.getAsLong; -import static org.mitre.util.JsonUtils.getAsStringSet; - -import java.util.Set; - -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.PermissionService; -import org.mitre.uma.service.ResourceSetService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; - -/** - * @author jricher - * - */ -@Controller -@RequestMapping("/" + PermissionRegistrationEndpoint.URL) -@PreAuthorize("hasRole('ROLE_USER')") -public class PermissionRegistrationEndpoint { - // Logger for this class - private static final Logger logger = LoggerFactory.getLogger(PermissionRegistrationEndpoint.class); - - public static final String URL = "permission"; - - @Autowired - private PermissionService permissionService; - - @Autowired - private ResourceSetService resourceSetService; - - @Autowired - private SystemScopeService scopeService; - - private JsonParser parser = new JsonParser(); - - @RequestMapping(method = RequestMethod.POST, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String getPermissionTicket(@RequestBody String jsonString, Model m, Authentication auth) { - - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - try { - - // parse the permission request - - JsonElement el = parser.parse(jsonString); - if (el.isJsonObject()) { - JsonObject o = el.getAsJsonObject(); - - Long rsid = getAsLong(o, "resource_set_id"); - Set scopes = getAsStringSet(o, "scopes"); - - if (rsid == null || scopes == null || scopes.isEmpty()){ - // missing information - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Missing required component of permission registration request."); - return JsonErrorView.VIEWNAME; - } - - // trim any restricted scopes - Set scopesRequested = scopeService.fromStrings(scopes); - scopesRequested = scopeService.removeRestrictedAndReservedScopes(scopesRequested); - scopes = scopeService.toStrings(scopesRequested); - - ResourceSet resourceSet = resourceSetService.getById(rsid); - - // requested resource set doesn't exist - if (resourceSet == null) { - m.addAttribute("code", HttpStatus.NOT_FOUND); - m.addAttribute("errorMessage", "Requested resource set not found: " + rsid); - return JsonErrorView.VIEWNAME; - } - - // authorized user of the token doesn't match owner of the resource set - if (!resourceSet.getOwner().equals(auth.getName())) { - m.addAttribute("code", HttpStatus.FORBIDDEN); - m.addAttribute("errorMessage", "Party requesting permission is not owner of resource set, expected " + resourceSet.getOwner() + " got " + auth.getName()); - return JsonErrorView.VIEWNAME; - } - - // create the permission - PermissionTicket permission = permissionService.createTicket(resourceSet, scopes); - - if (permission != null) { - // we've created the permission, return the ticket - JsonObject out = new JsonObject(); - out.addProperty("ticket", permission.getTicket()); - m.addAttribute("entity", out); - - m.addAttribute("code", HttpStatus.CREATED); - - return JsonEntityView.VIEWNAME; - } else { - // there was a failure creating the permission object - - m.addAttribute("code", HttpStatus.INTERNAL_SERVER_ERROR); - m.addAttribute("errorMessage", "Unable to save permission and generate ticket."); - - return JsonErrorView.VIEWNAME; - } - - } else { - // malformed request - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Malformed JSON request."); - return JsonErrorView.VIEWNAME; - } - } catch (JsonParseException e) { - // malformed request - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("errorMessage", "Malformed JSON request."); - return JsonErrorView.VIEWNAME; - } - - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/PolicyAPI.java b/uma-server/src/main/java/org/mitre/uma/web/PolicyAPI.java deleted file mode 100644 index 2b1feda583..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/PolicyAPI.java +++ /dev/null @@ -1,391 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.mitre.openid.connect.web.RootController; -import org.mitre.uma.model.Claim; -import org.mitre.uma.model.Policy; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ResourceSetService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.common.collect.Sets; -import com.google.gson.Gson; - -/** - * API for managing policies on resource sets. - * - * @author jricher - * - */ -@Controller -@RequestMapping("/" + PolicyAPI.URL) -@PreAuthorize("hasRole('ROLE_USER')") -public class PolicyAPI { - - // Logger for this class - private static final Logger logger = LoggerFactory.getLogger(PolicyAPI.class); - - public static final String URL = RootController.API_URL + "/resourceset"; - public static final String POLICYURL = "/policy"; - - private Gson gson = new Gson(); - - @Autowired - private ResourceSetService resourceSetService; - - /** - * List all resource sets for the current user - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String getResourceSetsForCurrentUser(Model m, Authentication auth) { - - Collection resourceSets = resourceSetService.getAllForOwner(auth.getName()); - - m.addAttribute(JsonEntityView.ENTITY, resourceSets); - - return JsonEntityView.VIEWNAME; - } - - /** - * Get the indicated resource set - * @param rsid - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String getResourceSet(@PathVariable (value = "rsid") Long rsid, Model m, Authentication auth) { - - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (!rs.getOwner().equals(auth.getName())) { - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // authenticated user didn't match the owner of the resource set - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - m.addAttribute(JsonEntityView.ENTITY, rs); - - return JsonEntityView.VIEWNAME; - } - - /** - * Delete the indicated resource set - * @param rsid - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}", method = RequestMethod.DELETE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String deleteResourceSet(@PathVariable (value = "rsid") Long rsid, Model m, Authentication auth) { - - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (!rs.getOwner().equals(auth.getName())) { - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // authenticated user didn't match the owner of the resource set - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - resourceSetService.remove(rs); - m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT); - return HttpCodeView.VIEWNAME; - - } - - /** - * List all the policies for the given resource set - * @param rsid - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}" + POLICYURL, method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String getPoliciesForResourceSet(@PathVariable (value = "rsid") Long rsid, Model m, Authentication auth) { - - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (!rs.getOwner().equals(auth.getName())) { - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // authenticated user didn't match the owner of the resource set - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - m.addAttribute(JsonEntityView.ENTITY, rs.getPolicies()); - - return JsonEntityView.VIEWNAME; - } - - /** - * Create a new policy on the given resource set - * @param rsid - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}" + POLICYURL, method = RequestMethod.POST, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String createNewPolicyForResourceSet(@PathVariable (value = "rsid") Long rsid, @RequestBody String jsonString, Model m, Authentication auth) { - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (!rs.getOwner().equals(auth.getName())) { - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // authenticated user didn't match the owner of the resource set - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - Policy p = gson.fromJson(jsonString, Policy.class); - - if (p.getId() != null) { - logger.warn("Tried to add a policy with a non-null ID: " + p.getId()); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - return HttpCodeView.VIEWNAME; - } - - for (Claim claim : p.getClaimsRequired()) { - if (claim.getId() != null) { - logger.warn("Tried to add a policy with a non-null claim ID: " + claim.getId()); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - return HttpCodeView.VIEWNAME; - } - } - - rs.getPolicies().add(p); - ResourceSet saved = resourceSetService.update(rs, rs); - - // find the new policy object - Collection newPolicies = Sets.difference(new HashSet<>(saved.getPolicies()), new HashSet<>(rs.getPolicies())); - - if (newPolicies.size() == 1) { - Policy newPolicy = newPolicies.iterator().next(); - m.addAttribute(JsonEntityView.ENTITY, newPolicy); - return JsonEntityView.VIEWNAME; - } else { - logger.warn("Unexpected result trying to add a new policy object: " + newPolicies); - m.addAttribute(HttpCodeView.CODE, HttpStatus.INTERNAL_SERVER_ERROR); - return HttpCodeView.VIEWNAME; - } - - } - - /** - * Get a specific policy - * @param rsid - * @param pid - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}" + POLICYURL + "/{pid}", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String getPolicy(@PathVariable (value = "rsid") Long rsid, @PathVariable (value = "pid") Long pid, Model m, Authentication auth) { - - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (!rs.getOwner().equals(auth.getName())) { - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // authenticated user didn't match the owner of the resource set - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - for (Policy policy : rs.getPolicies()) { - if (policy.getId().equals(pid)) { - // found it! - m.addAttribute(JsonEntityView.ENTITY, policy); - return JsonEntityView.VIEWNAME; - } - } - - // if we made it this far, we haven't found it - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - /** - * Update a specific policy - * @param rsid - * @param pid - * @param jsonString - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}" + POLICYURL + "/{pid}", method = RequestMethod.PUT, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String setClaimsForResourceSet(@PathVariable (value = "rsid") Long rsid, @PathVariable (value = "pid") Long pid, @RequestBody String jsonString, Model m, Authentication auth) { - - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - if (!rs.getOwner().equals(auth.getName())) { - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // authenticated user didn't match the owner of the resource set - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return HttpCodeView.VIEWNAME; - } - - Policy p = gson.fromJson(jsonString, Policy.class); - - if (!pid.equals(p.getId())) { - logger.warn("Policy ID mismatch, expected " + pid + " got " + p.getId()); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - return HttpCodeView.VIEWNAME; - } - - for (Policy policy : rs.getPolicies()) { - if (policy.getId().equals(pid)) { - // found it! - - // find the existing claim IDs, make sure we're not overwriting anything from another policy - Set claimIds = new HashSet<>(); - for (Claim claim : policy.getClaimsRequired()) { - claimIds.add(claim.getId()); - } - - for (Claim claim : p.getClaimsRequired()) { - if (claim.getId() != null && !claimIds.contains(claim.getId())) { - logger.warn("Tried to add a policy with a an unmatched claim ID: got " + claim.getId() + " expected " + claimIds); - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - return HttpCodeView.VIEWNAME; - } - } - - // update the existing object with the new values - policy.setClaimsRequired(p.getClaimsRequired()); - policy.setName(p.getName()); - policy.setScopes(p.getScopes()); - - resourceSetService.update(rs, rs); - - m.addAttribute(JsonEntityView.ENTITY, policy); - return JsonEntityView.VIEWNAME; - } - } - - // if we made it this far, we haven't found it - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - } - - /** - * Delete a specific policy - * @param rsid - * @param pid - * @param m - * @param auth - * @return - */ - @RequestMapping(value = "/{rsid}" + POLICYURL + "/{pid}", method = RequestMethod.DELETE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String deleteResourceSet(@PathVariable ("rsid") Long rsid, @PathVariable (value = "pid") Long pid, Model m, Authentication auth) { - - ResourceSet rs = resourceSetService.getById(rsid); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.addAttribute(JsonErrorView.ERROR, "not_found"); - return JsonErrorView.VIEWNAME; - } - - if (!auth.getName().equals(rs.getOwner())) { - - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // it wasn't issued to this user - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return JsonErrorView.VIEWNAME; - } - - - for (Policy policy : rs.getPolicies()) { - if (policy.getId().equals(pid)) { - // found it! - rs.getPolicies().remove(policy); - resourceSetService.update(rs, rs); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT); - return HttpCodeView.VIEWNAME; - } - } - - // if we made it this far, we haven't found it - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return HttpCodeView.VIEWNAME; - - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/ResourceSetRegistrationEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/ResourceSetRegistrationEndpoint.java deleted file mode 100644 index ce10568fba..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/ResourceSetRegistrationEndpoint.java +++ /dev/null @@ -1,317 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - - -import static org.mitre.oauth2.web.AuthenticationUtilities.ensureOAuthScope; -import static org.mitre.util.JsonUtils.getAsLong; -import static org.mitre.util.JsonUtils.getAsString; -import static org.mitre.util.JsonUtils.getAsStringSet; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.mitre.oauth2.model.SystemScope; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.service.ResourceSetService; -import org.mitre.uma.view.ResourceSetEntityAbbreviatedView; -import org.mitre.uma.view.ResourceSetEntityView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.Authentication; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import com.google.common.base.Strings; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; - -@Controller -@RequestMapping("/" + ResourceSetRegistrationEndpoint.URL) -@PreAuthorize("hasRole('ROLE_USER')") -public class ResourceSetRegistrationEndpoint { - - private static final Logger logger = LoggerFactory.getLogger(ResourceSetRegistrationEndpoint.class); - - public static final String DISCOVERY_URL = "resource_set"; - public static final String URL = DISCOVERY_URL + "/resource_set"; - - @Autowired - private ResourceSetService resourceSetService; - - @Autowired - private ConfigurationPropertiesBean config; - - @Autowired - private SystemScopeService scopeService; - - private JsonParser parser = new JsonParser(); - - @RequestMapping(method = RequestMethod.POST, produces = MimeTypeUtils.APPLICATION_JSON_VALUE, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String createResourceSet(@RequestBody String jsonString, Model m, Authentication auth) { - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - ResourceSet rs = parseResourceSet(jsonString); - - if (rs == null) { // there was no resource set in the body - logger.warn("Resource set registration missing body."); - - m.addAttribute("code", HttpStatus.BAD_REQUEST); - m.addAttribute("error_description", "Resource request was missing body."); - return JsonErrorView.VIEWNAME; - } - - if (auth instanceof OAuth2Authentication) { - // if it's an OAuth mediated call, it's on behalf of a client, so store that - OAuth2Authentication o2a = (OAuth2Authentication) auth; - rs.setClientId(o2a.getOAuth2Request().getClientId()); - rs.setOwner(auth.getName()); // the username is going to be in the auth object - } else { - // this one shouldn't be called if it's not OAuth - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, "This call must be made with an OAuth token"); - return JsonErrorView.VIEWNAME; - } - - rs = validateScopes(rs); - - if (Strings.isNullOrEmpty(rs.getName()) // there was no name (required) - || rs.getScopes() == null // there were no scopes (required) - ) { - - logger.warn("Resource set registration missing one or more required fields."); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Resource request was missing one or more required fields."); - return JsonErrorView.VIEWNAME; - } - - ResourceSet saved = resourceSetService.saveNew(rs); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.CREATED); - m.addAttribute(JsonEntityView.ENTITY, saved); - m.addAttribute(ResourceSetEntityAbbreviatedView.LOCATION, config.getIssuer() + URL + "/" + saved.getId()); - - return ResourceSetEntityAbbreviatedView.VIEWNAME; - - } - - @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String readResourceSet(@PathVariable ("id") Long id, Model m, Authentication auth) { - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - ResourceSet rs = resourceSetService.getById(id); - - if (rs == null) { - m.addAttribute("code", HttpStatus.NOT_FOUND); - m.addAttribute("error", "not_found"); - return JsonErrorView.VIEWNAME; - } else { - - rs = validateScopes(rs); - - if (!auth.getName().equals(rs.getOwner())) { - - logger.warn("Unauthorized resource set request from wrong user; expected " + rs.getOwner() + " got " + auth.getName()); - - // it wasn't issued to this user - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return JsonErrorView.VIEWNAME; - } else { - m.addAttribute(JsonEntityView.ENTITY, rs); - return ResourceSetEntityView.VIEWNAME; - } - - } - - } - - @RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String updateResourceSet(@PathVariable ("id") Long id, @RequestBody String jsonString, Model m, Authentication auth) { - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - ResourceSet newRs = parseResourceSet(jsonString); - - if (newRs == null // there was no resource set in the body - || Strings.isNullOrEmpty(newRs.getName()) // there was no name (required) - || newRs.getScopes() == null // there were no scopes (required) - || newRs.getId() == null || !newRs.getId().equals(id) // the IDs didn't match - ) { - - logger.warn("Resource set registration missing one or more required fields."); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); - m.addAttribute(JsonErrorView.ERROR_MESSAGE, "Resource request was missing one or more required fields."); - return JsonErrorView.VIEWNAME; - } - - ResourceSet rs = resourceSetService.getById(id); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.addAttribute(JsonErrorView.ERROR, "not_found"); - return JsonErrorView.VIEWNAME; - } else { - if (!auth.getName().equals(rs.getOwner())) { - - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // it wasn't issued to this user - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return JsonErrorView.VIEWNAME; - } else { - - ResourceSet saved = resourceSetService.update(rs, newRs); - - m.addAttribute(JsonEntityView.ENTITY, saved); - m.addAttribute(ResourceSetEntityAbbreviatedView.LOCATION, config.getIssuer() + URL + "/" + rs.getId()); - return ResourceSetEntityAbbreviatedView.VIEWNAME; - } - - } - } - - @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String deleteResourceSet(@PathVariable ("id") Long id, Model m, Authentication auth) { - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - ResourceSet rs = resourceSetService.getById(id); - - if (rs == null) { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - m.addAttribute(JsonErrorView.ERROR, "not_found"); - return JsonErrorView.VIEWNAME; - } else { - if (!auth.getName().equals(rs.getOwner())) { - - logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName()); - - // it wasn't issued to this user - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return JsonErrorView.VIEWNAME; - } else if (auth instanceof OAuth2Authentication && - !((OAuth2Authentication)auth).getOAuth2Request().getClientId().equals(rs.getClientId())){ - - logger.warn("Unauthorized resource set request from bad client; expected " + rs.getClientId() + " got " + ((OAuth2Authentication)auth).getOAuth2Request().getClientId()); - - // it wasn't issued to this client - m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN); - return JsonErrorView.VIEWNAME; - } else { - - // user and client matched - resourceSetService.remove(rs); - - m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT); - return HttpCodeView.VIEWNAME; - } - - } - } - - @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String listResourceSets(Model m, Authentication auth) { - ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE); - - String owner = auth.getName(); - - Collection resourceSets = Collections.emptySet(); - if (auth instanceof OAuth2Authentication) { - // if it's an OAuth mediated call, it's on behalf of a client, so look that up too - OAuth2Authentication o2a = (OAuth2Authentication) auth; - resourceSets = resourceSetService.getAllForOwnerAndClient(owner, o2a.getOAuth2Request().getClientId()); - } else { - // otherwise get everything for the current user - resourceSets = resourceSetService.getAllForOwner(owner); - } - - // build the entity here and send to the display - - Set ids = new HashSet<>(); - for (ResourceSet resourceSet : resourceSets) { - ids.add(resourceSet.getId().toString()); // add them all as strings so that gson renders them properly - } - - m.addAttribute(JsonEntityView.ENTITY, ids); - return JsonEntityView.VIEWNAME; - } - - private ResourceSet parseResourceSet(String jsonString) { - - try { - JsonElement el = parser.parse(jsonString); - - if (el.isJsonObject()) { - JsonObject o = el.getAsJsonObject(); - - ResourceSet rs = new ResourceSet(); - rs.setId(getAsLong(o, "_id")); - rs.setName(getAsString(o, "name")); - rs.setIconUri(getAsString(o, "icon_uri")); - rs.setType(getAsString(o, "type")); - rs.setScopes(getAsStringSet(o, "scopes")); - rs.setUri(getAsString(o, "uri")); - - return rs; - - } - - return null; - - } catch (JsonParseException e) { - return null; - } - - } - - - /** - * - * Make sure the resource set doesn't have any restricted or reserved scopes. - * - * @param rs - */ - private ResourceSet validateScopes(ResourceSet rs) { - // scopes that the client is asking for - Set requestedScopes = scopeService.fromStrings(rs.getScopes()); - - // the scopes that the resource set can have must be a subset of the dynamically allowed scopes - Set allowedScopes = scopeService.removeRestrictedAndReservedScopes(requestedScopes); - - rs.setScopes(scopeService.toStrings(allowedScopes)); - - return rs; - } - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java b/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java deleted file mode 100644 index 6dc8717adb..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/UmaDiscoveryEndpoint.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.mitre.oauth2.web.IntrospectionEndpoint; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.web.DynamicClientRegistrationEndpoint; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; - -/** - * @author jricher - * - */ -@Controller -public class UmaDiscoveryEndpoint { - - @Autowired - private ConfigurationPropertiesBean config; - - @RequestMapping(".well-known/uma-configuration") - public String umaConfiguration(Model model) { - - Map m = new HashMap<>(); - - String issuer = config.getIssuer(); - ImmutableSet tokenProfiles = ImmutableSet.of("bearer"); - ArrayList grantTypes = Lists.newArrayList("authorization_code", "implicit", "urn:ietf:params:oauth:grant-type:jwt-bearer", "client_credentials", "urn:ietf:params:oauth:grant_type:redelegate"); - - m.put("version", "1.0"); - m.put("issuer", issuer); - m.put("pat_profiles_supported", tokenProfiles); - m.put("aat_profiles_supported", tokenProfiles); - m.put("rpt_profiles_supported", tokenProfiles); - m.put("pat_grant_types_supported", grantTypes); - m.put("aat_grant_types_supported", grantTypes); - m.put("claim_token_profiles_supported", ImmutableSet.of()); - m.put("uma_profiles_supported", ImmutableSet.of()); - m.put("dynamic_client_endpoint", issuer + DynamicClientRegistrationEndpoint.URL); - m.put("token_endpoint", issuer + "token"); - m.put("authorization_endpoint", issuer + "authorize"); - m.put("requesting_party_claims_endpoint", issuer + ClaimsCollectionEndpoint.URL); - m.put("introspection_endpoint", issuer + IntrospectionEndpoint.URL); - m.put("resource_set_registration_endpoint", issuer + ResourceSetRegistrationEndpoint.DISCOVERY_URL); - m.put("permission_registration_endpoint", issuer + PermissionRegistrationEndpoint.URL); - m.put("rpt_endpoint", issuer + AuthorizationRequestEndpoint.URL); - - - - model.addAttribute("entity", m); - return JsonEntityView.VIEWNAME; - } - - -} diff --git a/uma-server/src/main/java/org/mitre/uma/web/UserClaimSearchHelper.java b/uma-server/src/main/java/org/mitre/uma/web/UserClaimSearchHelper.java deleted file mode 100644 index 3773264707..0000000000 --- a/uma-server/src/main/java/org/mitre/uma/web/UserClaimSearchHelper.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.web; - -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import org.mitre.openid.connect.client.model.IssuerServiceResponse; -import org.mitre.openid.connect.client.service.impl.WebfingerIssuerService; -import org.mitre.openid.connect.config.ConfigurationPropertiesBean; -import org.mitre.openid.connect.model.UserInfo; -import org.mitre.openid.connect.service.UserInfoService; -import org.mitre.openid.connect.view.HttpCodeView; -import org.mitre.openid.connect.view.JsonEntityView; -import org.mitre.openid.connect.view.JsonErrorView; -import org.mitre.openid.connect.web.RootController; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.util.MimeTypeUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -import com.google.common.collect.ImmutableSet; - - -/** - * @author jricher - * - */ -@Controller -@RequestMapping("/" + UserClaimSearchHelper.URL) -@PreAuthorize("hasRole('ROLE_USER')") -public class UserClaimSearchHelper { - - public static final String URL = RootController.API_URL + "/emailsearch"; - - private WebfingerIssuerService webfingerIssuerService = new WebfingerIssuerService(); - - @Autowired - private UserInfoService userInfoService; - - @Autowired - private ConfigurationPropertiesBean config; - - - @RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE) - public String search(@RequestParam(value = "identifier") String email, Model m, Authentication auth, HttpServletRequest req) { - - // check locally first - UserInfo localUser = userInfoService.getByEmailAddress(email); - - if (localUser != null) { - Map e = new HashMap<>(); - e.put("issuer", ImmutableSet.of(config.getIssuer())); - e.put("name", "email"); - e.put("value", localUser.getEmail()); - - Map ev = new HashMap<>(); - ev.put("issuer", ImmutableSet.of(config.getIssuer())); - ev.put("name", "email_verified"); - ev.put("value", localUser.getEmailVerified()); - - Map s = new HashMap<>(); - s.put("issuer", ImmutableSet.of(config.getIssuer())); - s.put("name", "sub"); - s.put("value", localUser.getSub()); - - m.addAttribute(JsonEntityView.ENTITY, ImmutableSet.of(e, ev, s)); - return JsonEntityView.VIEWNAME; - } else { - - // otherwise do a webfinger lookup - IssuerServiceResponse resp = webfingerIssuerService.getIssuer(req); - - if (resp != null && resp.getIssuer() != null) { - // we found an issuer, return that - Map e = new HashMap<>(); - e.put("issuer", ImmutableSet.of(resp.getIssuer())); - e.put("name", "email"); - e.put("value", email); - - Map ev = new HashMap<>(); - ev.put("issuer", ImmutableSet.of(resp.getIssuer())); - ev.put("name", "email_verified"); - ev.put("value", true); - - m.addAttribute(JsonEntityView.ENTITY, ImmutableSet.of(e, ev)); - return JsonEntityView.VIEWNAME; - } else { - m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND); - return JsonErrorView.VIEWNAME; - } - } - } - -} diff --git a/uma-server/src/test/java/META-INF/MANIFEST.MF b/uma-server/src/test/java/META-INF/MANIFEST.MF deleted file mode 100644 index 254272e1c0..0000000000 --- a/uma-server/src/test/java/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Class-Path: - diff --git a/uma-server/src/test/java/org/mitre/uma/service/impl/TestDefaultPermissionService.java b/uma-server/src/test/java/org/mitre/uma/service/impl/TestDefaultPermissionService.java deleted file mode 100644 index 0a2063cb3e..0000000000 --- a/uma-server/src/test/java/org/mitre/uma/service/impl/TestDefaultPermissionService.java +++ /dev/null @@ -1,173 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import static org.mockito.Matchers.anySetOf; - -import java.util.Set; -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.oauth2.service.SystemScopeService; -import org.mitre.uma.model.PermissionTicket; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.repository.PermissionRepository; -import org.mockito.AdditionalAnswers; -import org.mockito.InjectMocks; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException; - -import com.google.common.collect.ImmutableSet; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.not; - -import static org.mockito.Mockito.when; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -/** - * @author jricher - * - */ -@RunWith(MockitoJUnitRunner.class) -public class TestDefaultPermissionService { - - @Mock - private PermissionRepository permissionRepository; - - @Mock - private SystemScopeService scopeService; - - @InjectMocks - private DefaultPermissionService permissionService; - - private Set scopes1 = ImmutableSet.of("foo", "bar", "baz"); - private Set scopes2 = ImmutableSet.of("alpha", "beta", "betest"); - - private ResourceSet rs1; - private ResourceSet rs2; - - private String rs1Name = "resource set 1"; - private String rs1Owner = "resource set owner 1"; - private Long rs1Id = 1L; - - private String rs2Name = "resource set 2"; - private String rs2Owner = "resource set owner 2"; - private Long rs2Id = 2L; - - - @Before - public void prepare() { - rs1 = new ResourceSet(); - rs1.setName(rs1Name); - rs1.setOwner(rs1Owner); - rs1.setId(rs1Id ); - rs1.setScopes(scopes1); - - rs2 = new ResourceSet(); - rs2.setName(rs2Name); - rs2.setOwner(rs2Owner); - rs2.setId(rs2Id); - rs2.setScopes(scopes2); - - // have the repository just pass the argument through - when(permissionRepository.save(Matchers.any(PermissionTicket.class))).then(AdditionalAnswers.returnsFirstArg()); - - when(scopeService.scopesMatch(anySetOf(String.class), anySetOf(String.class))).then(new Answer() { - - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - Object[] arguments = invocation.getArguments(); - @SuppressWarnings("unchecked") - Set expected = (Set) arguments[0]; - @SuppressWarnings("unchecked") - Set actual = (Set) arguments[1]; - - return expected.containsAll(actual); - } - }); - - } - - - /** - * Test method for {@link org.mitre.uma.service.impl.DefaultPermissionService#createTicket(org.mitre.uma.model.ResourceSet, java.util.Set)}. - */ - @Test - public void testCreate_ticket() { - - PermissionTicket perm = permissionService.createTicket(rs1, scopes1); - - // we want there to be a non-null ticket - assertNotNull(perm.getTicket()); - } - - @Test - public void testCreate_uuid() { - PermissionTicket perm = permissionService.createTicket(rs1, scopes1); - - // we expect this to be a UUID - UUID uuid = UUID.fromString(perm.getTicket()); - - assertNotNull(uuid); - - } - - @Test - public void testCreate_differentTicketsSameClient() { - - PermissionTicket perm1 = permissionService.createTicket(rs1, scopes1); - PermissionTicket perm2 = permissionService.createTicket(rs1, scopes1); - - assertNotNull(perm1.getTicket()); - assertNotNull(perm2.getTicket()); - - // make sure these are different from each other - assertThat(perm1.getTicket(), not(equalTo(perm2.getTicket()))); - - } - - @Test - public void testCreate_differentTicketsDifferentClient() { - - PermissionTicket perm1 = permissionService.createTicket(rs1, scopes1); - PermissionTicket perm2 = permissionService.createTicket(rs2, scopes2); - - assertNotNull(perm1.getTicket()); - assertNotNull(perm2.getTicket()); - - // make sure these are different from each other - assertThat(perm1.getTicket(), not(equalTo(perm2.getTicket()))); - - } - - @Test(expected = InsufficientScopeException.class) - public void testCreate_scopeMismatch() { - @SuppressWarnings("unused") - // try to get scopes outside of what we're allowed to do, this should throw an exception - PermissionTicket perm = permissionService.createTicket(rs1, scopes2); - } - -} diff --git a/uma-server/src/test/java/org/mitre/uma/service/impl/TestDefaultResourceSetService.java b/uma-server/src/test/java/org/mitre/uma/service/impl/TestDefaultResourceSetService.java deleted file mode 100644 index 52ca091be8..0000000000 --- a/uma-server/src/test/java/org/mitre/uma/service/impl/TestDefaultResourceSetService.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright 2018 The MIT Internet Trust Consortium - * - * 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.mitre.uma.service.impl; - -import static org.mockito.Matchers.any; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mitre.uma.model.ResourceSet; -import org.mitre.uma.repository.ResourceSetRepository; -import org.mockito.AdditionalAnswers; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import static org.mockito.Mockito.when; - -/** - * @author jricher - * - */ -@RunWith(MockitoJUnitRunner.class) -public class TestDefaultResourceSetService { - - @Mock - private ResourceSetRepository repository; - - @InjectMocks - private DefaultResourceSetService resourceSetService; - - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - - when(repository.save(any(ResourceSet.class))).then(AdditionalAnswers.returnsFirstArg()); - - } - - /** - * Test method for {@link org.mitre.uma.service.impl.DefaultResourceSetService#saveNew(org.mitre.uma.model.ResourceSet)}. - */ - @Test(expected = IllegalArgumentException.class) - public void testSaveNew_hasId() { - - ResourceSet rs = new ResourceSet(); - rs.setId(1L); - - resourceSetService.saveNew(rs); - - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdate_nullId() { - ResourceSet rs = new ResourceSet(); - rs.setId(1L); - - ResourceSet rs2 = new ResourceSet(); - - resourceSetService.update(rs, rs2); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdate_nullId2() { - ResourceSet rs = new ResourceSet(); - - ResourceSet rs2 = new ResourceSet(); - rs2.setId(1L); - - resourceSetService.update(rs, rs2); - } - - @Test(expected = IllegalArgumentException.class) - public void testUpdate_mismatchedIds() { - ResourceSet rs = new ResourceSet(); - rs.setId(1L); - - ResourceSet rs2 = new ResourceSet(); - rs2.setId(2L); - - resourceSetService.update(rs, rs2); - - } - -}