/* * Copyright (c) 2005, 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.sts.store.dao; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.rahas.Token; import org.apache.rahas.TrustException; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.sts.store.DBQueries; import org.wso2.carbon.identity.sts.store.STSMgtConstants; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; /** * This utility used to manage the DB operations for token store. */ public class DBStsDAO { private static final Log log = LogFactory.getLog(DBStsDAO.class); /** * This is for adding token to DB. * * @param token Token */ public void addToken(Token token) throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; String query = DBQueries.ADD_TOKEN; try { prepStmt = connection.prepareStatement(query); prepStmt.setString(1, token.getId()); byte[] tokenByteContainer = getTokenContent(token); InputStream tokenInputStream = new ByteArrayInputStream(tokenByteContainer); prepStmt.setBinaryStream(2, tokenInputStream, tokenByteContainer.length); prepStmt.setTimestamp(3, new Timestamp(token.getCreated().getTime())); prepStmt.setTimestamp(4, new Timestamp(token.getExpires().getTime())); prepStmt.setInt(5, token.getState()); prepStmt.execute(); connection.commit(); } catch (Exception e) { IdentityDatabaseUtil.rollBack(connection); String msg = "Failed to add token"; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } } /** * This is for updating the token in DB * * @param token Token */ public void updateToken(Token token) throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; String query = DBQueries.UPDATE_TOKEN; try { prepStmt = connection.prepareStatement(query); byte[] tokenByteContainer = getTokenContent(token); InputStream tokenInputStream = new ByteArrayInputStream(tokenByteContainer); prepStmt.setBinaryStream(1, tokenInputStream, tokenByteContainer.length); prepStmt.setTimestamp(2, new Timestamp(token.getCreated().getTime())); prepStmt.setTimestamp(3, new Timestamp(token.getExpires().getTime())); prepStmt.setInt(4, token.getState()); prepStmt.setString(5, token.getId()); prepStmt.executeUpdate(); connection.commit(); } catch (Exception e) { IdentityDatabaseUtil.rollBack(connection); String msg = "Failed to update token "; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } } /** * This is for removing token * * @param tokenId tokenId */ public void removeToken(String tokenId) throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; String query = DBQueries.REMOVE_TOKEN; try { prepStmt = connection.prepareStatement(query); prepStmt.setString(1, tokenId); prepStmt.executeUpdate(); } catch (Exception e) { String msg = "Failed to remove token"; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } } /** * This is for get all the token keys * * @return arrays of keys */ public String[] getAllTokenKeys() throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; List<String> keyList; String[] keys = new String[0]; String query = DBQueries.ALL_TOKEN_KEYS; try { prepStmt = connection.prepareStatement(query); rs = prepStmt.executeQuery(); keyList = new ArrayList<>(); if (rs != null) { while (rs.next()) { keyList.add(rs.getString(STSMgtConstants.TOKEN_ID)); } } if (!keyList.isEmpty()) { keys = keyList.toArray(new String[keyList.size()]); } } catch (Exception e) { String msg = "Failed to get all tokens"; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } return keys; } /** * This is to get Token from token id * * @param tokenId tokenId * @return Token */ public Token getToken(String tokenId) throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; Token token = null; String query = DBQueries.GET_TOKEN; try { prepStmt = connection.prepareStatement(query); prepStmt.setString(1, tokenId); rs = prepStmt.executeQuery(); if (rs != null) { while (rs.next()) { Blob tokenContent = rs.getBlob(STSMgtConstants.TOKEN_CONTENT); byte[] tokenContentBytes = tokenContent.getBytes(1, (int) tokenContent.length()); token = getToken(tokenContentBytes); } } } catch (Exception e) { String msg = "Failed to get token"; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } return token; } private Token getToken(byte[] tokenContentBytes) throws TrustException { Token token; try { ByteArrayInputStream tokenContentByteArray = new ByteArrayInputStream(tokenContentBytes); ObjectInputStream tokenContentObject = new ObjectInputStream(tokenContentByteArray); Object tokenObj = tokenContentObject.readObject(); token = (Token) tokenObj; } catch (Exception e) { String msg = "Failed to convert blob content to Token object "; throw new TrustException(msg, e); } return token; } /** * This is to get all tokens from token store * * @return List of Tokens */ public List<Token> getTokens() throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; List<Token> tokens = new ArrayList<Token>(); String query = DBQueries.GET_ALL_TOKENS; try { prepStmt = connection.prepareStatement(query); rs = prepStmt.executeQuery(); if (rs != null) { while (rs.next()) { tokens.add(getToken((byte[]) rs.getObject(STSMgtConstants.TOKEN_CONTENT))); } } return tokens; } catch (Exception e) { String msg = "Failed to get all tokens"; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } } /** * This is to get valid tokens * * @param status Token.ISSUED, Token.RENEWED * @return Arrays of Tokens * @throws TrustException if failed to get valid tokens */ public Token[] getValidTokens(int[] status) throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; List<Token> tokens = new ArrayList<Token>(); String query = DBQueries.VALID_TOKENS; try { prepStmt = connection.prepareStatement(query); prepStmt.setInt(1, Token.ISSUED); prepStmt.setInt(2, Token.RENEWED); rs = prepStmt.executeQuery(); if (rs != null) { while (rs.next()) { Token token = getToken((byte[]) rs.getObject(STSMgtConstants.TOKEN_CONTENT)); tokens.add(token); } } return tokens.toArray(new Token[tokens.size()]); } catch (Exception e) { String msg = "Failed to get valid tokens"; throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } } /** * This is to get expired tokens from token store * * @param status state id of expired tokens * @return Token[] * @throws TrustException if failed to get expired tokens */ public Token[] getExpiredTokens(int status) throws TrustException { return getTokens(status); } /** * This is to get the renewed tokens from token store * * @param status state id of the renewed token * @return Token[] * @throws TrustException if failed to get renewed tokens */ public Token[] getRenewedTokens(int status) throws TrustException { return getTokens(status); } /** * This is to get canceled tokens from token store * * @param status state id of cancel token * @return Token[] * @throws TrustException if failed to get canceled tokens */ public Token[] getCancelledTokens(int status) throws TrustException { return getTokens(status); } private Token[] getTokens(int status) throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; List<Token> tokens = new ArrayList<Token>(); String query = DBQueries.GET_TOKENS_BY_STATE; try { prepStmt = connection.prepareStatement(query); prepStmt.setInt(1, status); rs = prepStmt.executeQuery(); if (rs != null) { while (rs.next()) { Token token = getToken((byte[]) rs.getObject(STSMgtConstants.TOKEN_CONTENT)); tokens.add(token); } } return tokens.toArray(new Token[tokens.size()]); } catch (Exception e) { String msg = "Failed to get token"; log.error(msg, e); throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } } /** * This is to check token store empty or not * * @return boolean * @throws TrustException if failed to check the tokens availability */ public boolean isTokensExist() throws TrustException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rs = null; boolean tokenExist = false; String query = DBQueries.TOKENS_EXISTS; try { prepStmt = connection.prepareStatement(query); rs = prepStmt.executeQuery(); if (rs != null && rs.next()) { return true; } } catch (Exception e) { String msg = "Failed to check token exist"; log.error(msg, e); throw new TrustException(msg, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rs, prepStmt); } return tokenExist; } private byte[] getTokenContent(Token token) throws IOException { ByteArrayOutputStream tokenArrayStream = new ByteArrayOutputStream(); ObjectOutputStream tokenObjectStream = null; byte[] tokenBytes = null; try { tokenObjectStream = new ObjectOutputStream(tokenArrayStream); tokenObjectStream.writeObject(token); tokenObjectStream.flush(); tokenBytes = tokenArrayStream.toByteArray(); } finally { if (tokenObjectStream != null) { tokenObjectStream.close(); } } return tokenBytes; } }