package org.jboss.resteasy.auth.oauth;
import java.net.HttpURLConnection;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.jboss.resteasy.auth.oauth.i18n.Messages;
/**
* OAuthProvider that keeps all data in memory. Mainly used as an example and for tests.
* @author Stéphane Épardaud <stef@epardaud.fr>
*/
public class OAuthMemoryProvider implements OAuthProvider {
private String realm;
private ConcurrentHashMap<String, OAuthConsumer> consumers = new ConcurrentHashMap<String,OAuthConsumer>();
private ConcurrentHashMap<String, OAuthRequestToken> requestTokens = new ConcurrentHashMap<String,OAuthRequestToken>();
private ConcurrentHashMap<String, OAuthToken> accessTokens = new ConcurrentHashMap<String,OAuthToken>();
public OAuthMemoryProvider(){
this("default");
}
public OAuthMemoryProvider(String realm){
this.realm = realm;
}
private OAuthToken doMakeAccessTokens(OAuthRequestToken requestToken) throws OAuthException {
String newToken;
do{
newToken = makeRandomString();
}while(accessTokens.containsKey(newToken));
OAuthToken token = new OAuthToken(newToken, makeRandomString(),
requestToken.getScopes(), requestToken.getPermissions(),
-1, requestToken.getConsumer());
accessTokens.put(token.getToken(), token);
return token;
}
private OAuthToken doGetAccessToken(String consumerKey, String accessKey) throws OAuthException{
// get is atomic
OAuthToken ret = accessTokens.get(accessKey);
if (!ret.getConsumer().getKey().equals(consumerKey)) {
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.consumerIsInvalid());
}
if(ret == null)
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.noSuchAccessKey(accessKey));
return ret;
}
private OAuthRequestToken doMakeRequestToken(String consumerKey, String callback,
String[] scopes, String[] permissions)
throws OAuthException {
OAuthConsumer consumer = _getConsumer(consumerKey);
String newToken;
do{
newToken = makeRandomString();
}while(requestTokens.containsKey(newToken));
OAuthRequestToken token =
new OAuthRequestToken(newToken, makeRandomString(), callback,
scopes, permissions, -1, consumer);
requestTokens.put(token.getToken(), token);
return token;
}
private OAuthRequestToken doGetRequestToken(String customerKey, String requestKey) throws OAuthException{
// get is atomic
OAuthRequestToken ret = requestTokens.get(requestKey);
checkCustomerKey(ret, customerKey);
if(ret == null)
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.noSuchRequestKey(requestKey));
return ret;
}
public OAuthRequestToken verifyAndRemoveRequestToken(String customerKey, String requestToken, String verifier) throws OAuthException {
OAuthRequestToken request = getRequestToken(requestToken);
checkCustomerKey(request, customerKey);
// check the verifier, which is only set when the request token was accepted
if(verifier == null || !verifier.equals(request.getVerifier()))
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.invalidVerifierCode(requestToken));
// then let's go through and exchange this for an access token
return requestTokens.remove(requestToken);
}
private static String makeRandomString(){
return UUID.randomUUID().toString();
}
private void checkCustomerKey(OAuthToken token, String customerKey) throws OAuthException {
if (customerKey != null && !customerKey.equals(token.getConsumer().getKey())) {
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.invalidCustomerKey());
}
}
//
// For subclassers
protected void addConsumer(String consumerKey, String consumerSecret){
consumers.put(consumerKey, new OAuthConsumer(consumerKey, consumerSecret, null, null));
}
protected void addRequestKey(String consumerKey, String requestToken, String requestSecret, String callback, String[] scopes) throws OAuthException{
OAuthConsumer consumer = _getConsumer(consumerKey);
OAuthRequestToken token = new OAuthRequestToken(requestToken, requestSecret, callback,
scopes, null, -1, consumer);
requestTokens.put(requestToken, token);
}
protected void addAccessKey(String consumerKey, String accessToken, String accessSecret, String[] permissions) throws OAuthException {
OAuthConsumer consumer = _getConsumer(consumerKey);
OAuthToken token = new OAuthToken(accessToken, accessSecret,
null, permissions, -1, consumer);
accessTokens.put(accessToken, token);
}
protected void authoriseRequestToken(String consumerKey, String requestToken, String verifier) throws OAuthException{
doGetRequestToken(consumerKey, requestToken).setVerifier(verifier);
}
protected OAuthConsumer _getConsumer(String consumerKey) throws OAuthException{
OAuthConsumer ret = consumers.get(consumerKey);
if(ret == null)
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.noSuchConsumerKey(consumerKey));
return ret;
}
//
// OAuthProvider interface
public String getRealm() {
return realm;
}
public String authoriseRequestToken(String consumerKey, String requestToken) throws OAuthException{
String verifier = makeRandomString();
doGetRequestToken(consumerKey, requestToken).setVerifier(verifier);
return verifier;
}
public OAuthConsumer registerConsumer(String consumerKey,
String displayName, String connectURI) throws OAuthException {
OAuthConsumer consumer = consumers.get(consumerKey);
if (consumer == null) {
return consumer;
}
consumer = new OAuthConsumer(consumerKey, "therealfrog", displayName, connectURI);
consumers.putIfAbsent(consumerKey, consumer);
return consumer;
}
public OAuthConsumer getConsumer(String consumerKey) throws OAuthException {
return _getConsumer(consumerKey);
}
public OAuthRequestToken getRequestToken(String consumerKey, String requestToken)
throws OAuthException {
OAuthRequestToken token = getRequestToken(requestToken);
if (consumerKey != null && !token.getConsumer().getKey().equals(consumerKey)) {
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.noSuchConsumerKey(consumerKey));
}
return token;
}
public OAuthToken getAccessToken(String consumerKey, String accessToken)
throws OAuthException {
return doGetAccessToken(consumerKey, accessToken);
}
public void checkTimestamp(OAuthToken token, long timestamp) throws OAuthException {
if(token.getTimestamp() > timestamp)
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.invalidTimestampLong(timestamp));
}
public OAuthToken makeAccessToken(String consumerKey,
String requestToken, String verifier) throws OAuthException {
OAuthRequestToken token = verifyAndRemoveRequestToken(consumerKey, requestToken, verifier);
return doMakeAccessTokens(token);
}
public OAuthRequestToken makeRequestToken(String consumerKey, String callback,
String[] scopes, String[] permissions) throws OAuthException {
OAuthRequestToken token = doMakeRequestToken(consumerKey, callback, scopes, permissions);
requestTokens.put(token.getToken(), token);
return token;
}
public OAuthRequestToken getRequestToken(String requestToken)
throws OAuthException {
OAuthRequestToken token = requestTokens.get(requestToken);
if (token == null) {
throw new OAuthException(HttpURLConnection.HTTP_UNAUTHORIZED, Messages.MESSAGES.noSuchRequestToken(requestToken));
}
return token;
}
public void registerConsumerScopes(String consumerKey, String[] scopes)
throws OAuthException {
OAuthConsumer consumer = _getConsumer(consumerKey);
consumer.setScopes(scopes);
}
public void registerConsumerPermissions(String consumerKey,
String[] permissions) throws OAuthException {
// TODO Auto-generated method stub
}
public Set<String> convertPermissionsToRoles(String[] permissions) {
// TODO Auto-generated method stub
return null;
}
}