/* * Copyright (c) 2013, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.wso2.carbon.identity.oauth.dao; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.oauth.IdentityOAuthAdminException; import org.wso2.carbon.identity.oauth.Parameters; import org.wso2.carbon.identity.oauth.config.OAuthServerConfiguration; import org.wso2.carbon.identity.oauth.tokenprocessor.PlainTextPersistenceProcessor; import org.wso2.carbon.identity.oauth.tokenprocessor.TokenPersistenceProcessor; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class OAuthConsumerDAO { public static final Log log = LogFactory.getLog(OAuthConsumerDAO.class); private TokenPersistenceProcessor persistenceProcessor; public OAuthConsumerDAO() { try { persistenceProcessor = OAuthServerConfiguration.getInstance().getPersistenceProcessor(); } catch (IdentityOAuth2Exception e) { log.error("Error retrieving TokenPersistenceProcessor. Defaulting to PlainTextProcessor", e); persistenceProcessor = new PlainTextPersistenceProcessor(); } } /** * Returns the consumer secret corresponding to a given consumer key * * @param consumerKey Consumer key * @return consumer secret * @throws IdentityOAuthAdminException Error when reading consumer secret from the persistence store */ public String getOAuthConsumerSecret(String consumerKey) throws IdentityOAuthAdminException { String consumerSecret = null; Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.GET_CONSUMER_SECRET); prepStmt.setString(1, persistenceProcessor.getProcessedClientId(consumerKey)); resultSet = prepStmt.executeQuery(); if (resultSet.next()) { consumerSecret = persistenceProcessor.getPreprocessedClientSecret(resultSet.getString(1)); } else { if(log.isDebugEnabled()) { log.debug("Invalid Consumer Key : " + consumerKey); } } connection.commit(); } catch (SQLException e) { throw new IdentityOAuthAdminException("Error when reading the consumer secret for consumer key : " + consumerKey, e); } catch (IdentityOAuth2Exception e) { throw new IdentityOAuthAdminException("Error occurred while processing client id and client secret by " + "TokenPersistenceProcessor", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return consumerSecret; } /** * Returns the username corresponding to a given client id and consumer secret * * @param clientId Client Id/Key * @param clientSecret Consumer secret * @return Username if successful, empty string otherwise * @throws IdentityOAuthAdminException Error when reading consumer secret from the persistence store */ public String getAuthenticatedUsername(String clientId, String clientSecret) throws IdentityOAuthAdminException { String username = ""; Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.GET_USERNAME_FOR_KEY_AND_SECRET); prepStmt.setString(1, clientId); prepStmt.setString(2, clientSecret); resultSet = prepStmt.executeQuery(); if (resultSet.next()) { username = resultSet.getString(1); } else { log.debug("Invalid client id : " + clientId + ", and consumer secret : " + clientSecret); } connection.commit(); } catch (SQLException e) { log.error("Error when executing the SQL : " + SQLQueries.OAuthConsumerDAOSQLQueries.GET_USERNAME_FOR_KEY_AND_SECRET); log.error(e.getMessage(), e); throw new IdentityOAuthAdminException("Error while reading username for client id : " + clientId + ", and consumer secret : " + clientSecret); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return username; } /** * Get the token secret for the given access token * * @param token OAuth token, this could be a request token(temporary token) or a access token * @param isAccessToken True, if it is as access token * @return Token Secret * @throws IdentityOAuthAdminException Error when accessing the token secret from the persistence store. */ public String getOAuthTokenSecret(String token, Boolean isAccessToken) throws IdentityException { String tokenSecret = null; Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; String sqlStmt; if (isAccessToken) { sqlStmt = SQLQueries.OAuthConsumerDAOSQLQueries.GET_ACCESS_TOKEN_SECRET; } else { sqlStmt = SQLQueries.OAuthConsumerDAOSQLQueries.GET_REQ_TOKEN_SECRET; } try { prepStmt = connection.prepareStatement(sqlStmt); prepStmt.setString(1, token); resultSet = prepStmt.executeQuery(); connection.commit(); if (resultSet.next()) { tokenSecret = resultSet.getString(1); } else { throw IdentityException.error("Invalid token : " + token); } } catch (SQLException e) { throw new IdentityOAuthAdminException("Error when reading the token secret for token : " + token, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return tokenSecret; } /** * Creates a new OAuth token. * * @param consumerKey Consumer Key * @param oauthToken OAuth Token, a unique identifier * @param oauthSecret OAuth Secret * @param userCallback Where the user should be redirected once the approval completed. * @param scope Resource or the scope of the resource. * @throws IdentityOAuthAdminException Error when writing the OAuth Req. token to the persistence store */ public void createOAuthRequestToken(String consumerKey, String oauthToken, String oauthSecret, String userCallback, String scope) throws IdentityOAuthAdminException { final String OUT_OF_BAND = "oob"; if (userCallback == null || OUT_OF_BAND.equals(userCallback)) { userCallback = getCallbackURLOfApp(consumerKey); } Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.ADD_OAUTH_REQ_TOKEN); prepStmt.setString(1, oauthToken); prepStmt.setString(2, oauthSecret); prepStmt.setString(3, userCallback); prepStmt.setString(4, scope); prepStmt.setString(5, Boolean.toString(false)); prepStmt.setString(6, consumerKey); prepStmt.execute(); connection.commit(); } catch (SQLException e) { log.error("Error when executing the SQL : " + SQLQueries.OAuthConsumerDAOSQLQueries.ADD_OAUTH_REQ_TOKEN); log.error(e.getMessage(), e); throw new IdentityOAuthAdminException("Error when creating the request token for consumer : " + consumerKey); } finally { IdentityDatabaseUtil.closeAllConnections(connection, null, prepStmt); } } /** * Authorizes the OAuth request token. * * @param oauthToken Authorized OAuth token * @param userName The name of the user who authorized the token. * @param oauthVerifier oauth_verifier - an unique identifier * @throws IdentityException */ public Parameters authorizeOAuthToken(String oauthToken, String userName, String oauthVerifier) throws IdentityException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.AUTHORIZE_REQ_TOKEN); prepStmt.setString(1, Boolean.toString(true)); prepStmt.setString(2, oauthVerifier); prepStmt.setString(3, userName); prepStmt.setString(4, oauthToken); prepStmt.execute(); connection.commit(); } catch (SQLException e) { throw new IdentityOAuthAdminException("Error when authorizing the request token : " + oauthToken); } finally { IdentityDatabaseUtil.closeAllConnections(connection, null, prepStmt); } Parameters params = new Parameters(); params.setOauthCallback(getCallbackURLOfReqToken(oauthToken)); return params; } public Parameters getRequestToken(String oauthToken) throws IdentityException { Parameters params = new Parameters(); Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.GET_REQ_TOKEN); prepStmt.setString(1, oauthToken); resultSet = prepStmt.executeQuery(); if (resultSet.next()) { params.setOauthToken(resultSet.getString(1)); params.setOauthTokenSecret(resultSet.getString(2)); params.setOauthConsumerKey(resultSet.getString(3)); params.setOauthCallback(resultSet.getString(4)); params.setScope(resultSet.getString(5)); params.setOauthTokenVerifier(resultSet.getString(7)); params.setAuthorizedbyUserName(resultSet.getString(8)); } else { throw IdentityException.error("Invalid request token : " + oauthToken); } connection.commit(); } catch (SQLException e) { throw IdentityException.error("Error when retrieving request token from the persistence store : " + oauthToken); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return params; } public void issueAccessToken(String consumerKey, String accessToken, String accessTokenSecret, String requestToken, String authorizedUser, String scope) throws IdentityOAuthAdminException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement removeReqTokStmt = null; PreparedStatement issueAccessTokStmt = null; try { removeReqTokStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.REMOVE_REQUEST_TOKEN); removeReqTokStmt.setString(1, requestToken); removeReqTokStmt.execute(); issueAccessTokStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.ADD_ACCESS_TOKEN); issueAccessTokStmt.setString(1, accessToken); issueAccessTokStmt.setString(2, accessTokenSecret); issueAccessTokStmt.setString(3, consumerKey); issueAccessTokStmt.setString(4, scope); issueAccessTokStmt.setString(5, authorizedUser); issueAccessTokStmt.execute(); connection.commit(); } catch (SQLException e) { log.error(e.getMessage(), e); throw new IdentityOAuthAdminException("Error when creating the request token for consumer : " + consumerKey); } finally { IdentityDatabaseUtil.closeStatement(issueAccessTokStmt); IdentityDatabaseUtil.closeAllConnections(connection, null, removeReqTokStmt); } } /** * Validating the access token. Should be equal in the scope where the original request token * been issued to.If this matches, the method returns the user who authorized the request token. * * @param consumerKey Consumer Key * @param oauthToken Access Token * @param reqScope Scope in the request * @return Authorized Username * @throws IdentityException Error when reading token information from persistence store or invalid token or invalid scope. */ public String validateAccessToken(String consumerKey, String oauthToken, String reqScope) throws IdentityException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; String scope = null; String authorizedUser = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.GET_ACCESS_TOKEN); prepStmt.setString(1, oauthToken); resultSet = prepStmt.executeQuery(); if (resultSet.next()) { scope = resultSet.getString(1); authorizedUser = resultSet.getString(2); } else { throw IdentityException.error("Invalid access token : " + oauthToken); } connection.commit(); } catch (SQLException e) { throw new IdentityOAuthAdminException("Error when reading the callback url for consumer key : " + consumerKey, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } if (reqScope != null && reqScope.equals(scope)) { return authorizedUser; } else { throw IdentityException.error("Scope of the access token doesn't match with the original scope"); } } private String getCallbackURLOfApp(String consumerKey) throws IdentityOAuthAdminException { String callbackURL = null; Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.GET_REGISTERED_CALLBACK_URL); prepStmt.setString(1, consumerKey); resultSet = prepStmt.executeQuery(); if (resultSet.next()) { callbackURL = resultSet.getString(1); } connection.commit(); } catch (SQLException e) { throw new IdentityOAuthAdminException("Error when reading the callback url for consumer key : " + consumerKey, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return callbackURL; } private String getCallbackURLOfReqToken(String oauthToken) throws IdentityOAuthAdminException { String callbackURL = null; Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; try { prepStmt = connection.prepareStatement(SQLQueries.OAuthConsumerDAOSQLQueries.GET_CALLBACK_URL_OF_REQ_TOKEN); prepStmt.setString(1, oauthToken); resultSet = prepStmt.executeQuery(); if (resultSet.next()) { callbackURL = resultSet.getString(1); } connection.commit(); } catch (SQLException e) { throw new IdentityOAuthAdminException("Error when reading the callback url for OAuth Token : " + oauthToken, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return callbackURL; } }