/* * Copyright (c) JForum Team * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * 1) Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * 2) Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * 3) Neither the name of "Rafael Steil" nor * the names of its contributors may be used to endorse * or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE * * This file creation date: 19/03/2004 - 18:45:54 * The JForum Project * http://www.jforum.net */ package net.jforum.dao.generic.security; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Iterator; import net.jforum.JForumExecutionContext; import net.jforum.exceptions.DatabaseException; import net.jforum.security.PermissionControl; import net.jforum.security.Role; import net.jforum.security.RoleCollection; import net.jforum.security.RoleValue; import net.jforum.security.RoleValueCollection; import net.jforum.util.DbUtils; import net.jforum.util.preferences.SystemGlobals; import org.apache.commons.lang.StringUtils; /** * @author Rafael Steil * @version $Id: SecurityCommon.java,v 1.13 2007/08/16 13:07:34 rafaelsteil Exp $ */ public class SecurityCommon { /** * Execute the <i>add role</i> thing. As the SQL statement to insert user and group roles are * diferent, they cannot be manipuled with a 'generic' statement, and is for this reason that * <code>addRole</code> method is marked abstract. <br> * The only job the <code>addRole</code> method should do is to get the correct SQL statement * for each case - user or group - and the repass it to this method, who then do the job for us. * * @param sql The SQL statement to be executed. * @param id The ID do insert. May be user's or group's id, depending of the situation ( the caller ) * @param role The role name to insert * @param roleValues A <code>RoleValueCollection</code> collection containing the role values to * insert. If none is wanted, just pass null as argument. * @param supportAutoGeneratedKeys Set to <code>true</code> if <i>Statement.RETURN_GENERATED_KEYS</i> is supported * by the Driver, or <code>false</code> if not. * @param autoKeysQuery String */ public static void executeAddRole(String sql, int id, Role role, RoleValueCollection roleValues, boolean supportAutoGeneratedKeys, String autoKeysQuery) { PreparedStatement p = null; ResultSet rs = null; try { if (supportAutoGeneratedKeys) { p = JForumExecutionContext.getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); } else { p = JForumExecutionContext.getConnection().prepareStatement(sql); } p.setInt(1, id); p.setString(2, role.getName()); p.executeUpdate(); if (roleValues != null) { int roleId = -1; if (supportAutoGeneratedKeys) { rs = p.getGeneratedKeys(); rs.next(); roleId = rs.getInt(1); } else { p = JForumExecutionContext.getConnection().prepareStatement(autoKeysQuery); rs = p.executeQuery(); if (rs.next()) { roleId = rs.getInt(1); } } rs.close(); rs = null; p.close(); p = null; if (roleId == -1) { throw new SQLException("Could not obtain the latest role id"); } p = JForumExecutionContext.getConnection().prepareStatement( SystemGlobals.getSql("PermissionControl.addRoleValues")); for (Iterator iter = roleValues.iterator(); iter.hasNext();) { RoleValue rv = (RoleValue) iter.next(); p.setInt(1, roleId); p.setString(2, rv.getValue()); p.executeUpdate(); } } } catch (SQLException e) { throw new DatabaseException(e); } finally { DbUtils.close(rs, p); } } /** * See {@link PermissionControl#executeAddRole(String, int, String, RoleValueCollection)} for * explanation about this method. The working way is the same. * * @param rs The ResultSet containing the data to be fetched. This method does not * free the resultset after it finished using it, so it's responsability of the * caller to do such task. * @return A <code>RoleCollection</code> collection with the roles processed. */ public static RoleCollection loadRoles(ResultSet rs) { RoleCollection rc = new RoleCollection(); try { Role r = null; String lastName = null; while (rs.next()) { String currentName = rs.getString("name"); if (!currentName.equals(lastName)) { if (r != null) { rc.add(r); } r = new Role(); r.setName(rs.getString("name")); lastName = currentName; } String roleValue = rs.getString("role_value"); if (!rs.wasNull() && StringUtils.isNotBlank(roleValue)) { r.getValues().add(new RoleValue(roleValue)); } } if (r != null) { rc.add(r); } return rc; } catch (SQLException e) { throw new DatabaseException(e); } } public static String groupIdAsString(int[] ids) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < ids.length - 1; i++) { sb.append(ids[i]).append(','); } if (ids.length > 0) { sb.append(ids[ids.length - 1]); } return sb.toString(); } }