Did a lot of cleanup; untested but compiles

pull/165/merge
Amanda Anganes 2012-08-06 14:33:16 -04:00
parent ae44bd5e0c
commit 5fb67ab7bb
14 changed files with 92 additions and 316 deletions

View File

@ -34,14 +34,12 @@ import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.Transient;
import org.mitre.oauth2.model.ClientDetailsEntity;
@Entity
@Table(name="approvedsite")
@NamedQueries({
@NamedQuery(name = "ApprovedSite.getAll", query = "select a from ApprovedSite a"),
@NamedQuery(name = "ApprovedSite.getByUserId", query = "select a from ApprovedSite a where a.userId = :userId"),
@NamedQuery(name = "ApprovedSite.getByClientDetails", query = "select a from ApprovedSite a where a.clientDetails = :clientDetails")
@NamedQuery(name = "ApprovedSite.getByClientIdAndUserId", query = "select a from ApprovedSite a where a.clientId = :clientId and a.userId = :userId")
})
public class ApprovedSite {
@ -52,7 +50,7 @@ public class ApprovedSite {
private String userId;
// which OAuth2 client is this tied to
private ClientDetailsEntity clientDetails;
private String clientId;
// when was this first approved?
private Date creationDate;
@ -111,19 +109,18 @@ public class ApprovedSite {
}
/**
* @return the clientDetails
* @return the clientId
*/
@ManyToOne
@JoinColumn(name="clientdetails_id")
public ClientDetailsEntity getClientDetails() {
return clientDetails;
@Basic
public String getClientId() {
return clientId;
}
/**
* @param clientDetails the clientDetails to set
* @param clientId the clientId to set
*/
public void setClientDetails(ClientDetailsEntity clientDetails) {
this.clientDetails = clientDetails;
public void setClientId(String clientId) {
this.clientId = clientId;
}
/**

View File

@ -26,13 +26,10 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
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 org.mitre.oauth2.model.ClientDetailsEntity;
/**
* Indicator that login to a site should be automatically granted
* without user interaction.
@ -43,7 +40,7 @@ import org.mitre.oauth2.model.ClientDetailsEntity;
@Table(name="whitelistedsite")
@NamedQueries({
@NamedQuery(name = "WhitelistedSite.getAll", query = "select w from WhitelistedSite w"),
@NamedQuery(name = "WhitelistedSite.getByClientDetails", query = "select w from WhitelistedSite w where w.clientDetails = :clientDetails"),
@NamedQuery(name = "WhitelistedSite.getByClientId", query = "select w from WhitelistedSite w where w.clientId = :clientId"),
@NamedQuery(name = "WhitelistedSite.getByCreatoruserId", query = "select w from WhitelistedSite w where w.creatorUserId = :userId")
})
public class WhitelistedSite {
@ -55,7 +52,7 @@ public class WhitelistedSite {
private String creatorUserId;
// which OAuth2 client is this tied to
private ClientDetailsEntity clientDetails;
private String clientId;
// what scopes be allowed by default
// this should include all information for what data to access
@ -85,19 +82,18 @@ public class WhitelistedSite {
}
/**
* @return the clientDetails
* @return the clientId
*/
@ManyToOne
@JoinColumn(name="clientdetails_id")
public ClientDetailsEntity getClientDetails() {
return clientDetails;
@Basic
public String getClientId() {
return clientId;
}
/**
* @param clientDetails the clientDetails to set
* @param clientId the clientId to set
*/
public void setClientDetails(ClientDetailsEntity clientDetails) {
this.clientDetails = clientDetails;
public void setClientId(String clientId) {
this.clientId = clientId;
}
/**

View File

@ -17,13 +17,12 @@ package org.mitre.openid.connect.repository;
import java.util.Collection;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.openid.connect.model.ApprovedSite;
/**
* ApprovedSite repository interface
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
public interface ApprovedSiteRepository {
@ -46,22 +45,13 @@ public interface ApprovedSiteRepository {
/**
* Return a collection of ApprovedSite managed by this repository matching the
* provided ClientDetailsEntity
* provided client ID and user ID
*
* @param clientId
* @param userId
* @return
*/
public Collection<ApprovedSite> getByClientDetails(
ClientDetailsEntity clientDetails);
/**
* Return a collection of ApprovedSite managed by this repository matching the
* provided user id
*
* @param userId
* @return
*/
public Collection<ApprovedSite> getByUserId(String userId);
*/
public ApprovedSite getByClientIdAndUserId(String clientId, String userId);
/**
* Removes the given ApprovedSite from the repository

View File

@ -18,12 +18,11 @@ package org.mitre.openid.connect.repository;
import java.util.Collection;
import org.mitre.openid.connect.model.WhitelistedSite;
import org.springframework.security.oauth2.provider.ClientDetails;
/**
* WhitelistedSite repository interface
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
public interface WhitelistedSiteRepository {
@ -50,7 +49,7 @@ public interface WhitelistedSiteRepository {
* @param client the Relying Party
* @return the corresponding WhitelistedSite if one exists for the RP, or null
*/
public WhitelistedSite getByClientDetails(ClientDetails client);
public WhitelistedSite getByClientId(String clientId);
/**
* Return a collection of the WhitelistedSites created by a given user

View File

@ -16,19 +16,23 @@
package org.mitre.openid.connect.service;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.openid.connect.model.ApprovedSite;
import org.mitre.openid.connect.model.WhitelistedSite;
/**
* Interface for ApprovedSite service
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
public interface ApprovedSiteService {
public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes, WhitelistedSite whitelistedSite);
/**
* Return a collection of all ApprovedSites
*
@ -38,21 +42,13 @@ public interface ApprovedSiteService {
/**
* Return a collection of ApprovedSite managed by this repository matching the
* provided ClientDetailsEntity
* provided client ID and user ID
*
* @param clientId
* @param userId
* @return
*/
public Collection<ApprovedSite> getByClientDetails(ClientDetailsEntity clientDetails);
/**
* Return a collection of ApprovedSite managed by this repository matching the
* provided UserInfo
*
* @param userId
* @return
*/
public Collection<ApprovedSite> getByUserId(String userId);
public ApprovedSite getByClientIdAndUserId(String clientId, String userId);
/**
* Save an ApprovedSite
@ -60,7 +56,7 @@ public interface ApprovedSiteService {
* @param approvedSite
* the ApprovedSite to be saved
*/
public void save(ApprovedSite approvedSite);
public ApprovedSite save(ApprovedSite approvedSite);
/**
* Get ApprovedSite for id

View File

@ -18,12 +18,11 @@ package org.mitre.openid.connect.service;
import java.util.Collection;
import org.mitre.openid.connect.model.WhitelistedSite;
import org.springframework.security.oauth2.provider.ClientDetails;
/**
* Interface for WhitelistedSite service
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
public interface WhitelistedSiteService {
@ -50,7 +49,7 @@ public interface WhitelistedSiteService {
* @param client the Relying Party
* @return the corresponding WhitelistedSite if one exists for the RP, or null
*/
public WhitelistedSite getByClientDetails(ClientDetails client);
public WhitelistedSite getByClientId(String clientId);
/**
* Return a collection of the WhitelistedSites created by a given user

View File

@ -1,7 +1,7 @@
CREATE TABLE approvedsite (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
userId VARCHAR(256),
clientdetails_id VARCHAR(256),
clientId VARCHAR(256),
creationDate DATE,
accessDate DATE,
timeoutDate DATE,

View File

@ -1,5 +1,5 @@
CREATE TABLE whitelistedsite (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
creatorUserId VARCHAR(256),
clientdetails_id VARCHAR(256)
clientId VARCHAR(256)
);

View File

@ -18,22 +18,21 @@ package org.mitre.openid.connect.repository.impl;
import static org.mitre.util.jpa.JpaUtil.saveOrUpdate;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.openid.connect.model.ApprovedSite;
import org.mitre.openid.connect.repository.ApprovedSiteRepository;
import org.mitre.util.jpa.JpaUtil;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* JPA ApprovedSite repository implementation
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
@Repository
@ -49,20 +48,6 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
"ApprovedSite.getAll", ApprovedSite.class);
return query.getResultList();
}
@Override
@Transactional
public Collection<ApprovedSite> getByClientDetails(
ClientDetailsEntity clientDetails) {
TypedQuery<ApprovedSite> query = manager.createNamedQuery(
"ApprovedSite.getByClientDetails", ApprovedSite.class);
query.setParameter("clientDetails", clientDetails);
List<ApprovedSite> found = query.getResultList();
return found;
}
@Override
@Transactional
@ -70,18 +55,6 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
return manager.find(ApprovedSite.class, id);
}
@Override
@Transactional
public Collection<ApprovedSite> getByUserId(String userId) {
TypedQuery<ApprovedSite> query = manager.createNamedQuery(
"ApprovedSite.getByUserId", ApprovedSite.class);
query.setParameter("userId", userId);
List<ApprovedSite> found = query.getResultList();
return found;
}
@Override
@Transactional
public void remove(ApprovedSite approvedSite) {
@ -108,4 +81,14 @@ public class JpaApprovedSiteRepository implements ApprovedSiteRepository {
public ApprovedSite save(ApprovedSite approvedSite) {
return saveOrUpdate(approvedSite.getId(), manager, approvedSite);
}
@Override
public ApprovedSite getByClientIdAndUserId(String clientId, String userId) {
TypedQuery<ApprovedSite> query = manager.createNamedQuery("ApprovedSite.getByClientIdAndUserId", ApprovedSite.class);
query.setParameter("userId", userId);
query.setParameter("clientId", clientId);
return JpaUtil.getSingleResult(query.getResultList());
}
}

View File

@ -26,14 +26,13 @@ import javax.persistence.TypedQuery;
import org.mitre.openid.connect.model.WhitelistedSite;
import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
import org.mitre.util.jpa.JpaUtil;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* JPA WhitelistedSite repository implementation
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
@Repository
@ -85,9 +84,9 @@ public class JpaWhitelistedSiteRepository implements WhitelistedSiteRepository {
@Override
@Transactional
public WhitelistedSite getByClientDetails(ClientDetails client) {
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByClientDetails", WhitelistedSite.class);
query.setParameter("clientDetails", client);
public WhitelistedSite getByClientId(String clientId) {
TypedQuery<WhitelistedSite> query = manager.createNamedQuery("WhitelistedSite.getByClientId", WhitelistedSite.class);
query.setParameter("clientId", clientId);
return JpaUtil.getSingleResult(query.getResultList());
}

View File

@ -16,9 +16,11 @@
package org.mitre.openid.connect.service.impl;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import org.mitre.oauth2.model.ClientDetailsEntity;
import org.mitre.openid.connect.model.ApprovedSite;
import org.mitre.openid.connect.model.WhitelistedSite;
import org.mitre.openid.connect.repository.ApprovedSiteRepository;
import org.mitre.openid.connect.service.ApprovedSiteService;
import org.springframework.beans.factory.annotation.Autowired;
@ -28,7 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
/**
* Implementation of the ApprovedSiteService
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
@Service
@ -60,19 +62,8 @@ public class ApprovedSiteServiceImpl implements ApprovedSiteService {
}
@Override
public Collection<ApprovedSite> getByClientDetails(
ClientDetailsEntity clientDetails) {
return approvedSiteRepository.getByClientDetails(clientDetails);
}
@Override
public Collection<ApprovedSite> getByUserId(String userId) {
return approvedSiteRepository.getByUserId(userId);
}
@Override
public void save(ApprovedSite approvedSite) {
approvedSiteRepository.save(approvedSite);
public ApprovedSite save(ApprovedSite approvedSite) {
return approvedSiteRepository.save(approvedSite);
}
@Override
@ -90,4 +81,31 @@ public class ApprovedSiteServiceImpl implements ApprovedSiteService {
approvedSiteRepository.removeById(id);
}
@Override
public ApprovedSite createApprovedSite(String clientId, String userId, Date timeoutDate, Set<String> allowedScopes,
WhitelistedSite whitelistedSite) {
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);
as.setWhitelistedSite(whitelistedSite);
return save(as);
}
@Override
public ApprovedSite getByClientIdAndUserId(String clientId,
String userId) {
return approvedSiteRepository.getByClientIdAndUserId(clientId, userId);
}
}

View File

@ -21,14 +21,13 @@ import org.mitre.openid.connect.model.WhitelistedSite;
import org.mitre.openid.connect.repository.WhitelistedSiteRepository;
import org.mitre.openid.connect.service.WhitelistedSiteService;
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;
/**
* Implementation of the WhitelistedSiteService
*
* @author Michael Joseph Walsh
* @author Michael Joseph Walsh, aanganes
*
*/
@Service
@ -80,8 +79,8 @@ public class WhitelistedSiteServiceImpl implements WhitelistedSiteService {
}
@Override
public WhitelistedSite getByClientDetails(ClientDetails client) {
return whitelistedSiteRepository.getByClientDetails(client);
public WhitelistedSite getByClientId(String clientId) {
return whitelistedSiteRepository.getByClientId(clientId);
}
@Override

View File

@ -1,200 +0,0 @@
/*******************************************************************************
* Copyright 2012 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.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.mitre.oauth2.model.ClientDetailsEntity;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
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 com.google.common.base.Splitter;
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
*
*/
public class JdbcUserApprovalHandler implements UserApprovalHandler {
@Autowired
ApprovedSiteService approvedSiteService;
@Autowired
WhitelistedSiteService whitelistedSiteService;
@Autowired
ClientDetailsService clientDetailsService;
/**
* 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 pre-approved, false otherwise
*/
@Override
public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) {
//First, check database to see if the user identified by the userAuthentication has stored an approval decision
//getName may not be filled in? TODO: investigate
String userId = userAuthentication.getName();
ClientDetails client = clientDetailsService.loadClientByClientId(authorizationRequest.getClientId());
//lookup ApprovedSites by userId
Collection<ApprovedSite> approvedSites = approvedSiteService.getByUserId(userId);
for (ApprovedSite ap : approvedSites) {
if (sitesMatch(ap, authorizationRequest, userId)) {
//We have a match; update the access date on the AP entry and return true.
ap.setAccessDate(new Date());
approvedSiteService.save(ap);
return true;
}
}
WhitelistedSite ws = whitelistedSiteService.getByClientDetails(client);
if (ws != null && scopesMatch(ws, authorizationRequest)) {
//Create an approved site
ApprovedSite newAP = new ApprovedSite();
newAP.setClientDetails((ClientDetailsEntity)client);
newAP.setAccessDate(new Date());
newAP.setWhitelistedSite(ws);
newAP.setAllowedScopes(ws.getAllowedScopes());
newAP.setCreationDate(new Date());
newAP.setUserId(userId);
approvedSiteService.save(newAP);
return true;
}
boolean approved = Boolean.parseBoolean(authorizationRequest.getApprovalParameters().get("user_oauth_approval"));
if (approved && !authorizationRequest.getApprovalParameters().isEmpty()) {
//Only store an ApprovedSite if the user has checked "remember this decision":
if (authorizationRequest.getApprovalParameters().get("remember") != null) {
//TODO: Remember may eventually have an option to remember for a specific amount
//of time; this would set the ApprovedSite.timeout.
//Make a new AP
ApprovedSite newAP = new ApprovedSite();
newAP.setAccessDate(new Date());
Set<String> allowedScopes = Sets.newHashSet();
Map<String,String> approvalParams = authorizationRequest.getApprovalParameters();
for (String key : approvalParams.keySet()) {
if (key.contains("scope")) {
//This is a scope parameter from the approval page. The value sent back should
//be the scope string.
allowedScopes.add(approvalParams.get(key));
}
}
newAP.setAllowedScopes(allowedScopes);
newAP.setClientDetails((ClientDetailsEntity)client);
newAP.setUserId(userId);
newAP.setCreationDate(new Date());
approvedSiteService.save(newAP);
}
return true;
}
return false;
}
/**
* Check if a given ApprovedSite entry matches the information about the current request.
*
* @param ap the ApprovedSite to compare
* @param authReq the AuthorizationRequest for this requst
* @param user the User making the request
* @return true if everything matches, false otherwise
*/
private boolean sitesMatch(ApprovedSite ap, AuthorizationRequest authReq, String userId) {
ClientDetails client = clientDetailsService.loadClientByClientId(authReq.getClientId());
String scopes = authReq.getAuthorizationParameters().get("scope");
Set<String> requestedScopes = Sets.newHashSet(Splitter.on(" ").split(scopes));
if (!(ap.getClientDetails().getClientId()).equals(client.getClientId())) {
return false;
}
if (!(ap.getUserId()).equals(userId)) {
return false;
}
for (String scope : requestedScopes) {
if (!ap.getAllowedScopes().contains(scope)) {
return false;
}
}
return true;
}
private boolean scopesMatch(WhitelistedSite ws, AuthorizationRequest authorizationRequest) {
String scopes = authorizationRequest.getAuthorizationParameters().get("scope");
Set<String> authRequestScopes = Sets.newHashSet(Splitter.on(" ").split(scopes));
Set<String> wsScopes = ws.getAllowedScopes();
for (String scope : authRequestScopes) {
if (!wsScopes.contains(scope)) {
throw new InvalidScopeException("Invalid scope: " + scope, wsScopes);
}
}
return true;
}
}

View File

@ -82,7 +82,7 @@
</constructor-arg>
</bean>
<bean class="org.mitre.openid.connect.token.JdbcUserApprovalHandler" id="jdbcUserApprovalHandler">
<bean class="org.mitre.openid.connect.token.TofuUserApprovalHandler" id="jdbcUserApprovalHandler">
</bean>
<bean id="authCodeServices" class="org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices" />