/* * Copyright 2001-2008 Geert Bevin <gbevin[remove] at uwyn dot com> * Licensed under the Apache License, Version 2.0 (the "License") * $Id: com_mysql_jdbc_Driver.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.authentication.credentialsmanagers.databasedrivers; import com.uwyn.rife.authentication.credentialsmanagers.exceptions.*; import com.uwyn.rife.authentication.credentialsmanagers.DatabaseUsers; import com.uwyn.rife.authentication.credentialsmanagers.RoleUserAttributes; import com.uwyn.rife.authentication.exceptions.CredentialsManagerException; import com.uwyn.rife.config.RifeConfig; import com.uwyn.rife.database.Datasource; import com.uwyn.rife.database.DbPreparedStatement; import com.uwyn.rife.database.DbPreparedStatementHandler; import com.uwyn.rife.database.exceptions.DatabaseException; import com.uwyn.rife.database.queries.CreateTable; import com.uwyn.rife.database.queries.Delete; import com.uwyn.rife.database.queries.Insert; import com.uwyn.rife.database.queries.Select; import java.security.NoSuchAlgorithmException; import java.util.HashMap; public class com_mysql_jdbc_Driver extends generic { private Delete mRemoveRoleLinksByRoleId = null; public com_mysql_jdbc_Driver(Datasource datasource) { super(datasource); mCreateTableRole = new CreateTable(getDatasource()) .table(RifeConfig.Authentication.getTableRole()) .column("roleId", int.class, CreateTable.NOTNULL) .column("name", String.class, RifeConfig.Authentication.getRoleNameMaximumLength(), CreateTable.NOTNULL) .customAttribute("roleId", "AUTO_INCREMENT") .primaryKey(RifeConfig.Authentication.getTableRole().toUpperCase()+"_PK", "roleId") .unique(RifeConfig.Authentication.getTableRole().toUpperCase()+"_NAME_UQ", "name"); mCreateTableRoleLink = new CreateTable(getDatasource()) .table(RifeConfig.Authentication.getTableRoleLink()) .column("userId", long.class, CreateTable.NOTNULL) .column("roleId", int.class, CreateTable.NOTNULL) .primaryKey(RifeConfig.Authentication.getTableRoleLink().toUpperCase()+"_PK", new String[] {"userId", "roleId"}); mAddRole = new Insert(getDatasource()) .into(mCreateTableRole.getTable()) .fieldParameter("name"); mGetFreeUserId = new Select(getDatasource()) .field("MAX(userId)+1 as freeUserId") .from(mCreateTableUser.getTable()); mGetRoleId = new Select(getDatasource()) .from(mCreateTableRole.getTable()) .field("roleId") .whereParameter("name", "role", "="); mRemoveRoleLinksByRoleId = new Delete(getDatasource()) .from(mCreateTableRoleLink.getTable()) .whereParameter("roleId", "="); } public boolean install() throws CredentialsManagerException { try { executeUpdate(mCreateTableRole); executeUpdate(mCreateTableUser); executeUpdate(mCreateTableRoleLink); } catch (DatabaseException e) { throw new InstallCredentialsErrorException(e); } return true; } public boolean remove() throws CredentialsManagerException { try { executeUpdate(mDropTableRoleLink); executeUpdate(mDropTableUser); executeUpdate(mDropTableRole); } catch (DatabaseException e) { throw new RemoveCredentialsErrorException(e); } return true; } public DatabaseUsers addRole(final String role) throws CredentialsManagerException { if (null == role || 0 == role.length()) { throw new AddRoleErrorException(role); } try { if (0 == executeUpdate(mAddRole, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("name", role); } })) { throw new AddRoleErrorException(role); } } catch (DatabaseException e) { if (null != e.getCause()) { String message = e.getCause().getMessage().toUpperCase(); if (-1 != message.indexOf("DUPLICATE") && -1 != message.indexOf("FOR KEY 2")) { throw new DuplicateRoleException(role); } } throw new AddRoleErrorException(role, e); } return this; } public DatabaseUsers addUser(final String login, final RoleUserAttributes attributes) throws CredentialsManagerException { if (null == login || 0 == login.length() || null == attributes) { throw new AddUserErrorException(login, attributes); } try { // ensure that the password is encoded if an encoder has been set String password = null; if (null == mPasswordEncryptor || attributes.getPassword().startsWith(mPasswordEncryptor.toString())) { password = attributes.getPassword(); } else { try { password = mPasswordEncryptor.encrypt(attributes.getPassword()); } catch (NoSuchAlgorithmException e) { throw new AddUserErrorException(login, attributes, e); } } HashMap<String, Integer> roleids = null; // get the role ids if (attributes.getRoles() != null) { roleids = new HashMap<String, Integer>(); DbPreparedStatement ps_get_roleid = getConnection().getPreparedStatement(mGetRoleId); int roleid = -1; try { for (String role : attributes.getRoles()) { ps_get_roleid.setString(1, role); ps_get_roleid.executeQuery(); if (ps_get_roleid.getResultSet().hasResultRows()) { roleid = ps_get_roleid.getResultSet().getFirstInt(); } if (-1 == roleid) { throw new UnknownRoleErrorException(role, login, attributes); } roleids.put(role, roleid); } } finally { ps_get_roleid.close(); } } synchronized (mGetFreeUserId) { final String adapted_password = password; // get a new user id if it has not been provided if (attributes.getUserId() < 0) { attributes.setUserId(executeGetFirstLong(mGetFreeUserId)); } if (0 == executeUpdate(mAddUserWithId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("userId", attributes.getUserId()) .setString("login", login) .setString("passwd", adapted_password); } })) { throw new AddUserErrorException(login, attributes); } } // ensure that the correct roles are assigned to the user if (attributes.getRoles() != null) { DbPreparedStatement ps_add_rolelink = getConnection().getPreparedStatement(mAddRoleLink); try { for (String role : attributes.getRoles()) { ps_add_rolelink.setLong(1, attributes.getUserId()); ps_add_rolelink.setInt(2, roleids.get(role)); if (0 == ps_add_rolelink.executeUpdate()) { throw new AddUserErrorException(login, attributes); } ps_add_rolelink.clearParameters(); } } finally { ps_add_rolelink.close(); } } } catch (DatabaseException e) { if (null != e.getCause()) { String message = e.getCause().getMessage().toUpperCase(); if (-1 != message.indexOf("DUPLICATE")) { if (-1 != message.indexOf("FOR KEY 1")) { throw new DuplicateUserIdException(attributes.getUserId()); } if (-1 != message.indexOf("FOR KEY 2")) { throw new DuplicateLoginException(login); } } } throw new AddUserErrorException(login, attributes, e); } return this; } public boolean updateUser(final String login, RoleUserAttributes attributes) throws CredentialsManagerException { if (null == login || 0 == login.length() || null == attributes) { throw new UpdateUserErrorException(login, attributes); } try { HashMap<String, Integer> roleids = null; // get the role ids if (attributes.getRoles() != null) { roleids = new HashMap<String, Integer>(); DbPreparedStatement ps_get_roleid = getConnection().getPreparedStatement(mGetRoleId); int roleid = -1; try { for (String role : attributes.getRoles()) { ps_get_roleid.setString(1, role); ps_get_roleid.executeQuery(); if (ps_get_roleid.getResultSet().hasResultRows()) { roleid = ps_get_roleid.getResultSet().getFirstInt(); } if (-1 == roleid) { throw new UnknownRoleErrorException(role, login, attributes); } roleids.put(role, roleid); } } finally { ps_get_roleid.close(); } } // obtain the user id final long userid = getUserId(login); if (userid < 0) { throw new UpdateUserErrorException(login, attributes); } // only handle the password if it has been provided if (attributes.getPassword() != null) { // ensure that the password is encoded if an encoder has been set String password = null; if (null == mPasswordEncryptor || attributes.getPassword().startsWith(mPasswordEncryptor.toString())) { password = attributes.getPassword(); } else { try { password = mPasswordEncryptor.encrypt(attributes.getPassword()); } catch (NoSuchAlgorithmException e) { throw new UpdateUserErrorException(login, attributes, e); } } // update the user password final String adapted_password = password; if (0 == executeUpdate(mUpdateUser, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("passwd", adapted_password) .setString("login", login); } })) { return false; } } // remove the previous roles executeUpdate(mRemoveRoleLinksByUserId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("userId", userid); } }); // assign the correct roles to the user if (attributes.getRoles() != null) { // add the provided roles DbPreparedStatement ps_add_rolelink = getConnection().getPreparedStatement(mAddRoleLink); try { for (String role : attributes.getRoles()) { ps_add_rolelink.setLong(1, userid); ps_add_rolelink.setInt(2, roleids.get(role)); if (0 == ps_add_rolelink.executeUpdate()) { throw new AddUserErrorException(login, attributes); } ps_add_rolelink.clearParameters(); } } finally { ps_add_rolelink.close(); } } } catch (DatabaseException e) { throw new UpdateUserErrorException(login, attributes, e); } return true; } public boolean removeUser(final String login) throws CredentialsManagerException { if (null == login || 0 == login.length()) { return false; } boolean result = false; try { final long userid = executeGetFirstLong(mGetUserId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("login", login); } }); if (0 != executeUpdate(mRemoveUserByLogin, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("login", login); } })) { result = true; } if (0 != executeUpdate(mRemoveRoleLinksByUserId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("userId", userid); } })) { result = true; } } catch (DatabaseException e) { throw new RemoveUserErrorException(login, e); } return result; } public boolean removeUser(final long userId) throws CredentialsManagerException { if (userId < 0) { return false; } boolean result = false; try { if (0 != executeUpdate(mRemoveUserByUserId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("userId", userId); } })) { result = true; } if (0 != executeUpdate(mRemoveRoleLinksByUserId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setLong("userId", userId); } })) { result = true; } } catch (DatabaseException e) { throw new RemoveUserErrorException(userId, e); } return result; } public boolean removeRole(final String name) throws CredentialsManagerException { if (null == name || 0 == name.length()) { return false; } boolean result = false; try { final int roleid = executeGetFirstInt(mGetRoleId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("role", name); } }); if (0 != executeUpdate(mRemoveRole, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setString("role", name); } })) { result = true; } if (0 != executeUpdate(mRemoveRoleLinksByRoleId, new DbPreparedStatementHandler() { public void setParameters(DbPreparedStatement statement) { statement .setInt("roleId", roleid); } })) { result = true; } } catch (DatabaseException e) { throw new RemoveRoleErrorException(name, e); } return result; } }