All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hsqldb.rights.UserManager Maven / Gradle / Ivy

There is a newer version: 2.7.4
Show newest version
/* Copyright (c) 2001-2019, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 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.
 *
 * Neither the name of the HSQL Development Group 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 HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * 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.
 */


package org.hsqldb.rights;

import org.hsqldb.Database;
import org.hsqldb.HsqlException;
import org.hsqldb.HsqlNameManager.HsqlName;
import org.hsqldb.Routine;
import org.hsqldb.Schema;
import org.hsqldb.SchemaObject;
import org.hsqldb.Session;
import org.hsqldb.SqlInvariants;
import org.hsqldb.Tokens;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.HashMappedList;
import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.result.Result;

/**
 * Manages the User objects for a Database instance.
 * The special users PUBLIC_USER_NAME and SYSTEM_AUTHORIZATION_NAME
 * are created and managed here.  SYSTEM_AUTHORIZATION_NAME is also
 * special in that the name is not kept in the user "list"
 * (PUBLIC_USER_NAME is kept in the list because it's needed by MetaData
 * routines via "listVisibleUsers(x, true)").
 *
 * @author Campbell Burnet (campbell-burnet@users dot sourceforge.net)
 * @author Fred Toussi (fredt@users dot sourceforge.net)
 *
 * @version 2.5.0
 * @since 1.7.2
 * @see  User
 */
public final class UserManager {

    /**
     * This object's set of User objects. 

* * Note: The special _SYSTEM role * is not included in this list but the special PUBLIC * User object is kept in the list because it's needed by MetaData * routines via "listVisibleUsers(x, true)". */ private HashMappedList userList; private GranteeManager granteeManager; /** * The function for password complexity. */ Routine pwCheckFunction; Routine extAuthenticationFunction; /** * Construction happens once for each Database instance. * * Creates special users PUBLIC_USER_NAME and SYSTEM_AUTHORIZATION_NAME. * Sets up association with the GranteeManager for this database. */ public UserManager(Database database) { granteeManager = database.getGranteeManager(); userList = new HashMappedList(); } /** * Creates a new User object under management of this object.

* * A set of constraints regarding user creation is imposed:

* *

    *
  1. If the specified name is null, then an * ASSERTION_FAILED exception is thrown stating that * the name is null. * *
  2. If this object's collection already contains an element whose * name attribute equals the name argument, then * a GRANTEE_ALREADY_EXISTS exception is thrown. * (This will catch attempts to create Reserved grantee names). *
*/ public User createUser(Session session, HsqlName name, String password, boolean isDigest) { // This will throw an appropriate exception if grantee already exists, // regardless of whether the name is in any User, Role, etc. list. User user = granteeManager.addUser(name); if (session == null) { user.setPassword(password, isDigest); } else { try { setPassword(session, user, password, isDigest); } catch (HsqlException e) { granteeManager.removeNewUser(name); throw e; } } // this cannot fail userList.add(name.name, user); return user; } public void setPassword(Session session, User user, String password, boolean isDigest) { if (!isDigest && !checkComplexity(session, password)) { throw Error.error(ErrorCode.PASSWORD_COMPLEXITY); } // requires: UserManager.createSAUser(), UserManager.createPublicUser() user.setPassword(password, isDigest); } public boolean checkComplexity(Session session, String password) { if (session == null || pwCheckFunction == null) { return true; } Result result = pwCheckFunction.invoke(session, new Object[]{ password }, null, true); Boolean check = (Boolean) result.getValueObject(); if (check == null || !check.booleanValue()) { return false; } return true; } /** * Attempts to drop a User object with the specified name * from this object's set.

* * A successful drop action consists of:

* *

    * *
  • removing the User object with the specified name * from the set. * *
  • revoking all rights from the removed User
    * (this ensures that in case there are still references to the * just dropped User object, those references * cannot be used to erroneously access database objects). * *

* */ public void dropUser(String name) { boolean reservedUser = GranteeManager.isReserved(name); if (reservedUser) { throw Error.error(ErrorCode.X_28502, name); } boolean result = granteeManager.removeGrantee(name); if (!result) { throw Error.error(ErrorCode.X_28501, name); } User user = (User) userList.remove(name); if (user == null) { throw Error.error(ErrorCode.X_28501, name); } } public void createFirstUser(String username, String password) { boolean isQuoted = true; if (username.equalsIgnoreCase("SA")) { username = "SA"; isQuoted = false; } HsqlName name = granteeManager.database.nameManager.newHsqlName(username, isQuoted, SchemaObject.GRANTEE); User user = createUser(null, name, password, false); user.isLocalOnly = true; granteeManager.grant(name.name, SqlInvariants.DBA_ADMIN_ROLE_NAME, granteeManager.getDBARole()); } /** * Returns the User object with the specified name and * password from this object's set. */ public User getUser(String name, String password) { if (name == null) { name = ""; } if (password == null) { password = ""; } User user = (User) userList.get(name); boolean isLocal = user != null && user.isLocalOnly; if (extAuthenticationFunction == null || isLocal) { user = get(name); user.checkPassword(password); return user; } /* * Authentication returns String[]. When null, use the existing * user object only, with existing privileges. * When not null, ignore if user exists. Otherwise create a user and * assign the list of roles to the user. */ Result result = extAuthenticationFunction.invokeJavaMethodDirect(new String[] { granteeManager.database.getNameString(), name, password }); if (result.isError()) { throw Error.error(ErrorCode.X_28501, result.getMainString()); } Object[] roles = (Object[]) result.getValueObject(); if (user == null) { HsqlName hsqlName = granteeManager.database.nameManager.newHsqlName(name, true, SchemaObject.GRANTEE); user = createUser(null, hsqlName, "", false); user.isExternalOnly = true; } if (roles == null) { user.updateAllRights(); return user; } // this clears all existing privileges of the user user.clearPrivileges(); // assigns the roles to the user for (int i = 0; i < roles.length; i++) { try { Grantee role = granteeManager.getRole((String) roles[i]); user.grant(role); } catch (HsqlException e) {} } user.updateAllRights(); for (int i = 0; i < roles.length; i++) { Schema schema = granteeManager.database.schemaManager.findSchema( (String) roles[i]); if (schema != null) { user.setInitialSchema(schema.getName()); break; } } return user; } /** * Retrieves this object's set of User objects as * an associative list. */ public HashMappedList getUsers() { return userList; } public boolean exists(String name) { return userList.get(name) == null ? false : true; } /** * Returns the User object identified by the * name argument. */ public User get(String name) { User user = (User) userList.get(name); if (user == null) { throw Error.error(ErrorCode.X_28501, name); } return user; } /** * Retrieves the User objects representing the database * users that are visible to the User object * represented by the session argument.

* * If the session argument's User object * attribute has isAdmin() true (directly or by virtue of a Role), * then all of the * User objects in this collection are considered visible. * Otherwise, only this object's special PUBLIC * User object attribute and the session User * object, if it exists in this collection, are considered visible.

* * @param session The Session object used to determine * visibility * @return a list of User objects visible to * the User object contained by the * session argument. * */ public HsqlArrayList listVisibleUsers(Session session) { HsqlArrayList list; User user; boolean isAdmin; String sessionName; String userName; list = new HsqlArrayList(); isAdmin = session.isAdmin(); sessionName = session.getUsername(); if (userList == null || userList.size() == 0) { return list; } for (int i = 0; i < userList.size(); i++) { user = (User) userList.get(i); if (user == null) { continue; } userName = user.getName().getNameString(); if (isAdmin) { list.add(user); } else if (sessionName.equals(userName)) { list.add(user); } } return list; } /** * Returns the specially constructed * SYSTEM_AUTHORIZATION_NAME * User object for the current Database object. * * @return the SYS_AUTHORIZATION_NAME * User object * */ public User getSysUser() { return GranteeManager.systemAuthorisation; } public synchronized void removeSchemaReference(HsqlName schemaName) { for (int i = 0; i < userList.size(); i++) { User user = (User) userList.get(i); HsqlName schema = user.getInitialSchema(); if (schema == null) { continue; } if (schemaName.equals(schema)) { user.setInitialSchema(null); } } } public void setPasswordCheckFunction(Routine function) { pwCheckFunction = function; } public void setExtAuthenticationFunction(Routine function) { extAuthenticationFunction = function; } public String[] getInitialSchemaSQL() { HsqlArrayList list = new HsqlArrayList(userList.size()); for (int i = 0; i < userList.size(); i++) { User user = (User) userList.get(i); if (user.isSystem) { continue; } HsqlName name = user.getInitialSchema(); if (name == null) { continue; } list.add(user.getInitialSchemaSQL()); } String[] array = new String[list.size()]; list.toArray(array); return array; } public String[] getAuthenticationSQL() { HsqlArrayList list = new HsqlArrayList(); String[] array; if (pwCheckFunction != null) { StringBuilder sb = new StringBuilder(); sb.append(Tokens.T_SET).append(' ').append(Tokens.T_DATABASE); sb.append(' ').append(Tokens.T_PASSWORD).append(' '); sb.append(Tokens.T_CHECK).append(' ').append(Tokens.T_FUNCTION); sb.append(' '); sb.append(pwCheckFunction.getSQLBodyDefinition()); list.add(sb.toString()); } if (extAuthenticationFunction != null) { StringBuilder sb = new StringBuilder(); sb.append(Tokens.T_SET).append(' ').append(Tokens.T_DATABASE); sb.append(' ').append(Tokens.T_AUTHENTICATION).append(' '); sb.append(Tokens.T_FUNCTION).append(' '); sb.append(extAuthenticationFunction.getSQLBodyDefinition()); list.add(sb.toString()); } array = new String[list.size()]; list.toArray(array); return array; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy