| /* Copyright (c) 2001-2010, 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.error.Error; |
| import org.hsqldb.error.ErrorCode; |
| import org.hsqldb.HsqlNameManager.HsqlName; |
| import org.hsqldb.Session; |
| import org.hsqldb.lib.HashMappedList; |
| import org.hsqldb.lib.HsqlArrayList; |
| import org.hsqldb.SchemaObject; |
| import org.hsqldb.SqlInvariants; |
| |
| /** |
| * 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 Boucher-Burnett (boucherb@users dot sourceforge.net) |
| * @author Fred Toussi (fredt@users dot sourceforge.net) |
| * |
| * @version 1.8.0 |
| * @since 1.7.2 |
| * @see User |
| */ |
| public final class UserManager { |
| |
| /** |
| * This object's set of User objects. <p> |
| * |
| * 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; |
| |
| /** |
| * 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. <p> |
| * |
| * A set of constraints regarding user creation is imposed: <p> |
| * |
| * <OL> |
| * <LI>If the specified name is null, then an |
| * ASSERTION_FAILED exception is thrown stating that |
| * the name is null. |
| * |
| * <LI>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). |
| * </OL> |
| */ |
| public User createUser(HsqlName name, String password) { |
| |
| // 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); |
| |
| user.setPassword(password); |
| |
| boolean success = userList.add(name.name, user); |
| |
| if (!success) { |
| throw Error.error(ErrorCode.X_28503, name.statementName); |
| } |
| |
| return user; |
| } |
| |
| /** |
| * Attempts to drop a User object with the specified name |
| * from this object's set. <p> |
| * |
| * A successful drop action consists of: <p> |
| * |
| * <UL> |
| * |
| * <LI>removing the User object with the specified name |
| * from the set. |
| * |
| * <LI>revoking all rights from the removed User<br> |
| * (this ensures that in case there are still references to the |
| * just dropped User object, those references |
| * cannot be used to erronously access database objects). |
| * |
| * </UL> <p> |
| * |
| */ |
| 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); |
| |
| createUser(name, password); |
| 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 = get(name); |
| |
| user.checkPassword(password); |
| |
| 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 <code>User</code> objects representing the database |
| * users that are visible to the <code>User</code> object |
| * represented by the <code>session</code> argument. <p> |
| * |
| * If the <code>session</code> argument's <code>User</code> object |
| * attribute has isAdmin() true (directly or by virtue of a Role), |
| * then all of the |
| * <code>User</code> objects in this collection are considered visible. |
| * Otherwise, only this object's special <code>PUBLIC</code> |
| * <code>User</code> object attribute and the session <code>User</code> |
| * object, if it exists in this collection, are considered visible. <p> |
| * |
| * @param session The <code>Session</code> object used to determine |
| * visibility |
| * @return a list of <code>User</code> objects visible to |
| * the <code>User</code> object contained by the |
| * <code>session</code> 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.getNameString(); |
| |
| if (isAdmin) { |
| list.add(user); |
| } else if (sessionName.equals(userName)) { |
| list.add(user); |
| } |
| } |
| |
| return list; |
| } |
| |
| /** |
| * Returns the specially constructed |
| * <code>SYSTEM_AUTHORIZATION_NAME</code> |
| * <code>User</code> object for the current <code>Database</code> object. |
| * |
| * @return the <code>SYS_AUTHORIZATION_NAME</code> |
| * <code>User</code> object |
| * |
| */ |
| public User getSysUser() { |
| return GranteeManager.systemAuthorisation; |
| } |
| |
| public synchronized void removeSchemaReference(String 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.name)) { |
| user.setInitialSchema(null); |
| } |
| } |
| } |
| |
| 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; |
| } |
| } |