KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > UserManager


1 /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the Hypersonic SQL Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This software consists of voluntary contributions made by many individuals
31  * on behalf of the Hypersonic SQL Group.
32  *
33  *
34  * For work added by the HSQL Development Group:
35  *
36  * Copyright (c) 2001-2005, The HSQL Development Group
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions are met:
41  *
42  * Redistributions of source code must retain the above copyright notice, this
43  * list of conditions and the following disclaimer.
44  *
45  * Redistributions in binary form must reproduce the above copyright notice,
46  * this list of conditions and the following disclaimer in the documentation
47  * and/or other materials provided with the distribution.
48  *
49  * Neither the name of the HSQL Development Group nor the names of its
50  * contributors may be used to endorse or promote products derived from this
51  * software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
57  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */

65
66
67 package org.hsqldb;
68
69 import org.hsqldb.lib.HashMappedList;
70 import org.hsqldb.lib.HsqlArrayList;
71 import org.hsqldb.HsqlNameManager.HsqlName;
72 import org.hsqldb.SchemaManager.Schema;
73
74 // fredt@users 20020130 - patch 497872 by Nitin Chauhan - loop optimisation
75
// fredt@users 20020320 - doc 1.7.0 - update
76
// fredt@users 20021103 - patch 1.7.2 - allow for drop table, etc.
77
// fredt@users 20030613 - patch 1.7.2 - simplified data structures and reporting
78
// unsaved@users - patch 1.8.0 moved right managament to new classes
79

80 /**
81  *
82  * Manages the User objects for a Database instance.
83  * The special users PUBLIC_USER_NAME and SYSTEM_AUTHORIZATION_NAME
84  * are created and managed here. SYSTEM_AUTHORIZATION_NAME is also
85  * special in that the name is not kept in the user "list"
86  * (PUBLIC_USER_NAME is kept in the list because it's needed by MetaData
87  * routines via "listVisibleUsers(x, true)").
88  *
89  * Partly based on Hypersonic code.
90  *
91  * @author Thomas Mueller (Hypersonic SQL Group)
92  * @author boucherb@users
93  * @author fredt@users
94  *
95  * @version 1.8.0
96  * @since 1.7.2
97  * @see User
98  */

99 class UserManager implements GrantConstants {
100
101     /**
102      * We keep a link to the SYSTEM_AUTHORIZATION_NAME user because it is
103      * the only User with no entry in the User map.
104      */

105     User sysUser = null;
106
107     /**
108      * This object's set of User objects. <p>
109      *
110      * Note: The special _SYSTEM role
111      * is not included in this list but the special PUBLIC
112      * User object is kept in the list because it's needed by MetaData
113      * routines via "listVisibleUsers(x, true)".
114      */

115     private HashMappedList userList;
116     private GranteeManager granteeManager;
117
118     /**
119      * Construction happens once for each Database object.
120      *
121      * Creates special users PUBLIC_USER_NAME and SYSTEM_AUTHORIZATION_NAME.
122      * Sets up association with the GranteeManager for this database.
123      */

124     UserManager(Database database) throws HsqlException {
125
126         granteeManager = database.getGranteeManager();
127         userList = new HashMappedList();
128
129         createUser(GranteeManager.PUBLIC_ROLE_NAME, null);
130
131         sysUser = createUser(GranteeManager.SYSTEM_AUTHORIZATION_NAME, null);
132
133         // Don't know whether to grant ADMIN to SYS directly, or to grant
134
// role DBA. The former seems safer as it doesn't depend on any role.
135
//granteeManager.grant(SYSTEM_AUTHORIZATION_NAME, RoleManager.ADMIN_ROLE_NAME);
136
sysUser.getGrantee().setAdminDirect();
137     }
138
139     /**
140      * Creates a new User object under management of this object. <p>
141      *
142      * A set of constraints regarding user creation is imposed: <p>
143      *
144      * <OL>
145      * <LI>If the specified name is null, then an
146      * ASSERTION_FAILED exception is thrown stating that
147      * the name is null.
148      *
149      * <LI>If this object's collection already contains an element whose
150      * name attribute equals the name argument, then
151      * a GRANTEE_ALREADY_EXISTS exception is thrown.
152      * (This will catch attempts to create Reserved grantee names).
153      * </OL>
154      */

155     User createUser(String JavaDoc name, String JavaDoc password) throws HsqlException {
156
157         if (name == null) {
158             Trace.doAssert(false, Trace.getMessage(Trace.NULL_NAME));
159         }
160
161         // TODO:
162
// checkComplexity(password);
163
// requires special: createSAUser(), createPublicUser()
164
// boucherb@users 20020815 - disallow user-land creation of SYS user
165
// -------------------------------------------------------
166
// This will throw an appropriate Trace if grantee already exists,
167
// regardless of whether the name is in any User, Role, etc. list.
168
Grantee g = granteeManager.addGrantee(name);
169         User u = new User(name, password, g);
170
171         // ONLY!! SYSTEM_AUTHORIZATION_NAME is not stored in our User list.
172
if (GranteeManager.SYSTEM_AUTHORIZATION_NAME.equals(name)) {
173             return u;
174         }
175
176         boolean success = userList.add(name, u);
177
178         if (!success) {
179             throw Trace.error(Trace.USER_ALREADY_EXISTS, name);
180         }
181
182         return u;
183     }
184
185     /**
186      * Attempts to drop a User object with the specified name
187      * from this object's set. <p>
188      *
189      * A successful drop action consists of: <p>
190      *
191      * <UL>
192      *
193      * <LI>removing the User object with the specified name
194      * from the set.
195      *
196      * <LI>revoking all rights from the removed object<br>
197      * (this ensures that in case there are still references to the
198      * just dropped User object, those references
199      * cannot be used to erronously access database objects).
200      *
201      * </UL> <p>
202      *
203      */

204     void dropUser(String JavaDoc name) throws HsqlException {
205
206         boolean reservedUser = GranteeManager.isReserved(name);
207
208         Trace.check(!reservedUser, Trace.NONMOD_ACCOUNT, name);
209
210         boolean result = granteeManager.removeGrantee(name);
211
212         Trace.check(result, Trace.NO_SUCH_GRANTEE, name);
213
214         User u = (User) userList.remove(name);
215
216         Trace.check(u != null, Trace.USER_NOT_FOUND, name);
217     }
218
219     /**
220      * Returns the User object with the specified name and
221      * password from this object's set.
222      */

223     User getUser(String JavaDoc name, String JavaDoc password) throws HsqlException {
224
225         if (name == null) {
226             name = "";
227         }
228
229         if (password == null) {
230             password = "";
231         }
232
233         // Don't have to worry about SYSTEM_AUTHORIZATION_NAME, since get()
234
// will fail below (because it's not in the list).
235
if (name.equals(GranteeManager.PUBLIC_ROLE_NAME)) {
236             throw Trace.error(Trace.ACCESS_IS_DENIED);
237         }
238
239         name = name.toUpperCase();
240         password = password.toUpperCase();
241
242         User u = get(name);
243
244         u.checkPassword(password);
245
246         return u;
247     }
248
249     /**
250      * Retrieves this object's set of User objects as
251      * an HsqlArrayList. <p>
252      */

253     HashMappedList getUsers() {
254         return userList;
255     }
256
257     boolean exists(String JavaDoc name) {
258         return userList.get(name) == null ? false
259                                           : true;
260     }
261
262     /**
263      * Returns the User object identified by the
264      * name argument. <p>
265      */

266     User get(String JavaDoc name) throws HsqlException {
267
268         User u = (User) userList.get(name);
269
270         if (u == null) {
271             throw Trace.error(Trace.USER_NOT_FOUND, name);
272         }
273
274         return u;
275     }
276
277     /**
278      * Retrieves the <code>User</code> objects representing the database
279      * users that are visible to the <code>User</code> object
280      * represented by the <code>session</code> argument. <p>
281      *
282      * If the <code>session</code> argument's <code>User</code> object
283      * attribute has isAdmin() true (directly or by virtue of a Role),
284      * then all of the
285      * <code>User</code> objects in this collection are considered visible.
286      * Otherwise, only this object's special <code>PUBLIC</code>
287      * <code>User</code> object attribute and the session <code>User</code>
288      * object, if it exists in this collection, are considered visible. <p>
289      *
290      * @param session The <code>Session</code> object used to determine
291      * visibility
292      * @param andPublicUser whether to include the special <code>PUBLIC</code>
293      * <code>User</code> object in the retrieved list
294      * @return a list of <code>User</code> objects visible to
295      * the <code>User</code> object contained by the
296      * <code>session</code> argument.
297      *
298      */

299     HsqlArrayList listVisibleUsers(Session session, boolean andPublicUser) {
300
301         HsqlArrayList list;
302         User user;
303         boolean isAdmin;
304         String JavaDoc sessName;
305         String JavaDoc userName;
306
307         list = new HsqlArrayList();
308         isAdmin = session.isAdmin();
309         sessName = session.getUsername();
310
311         if (userList == null || userList.size() == 0) {
312             return list;
313         }
314
315         for (int i = 0; i < userList.size(); i++) {
316             user = (User) userList.get(i);
317
318             if (user == null) {
319                 continue;
320             }
321
322             userName = user.getName();
323
324             if (GranteeManager.PUBLIC_ROLE_NAME.equals(userName)) {
325                 if (andPublicUser) {
326                     list.add(user);
327                 }
328             } else if (isAdmin) {
329                 list.add(user);
330             } else if (sessName.equals(userName)) {
331                 list.add(user);
332             }
333         }
334
335         return list;
336     }
337
338     // Legacy wrappers
339
static String JavaDoc[] getRightsArray(int rights) {
340         return GranteeManager.getRightsArray(rights);
341     }
342
343     /**
344      * Removes all rights mappings for the database object identified by
345      * the dbobject argument from all Grantee objects in the set.
346      */

347     void removeDbObject(Object JavaDoc dbobject) {
348         granteeManager.removeDbObject(dbobject);
349     }
350
351     /**
352      * Returns the specially constructed
353      * <code>SYSTEM_AUTHORIZATION_NAME</code>
354      * <code>User</code> object for the current <code>Database</code> object.
355      *
356      * @throws HsqlException - if the specified <code>Database</code>
357      * has no <code>SYS_AUTHORIZATION_NAME</code>
358      * <code>User</code> object.
359      * @return the <code>SYS_AUTHORIZATION_NAME</code>
360      * <code>User</code> object
361      *
362      */

363     User getSysUser() {
364         return sysUser;
365     }
366
367     public synchronized void removeSchemaReference(Schema schema) {
368
369         for (int i = 0; i < userList.size(); i++) {
370             User user = (User) userList.get(i);
371
372             if (user.getInitialSchema() == schema.name) {
373                 user.setInitialSchema(null);
374             }
375         }
376     }
377 }
378
Popular Tags