001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: com_mysql_jdbc_Driver.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.authentication.credentialsmanagers.databasedrivers;
009:
010: import com.uwyn.rife.authentication.credentialsmanagers.exceptions.*;
011:
012: import com.uwyn.rife.authentication.credentialsmanagers.DatabaseUsers;
013: import com.uwyn.rife.authentication.credentialsmanagers.RoleUserAttributes;
014: import com.uwyn.rife.authentication.exceptions.CredentialsManagerException;
015: import com.uwyn.rife.config.RifeConfig;
016: import com.uwyn.rife.database.Datasource;
017: import com.uwyn.rife.database.DbPreparedStatement;
018: import com.uwyn.rife.database.DbPreparedStatementHandler;
019: import com.uwyn.rife.database.exceptions.DatabaseException;
020: import com.uwyn.rife.database.queries.CreateTable;
021: import com.uwyn.rife.database.queries.Delete;
022: import com.uwyn.rife.database.queries.Insert;
023: import com.uwyn.rife.database.queries.Select;
024: import java.security.NoSuchAlgorithmException;
025: import java.util.HashMap;
026:
027: public class com_mysql_jdbc_Driver extends generic {
028: private Delete mRemoveRoleLinksByRoleId = null;
029:
030: public com_mysql_jdbc_Driver(Datasource datasource) {
031: super (datasource);
032:
033: mCreateTableRole = new CreateTable(getDatasource()).table(
034: RifeConfig.Authentication.getTableRole()).column(
035: "roleId", int.class, CreateTable.NOTNULL).column(
036: "name", String.class,
037: RifeConfig.Authentication.getRoleNameMaximumLength(),
038: CreateTable.NOTNULL).customAttribute("roleId",
039: "AUTO_INCREMENT").primaryKey(
040: RifeConfig.Authentication.getTableRole().toUpperCase()
041: + "_PK", "roleId").unique(
042: RifeConfig.Authentication.getTableRole().toUpperCase()
043: + "_NAME_UQ", "name");
044:
045: mCreateTableRoleLink = new CreateTable(getDatasource()).table(
046: RifeConfig.Authentication.getTableRoleLink()).column(
047: "userId", long.class, CreateTable.NOTNULL).column(
048: "roleId", int.class, CreateTable.NOTNULL).primaryKey(
049: RifeConfig.Authentication.getTableRoleLink()
050: .toUpperCase()
051: + "_PK", new String[] { "userId", "roleId" });
052:
053: mAddRole = new Insert(getDatasource()).into(
054: mCreateTableRole.getTable()).fieldParameter("name");
055:
056: mGetFreeUserId = new Select(getDatasource()).field(
057: "MAX(userId)+1 as freeUserId").from(
058: mCreateTableUser.getTable());
059:
060: mGetRoleId = new Select(getDatasource()).from(
061: mCreateTableRole.getTable()).field("roleId")
062: .whereParameter("name", "role", "=");
063:
064: mRemoveRoleLinksByRoleId = new Delete(getDatasource()).from(
065: mCreateTableRoleLink.getTable()).whereParameter(
066: "roleId", "=");
067: }
068:
069: public boolean install() throws CredentialsManagerException {
070: try {
071: executeUpdate(mCreateTableRole);
072: executeUpdate(mCreateTableUser);
073: executeUpdate(mCreateTableRoleLink);
074: } catch (DatabaseException e) {
075: throw new InstallCredentialsErrorException(e);
076: }
077:
078: return true;
079: }
080:
081: public boolean remove() throws CredentialsManagerException {
082: try {
083: executeUpdate(mDropTableRoleLink);
084: executeUpdate(mDropTableUser);
085: executeUpdate(mDropTableRole);
086: } catch (DatabaseException e) {
087: throw new RemoveCredentialsErrorException(e);
088: }
089:
090: return true;
091: }
092:
093: public DatabaseUsers addRole(final String role)
094: throws CredentialsManagerException {
095: if (null == role || 0 == role.length()) {
096: throw new AddRoleErrorException(role);
097: }
098:
099: try {
100: if (0 == executeUpdate(mAddRole,
101: new DbPreparedStatementHandler() {
102: public void setParameters(
103: DbPreparedStatement statement) {
104: statement.setString("name", role);
105: }
106: })) {
107: throw new AddRoleErrorException(role);
108: }
109: } catch (DatabaseException e) {
110: if (null != e.getCause()) {
111: String message = e.getCause().getMessage()
112: .toUpperCase();
113: if (-1 != message.indexOf("DUPLICATE")
114: && -1 != message.indexOf("FOR KEY 2")) {
115: throw new DuplicateRoleException(role);
116: }
117: }
118:
119: throw new AddRoleErrorException(role, e);
120: }
121:
122: return this ;
123: }
124:
125: public DatabaseUsers addUser(final String login,
126: final RoleUserAttributes attributes)
127: throws CredentialsManagerException {
128: if (null == login || 0 == login.length() || null == attributes) {
129: throw new AddUserErrorException(login, attributes);
130: }
131:
132: try {
133: // ensure that the password is encoded if an encoder has been set
134: String password = null;
135: if (null == mPasswordEncryptor
136: || attributes.getPassword().startsWith(
137: mPasswordEncryptor.toString())) {
138: password = attributes.getPassword();
139: } else {
140: try {
141: password = mPasswordEncryptor.encrypt(attributes
142: .getPassword());
143: } catch (NoSuchAlgorithmException e) {
144: throw new AddUserErrorException(login, attributes,
145: e);
146: }
147: }
148:
149: HashMap<String, Integer> roleids = null;
150: // get the role ids
151: if (attributes.getRoles() != null) {
152: roleids = new HashMap<String, Integer>();
153:
154: DbPreparedStatement ps_get_roleid = getConnection()
155: .getPreparedStatement(mGetRoleId);
156: int roleid = -1;
157: try {
158: for (String role : attributes.getRoles()) {
159: ps_get_roleid.setString(1, role);
160: ps_get_roleid.executeQuery();
161: if (ps_get_roleid.getResultSet()
162: .hasResultRows()) {
163: roleid = ps_get_roleid.getResultSet()
164: .getFirstInt();
165: }
166:
167: if (-1 == roleid) {
168: throw new UnknownRoleErrorException(role,
169: login, attributes);
170: }
171:
172: roleids.put(role, roleid);
173: }
174: } finally {
175: ps_get_roleid.close();
176: }
177: }
178:
179: synchronized (mGetFreeUserId) {
180: final String adapted_password = password;
181:
182: // get a new user id if it has not been provided
183: if (attributes.getUserId() < 0) {
184: attributes
185: .setUserId(executeGetFirstLong(mGetFreeUserId));
186: }
187:
188: if (0 == executeUpdate(mAddUserWithId,
189: new DbPreparedStatementHandler() {
190: public void setParameters(
191: DbPreparedStatement statement) {
192: statement.setLong("userId",
193: attributes.getUserId())
194: .setString("login", login)
195: .setString("passwd",
196: adapted_password);
197: }
198: })) {
199: throw new AddUserErrorException(login, attributes);
200: }
201: }
202:
203: // ensure that the correct roles are assigned to the user
204: if (attributes.getRoles() != null) {
205: DbPreparedStatement ps_add_rolelink = getConnection()
206: .getPreparedStatement(mAddRoleLink);
207: try {
208: for (String role : attributes.getRoles()) {
209: ps_add_rolelink.setLong(1, attributes
210: .getUserId());
211: ps_add_rolelink.setInt(2, roleids.get(role));
212: if (0 == ps_add_rolelink.executeUpdate()) {
213: throw new AddUserErrorException(login,
214: attributes);
215: }
216: ps_add_rolelink.clearParameters();
217: }
218: } finally {
219: ps_add_rolelink.close();
220: }
221: }
222: } catch (DatabaseException e) {
223: if (null != e.getCause()) {
224: String message = e.getCause().getMessage()
225: .toUpperCase();
226: if (-1 != message.indexOf("DUPLICATE")) {
227: if (-1 != message.indexOf("FOR KEY 1")) {
228: throw new DuplicateUserIdException(attributes
229: .getUserId());
230: }
231: if (-1 != message.indexOf("FOR KEY 2")) {
232: throw new DuplicateLoginException(login);
233: }
234: }
235: }
236:
237: throw new AddUserErrorException(login, attributes, e);
238: }
239:
240: return this ;
241: }
242:
243: public boolean updateUser(final String login,
244: RoleUserAttributes attributes)
245: throws CredentialsManagerException {
246: if (null == login || 0 == login.length() || null == attributes) {
247: throw new UpdateUserErrorException(login, attributes);
248: }
249:
250: try {
251: HashMap<String, Integer> roleids = null;
252: // get the role ids
253: if (attributes.getRoles() != null) {
254: roleids = new HashMap<String, Integer>();
255:
256: DbPreparedStatement ps_get_roleid = getConnection()
257: .getPreparedStatement(mGetRoleId);
258: int roleid = -1;
259: try {
260: for (String role : attributes.getRoles()) {
261: ps_get_roleid.setString(1, role);
262: ps_get_roleid.executeQuery();
263: if (ps_get_roleid.getResultSet()
264: .hasResultRows()) {
265: roleid = ps_get_roleid.getResultSet()
266: .getFirstInt();
267: }
268:
269: if (-1 == roleid) {
270: throw new UnknownRoleErrorException(role,
271: login, attributes);
272: }
273:
274: roleids.put(role, roleid);
275: }
276: } finally {
277: ps_get_roleid.close();
278: }
279: }
280:
281: // obtain the user id
282: final long userid = getUserId(login);
283: if (userid < 0) {
284: throw new UpdateUserErrorException(login, attributes);
285: }
286:
287: // only handle the password if it has been provided
288: if (attributes.getPassword() != null) {
289: // ensure that the password is encoded if an encoder has been set
290: String password = null;
291: if (null == mPasswordEncryptor
292: || attributes.getPassword().startsWith(
293: mPasswordEncryptor.toString())) {
294: password = attributes.getPassword();
295: } else {
296: try {
297: password = mPasswordEncryptor
298: .encrypt(attributes.getPassword());
299: } catch (NoSuchAlgorithmException e) {
300: throw new UpdateUserErrorException(login,
301: attributes, e);
302: }
303: }
304:
305: // update the user password
306: final String adapted_password = password;
307: if (0 == executeUpdate(mUpdateUser,
308: new DbPreparedStatementHandler() {
309: public void setParameters(
310: DbPreparedStatement statement) {
311: statement.setString("passwd",
312: adapted_password).setString(
313: "login", login);
314: }
315: })) {
316: return false;
317: }
318: }
319:
320: // remove the previous roles
321: executeUpdate(mRemoveRoleLinksByUserId,
322: new DbPreparedStatementHandler() {
323: public void setParameters(
324: DbPreparedStatement statement) {
325: statement.setLong("userId", userid);
326: }
327: });
328:
329: // assign the correct roles to the user
330: if (attributes.getRoles() != null) {
331: // add the provided roles
332: DbPreparedStatement ps_add_rolelink = getConnection()
333: .getPreparedStatement(mAddRoleLink);
334: try {
335: for (String role : attributes.getRoles()) {
336: ps_add_rolelink.setLong(1, userid);
337: ps_add_rolelink.setInt(2, roleids.get(role));
338: if (0 == ps_add_rolelink.executeUpdate()) {
339: throw new AddUserErrorException(login,
340: attributes);
341: }
342: ps_add_rolelink.clearParameters();
343: }
344: } finally {
345: ps_add_rolelink.close();
346: }
347: }
348: } catch (DatabaseException e) {
349: throw new UpdateUserErrorException(login, attributes, e);
350: }
351:
352: return true;
353: }
354:
355: public boolean removeUser(final String login)
356: throws CredentialsManagerException {
357: if (null == login || 0 == login.length()) {
358: return false;
359: }
360:
361: boolean result = false;
362:
363: try {
364: final long userid = executeGetFirstLong(mGetUserId,
365: new DbPreparedStatementHandler() {
366: public void setParameters(
367: DbPreparedStatement statement) {
368: statement.setString("login", login);
369: }
370: });
371:
372: if (0 != executeUpdate(mRemoveUserByLogin,
373: new DbPreparedStatementHandler() {
374: public void setParameters(
375: DbPreparedStatement statement) {
376: statement.setString("login", login);
377: }
378: })) {
379: result = true;
380: }
381:
382: if (0 != executeUpdate(mRemoveRoleLinksByUserId,
383: new DbPreparedStatementHandler() {
384: public void setParameters(
385: DbPreparedStatement statement) {
386: statement.setLong("userId", userid);
387: }
388: })) {
389: result = true;
390: }
391: } catch (DatabaseException e) {
392: throw new RemoveUserErrorException(login, e);
393: }
394:
395: return result;
396: }
397:
398: public boolean removeUser(final long userId)
399: throws CredentialsManagerException {
400: if (userId < 0) {
401: return false;
402: }
403:
404: boolean result = false;
405:
406: try {
407: if (0 != executeUpdate(mRemoveUserByUserId,
408: new DbPreparedStatementHandler() {
409: public void setParameters(
410: DbPreparedStatement statement) {
411: statement.setLong("userId", userId);
412: }
413: })) {
414: result = true;
415: }
416:
417: if (0 != executeUpdate(mRemoveRoleLinksByUserId,
418: new DbPreparedStatementHandler() {
419: public void setParameters(
420: DbPreparedStatement statement) {
421: statement.setLong("userId", userId);
422: }
423: })) {
424: result = true;
425: }
426: } catch (DatabaseException e) {
427: throw new RemoveUserErrorException(userId, e);
428: }
429:
430: return result;
431: }
432:
433: public boolean removeRole(final String name)
434: throws CredentialsManagerException {
435: if (null == name || 0 == name.length()) {
436: return false;
437: }
438:
439: boolean result = false;
440:
441: try {
442: final int roleid = executeGetFirstInt(mGetRoleId,
443: new DbPreparedStatementHandler() {
444: public void setParameters(
445: DbPreparedStatement statement) {
446: statement.setString("role", name);
447: }
448: });
449:
450: if (0 != executeUpdate(mRemoveRole,
451: new DbPreparedStatementHandler() {
452: public void setParameters(
453: DbPreparedStatement statement) {
454: statement.setString("role", name);
455: }
456: })) {
457: result = true;
458: }
459:
460: if (0 != executeUpdate(mRemoveRoleLinksByRoleId,
461: new DbPreparedStatementHandler() {
462: public void setParameters(
463: DbPreparedStatement statement) {
464: statement.setInt("roleId", roleid);
465: }
466: })) {
467: result = true;
468: }
469: } catch (DatabaseException e) {
470: throw new RemoveRoleErrorException(name, e);
471: }
472:
473: return result;
474: }
475: }
|