0001: /*
0002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016: package org.outerj.daisy.repository.serverimpl.user;
0017:
0018: import java.sql.*;
0019: import java.util.*;
0020: import java.util.Date;
0021: import java.security.MessageDigest;
0022:
0023: import org.apache.xmlbeans.XmlObject;
0024: import org.apache.commons.collections.primitives.LongList;
0025: import org.apache.commons.collections.primitives.ArrayLongList;
0026: import org.apache.commons.logging.Log;
0027: import org.outerj.daisy.repository.commonimpl.AuthenticatedUser;
0028: import org.outerj.daisy.repository.commonimpl.user.*;
0029: import org.outerj.daisy.jdbcutil.JdbcHelper;
0030: import org.outerj.daisy.repository.serverimpl.EventHelper;
0031: import org.outerj.daisy.repository.serverimpl.LocalRepositoryManager.Context;
0032: import org.outerj.daisy.repository.user.*;
0033: import org.outerj.daisy.repository.RepositoryEventType;
0034: import org.outerj.daisy.repository.RepositoryException;
0035: import org.outerj.daisy.repository.ConcurrentUpdateException;
0036: import org.outerx.daisy.x10.*;
0037:
0038: public class LocalUserManagementStrategy implements
0039: UserManagementStrategy {
0040: private static final String SELECT_ALL_FROM_USERS = "select id, login, default_role, first_name, last_name, email, updateable_by_user, confirmed, confirmkey, auth_scheme, last_modified, last_modifier,updatecount from users";
0041: private static final String SELECT_USER_WHERE_LOGIN = SELECT_ALL_FROM_USERS
0042: + " where login=?";
0043: private static final String SELECT_USER_WHERE_ID = SELECT_ALL_FROM_USERS
0044: + " where id=?";
0045: private static final String SELECT_USERS_WHERE_EMAIL = SELECT_ALL_FROM_USERS
0046: + " where email=?";
0047: private static final String SELECT_ALL_FROM_ROLES = "select id, name, description, last_modified, last_modifier, updatecount from roles";
0048: private static final String SELECT_ROLE_WHERE_NAME = SELECT_ALL_FROM_ROLES
0049: + " where name=?";
0050: private static final String SELECT_ROLE_WHERE_ID = SELECT_ALL_FROM_ROLES
0051: + " where id=?";
0052: private static final String SELECT_ROLES_WHERE_USERID = "select role_id from user_roles where user_id=?";
0053: private static final String INSERT_ROLES = "insert into user_roles(role_id, user_id) values (?,?)";
0054: private static final String DELETE_ROLES = "delete from user_roles where user_id=?";
0055: private Log logger;
0056: private Context context;
0057: private JdbcHelper jdbcHelper;
0058: private EventHelper eventHelper;
0059: private AuthenticatedUser systemUser;
0060:
0061: /**
0062: * @param context
0063: */
0064: public LocalUserManagementStrategy(Context context,
0065: JdbcHelper jdbcHelper, AuthenticatedUser systemUser) {
0066: this .context = context;
0067: this .logger = context.getLogger();
0068: this .jdbcHelper = jdbcHelper;
0069: this .eventHelper = new EventHelper(context, jdbcHelper);
0070: this .systemUser = systemUser;
0071: }
0072:
0073: public Users loadUsers(AuthenticatedUser requestingUser)
0074: throws UserManagementException {
0075: if (!requestingUser.isInAdministratorRole())
0076: throw new UserManagementException(
0077: "Non-Administrator users cannot retrieve other users then themselve.");
0078:
0079: Connection conn = null;
0080: PreparedStatement stmt = null;
0081: List<User> users = new ArrayList<User>();
0082:
0083: try {
0084: conn = context.getDataSource().getConnection();
0085:
0086: stmt = conn.prepareStatement(SELECT_ALL_FROM_USERS);
0087: ResultSet rs = stmt.executeQuery();
0088:
0089: while (rs.next()) {
0090: UserImpl user = getUserFromResultSet(rs, requestingUser);
0091: users.add(user);
0092: }
0093: } catch (Exception e) {
0094: throw new UserManagementException(
0095: "Error while loading user list.", e);
0096: } finally {
0097: jdbcHelper.closeStatement(stmt);
0098: jdbcHelper.closeConnection(conn);
0099: }
0100:
0101: return new UsersImpl(users.toArray(new User[users.size()]));
0102: }
0103:
0104: private UserImpl getUserFromResultSet(ResultSet rs,
0105: AuthenticatedUser requestingUser) throws SQLException,
0106: UserManagementException {
0107: long id = rs.getLong(1);
0108: String login = rs.getString(2);
0109: long defaultRoleId = rs.getLong(3);
0110: String firstName = rs.getString(4);
0111: String lastName = rs.getString(5);
0112: String email = rs.getString(6);
0113: boolean updateableByUser = rs.getBoolean(7);
0114: boolean confirmed = rs.getBoolean(8);
0115: String confirmKey = rs.getString(9);
0116: String authenticationScheme = rs.getString(10);
0117: Date lastModified = rs.getTimestamp(11);
0118: long lastModifier = rs.getLong(12);
0119: long updateCount = rs.getLong(13);
0120:
0121: UserImpl user = new UserImpl(this , login, requestingUser);
0122: UserImpl.IntimateAccess userInt = user.getIntimateAccess(this );
0123: // TODO using the saved() method here to set the object state is conceptually wrong,
0124: // the purpose of that method is to update the object state after saving it
0125: userInt.saved(id, firstName, lastName, email, lastModified,
0126: lastModifier, updateCount);
0127: user.setUpdateableByUser(updateableByUser);
0128: user.setConfirmed(confirmed);
0129: user.setConfirmKey(confirmKey);
0130: user.setAuthenticationScheme(authenticationScheme);
0131:
0132: Role[] userRoles = getUserRoles(id, requestingUser);
0133: for (Role role : userRoles) {
0134: userInt.addToRole(role);
0135: }
0136:
0137: if (defaultRoleId == -1) {
0138: user.setDefaultRole(null);
0139: } else {
0140: Role defaultRole = RolesUtil.getRole(user.getAllRoles(),
0141: defaultRoleId);
0142: user.setDefaultRole(defaultRole);
0143: }
0144:
0145: return user;
0146: }
0147:
0148: public long[] getUserIds(AuthenticatedUser requestingUser)
0149: throws UserManagementException {
0150: Connection conn = null;
0151: Statement stmt = null;
0152: try {
0153: conn = context.getDataSource().getConnection();
0154: stmt = conn.createStatement();
0155: ResultSet rs = stmt.executeQuery("select id from users");
0156: LongList userIds = new ArrayLongList();
0157: while (rs.next())
0158: userIds.add(rs.getLong(1));
0159: return userIds.toArray();
0160: } catch (Exception e) {
0161: throw new UserManagementException(
0162: "Error while loading user list.", e);
0163: } finally {
0164: jdbcHelper.closeStatement(stmt);
0165: jdbcHelper.closeConnection(conn);
0166: }
0167: }
0168:
0169: public Roles loadRoles(AuthenticatedUser requestingUser)
0170: throws UserManagementException {
0171: Connection conn = null;
0172: PreparedStatement stmt = null;
0173: List<Role> roles = new ArrayList<Role>();
0174:
0175: try {
0176: conn = context.getDataSource().getConnection();
0177:
0178: stmt = conn.prepareStatement(SELECT_ALL_FROM_ROLES);
0179: ResultSet rs = stmt.executeQuery();
0180:
0181: while (rs.next()) {
0182: long id = rs.getLong(1);
0183: String name = rs.getString(2);
0184: String description = rs.getString(3);
0185: Date lastModified = rs.getTimestamp(4);
0186: long lastModifier = rs.getLong(5);
0187: RoleImpl role = new RoleImpl(this , name, requestingUser);
0188: role.setDescription(description);
0189: RoleImpl.IntimateAccess roleInt = role
0190: .getIntimateAccess(this );
0191: roleInt.setId(id);
0192: roleInt.setLastModified(lastModified);
0193: roleInt.setLastModifier(lastModifier);
0194: roles.add(role);
0195: }
0196:
0197: rs.close();
0198: } catch (Exception e) {
0199: throw new UserManagementException(
0200: "Error while loading role list.", e);
0201: } finally {
0202: jdbcHelper.closeStatement(stmt);
0203: jdbcHelper.closeConnection(conn);
0204: }
0205:
0206: return new RolesImpl(roles.toArray(new Role[roles.size()]));
0207: }
0208:
0209: public void deleteUser(long userId, AuthenticatedUser requestingUser)
0210: throws UserManagementException {
0211: if (logger.isDebugEnabled())
0212: logger.debug("start user deletion for user with login "
0213: + userId);
0214:
0215: if (!requestingUser.isInAdministratorRole())
0216: throw new UserManagementException(
0217: "Only Administrators can delete users.");
0218:
0219: if (userId == 1)
0220: throw new UserManagementException(
0221: "The system user (id 1) cannot be deleted.");
0222:
0223: Connection conn = null;
0224: PreparedStatement stmt = null;
0225: try {
0226: conn = context.getDataSource().getConnection();
0227: //yes...transaction necessary.
0228: jdbcHelper.startTransaction(conn);
0229:
0230: UserImpl user = getUser(userId, requestingUser);
0231:
0232: logger
0233: .debug("first we need to remove child records from user_roles");
0234:
0235: stmt = conn
0236: .prepareStatement("delete from user_roles where user_id=?");
0237: stmt.setLong(1, userId);
0238:
0239: stmt.executeUpdate();
0240: stmt.close();
0241: logger
0242: .debug("user_roles should be clear for this user. User can be deleted now");
0243:
0244: // Before deleting the user, set its last_modifier to 1 (system user ID), because
0245: // it could be that the user last saved itself in which case deleting will
0246: // fail because of the foreign key constraint that protects users from being
0247: // deleted if they are still referenced as last_modifier of users.
0248: stmt = conn
0249: .prepareStatement("update users set last_modifier = 1 where id = ?");
0250: stmt.setLong(1, userId);
0251: stmt.execute();
0252: stmt.close();
0253:
0254: stmt = conn
0255: .prepareStatement("delete from users where id=?");
0256: stmt.setLong(1, userId);
0257:
0258: int modifiedRecords = stmt.executeUpdate();
0259: if (modifiedRecords != 1) {
0260: throw new UserManagementException(
0261: "Something went wrong "
0262: + "when trying to delete user with login "
0263: + userId + ". "
0264: + "No records were affected.");
0265: }
0266:
0267: XmlObject eventDescription = createUserDeletedEvent(user,
0268: requestingUser.getId());
0269: eventHelper.createEvent(eventDescription, "UserDeleted",
0270: conn);
0271:
0272: conn.commit();
0273: } catch (Throwable e) {
0274: jdbcHelper.rollback(conn);
0275: throw new UserManagementException(
0276: "Error deleting the user with ID "
0277: + userId
0278: + ". This might be because the user is still in use (referenced by other objects such as documents), in which case it is impossible to delete the user.",
0279: e);
0280: } finally {
0281: jdbcHelper.closeStatement(stmt);
0282: jdbcHelper.closeConnection(conn);
0283: logger.debug("end user deletion");
0284: }
0285:
0286: // fire synchronous events
0287: context.getCommonRepository().fireRepositoryEvent(
0288: RepositoryEventType.USER_DELETED, new Long(userId), -1);
0289: }
0290:
0291: private UserDeletedDocument createUserDeletedEvent(UserImpl user,
0292: long deleterId) {
0293: UserDeletedDocument userDeletedDocument = UserDeletedDocument.Factory
0294: .newInstance();
0295: UserDeletedDocument.UserDeleted userDeleted = userDeletedDocument
0296: .addNewUserDeleted();
0297: userDeleted.setDeleterId(deleterId);
0298: userDeleted.setDeletedTime(new GregorianCalendar());
0299: UserDocument.User userXml = user.getXml().getUser();
0300: if (userXml.isSetPassword())
0301: userXml.unsetPassword();
0302: userDeleted.addNewDeletedUser().setUser(userXml);
0303: return userDeletedDocument;
0304: }
0305:
0306: public void deleteRole(long roleId, AuthenticatedUser requestingUser)
0307: throws UserManagementException {
0308: if (!requestingUser.isInAdministratorRole())
0309: throw new UserManagementException(
0310: "Only Administrators can delete roles.");
0311:
0312: if (roleId == 1)
0313: throw new UserManagementException(
0314: "The Administrator role (id 1) cannot be deleted.");
0315:
0316: /* TRICKY SITUATION:
0317: *
0318: * suppose a role is deleted. Then we first remove all related records
0319: * from the user_roles table. We then check all the users who have
0320: * their default role pointing towards the role-to-be deleted.
0321: *
0322: * Suppose we find out that some users still have this role as their
0323: * default role AND IT IS THEIR ONLY ROLE! This is tricky. What to do?
0324: *
0325: * Do we:
0326: * 1) either: delete these users
0327: * 2) or: throw an exception (preferred!) - we can provide an extra api call
0328: * that enables an admin to switch a specified default role to another
0329: * one. Also relieves us from the tedious task to switch default role
0330: * for users who DO have other roles to another role. Which role to
0331: * choose there? Therefore: just throw an exception in that case
0332: * and let the role switching task be the responsability of an admin!
0333: *
0334: */
0335: Connection conn = null;
0336: PreparedStatement stmt = null;
0337:
0338: try {
0339: conn = context.getDataSource().getConnection();
0340:
0341: stmt = conn
0342: .prepareStatement("select count(*) from users where default_role=?");
0343: stmt.setLong(1, roleId);
0344:
0345: ResultSet rs = stmt.executeQuery();
0346:
0347: rs.next();
0348: // Let's see if the admin needs to do some work :)
0349: long userCount = rs.getInt(1);
0350: if (userCount > 0) {
0351: throw new UserManagementException(
0352: "Cannot delete the role with id "
0353: + roleId
0354: + " because "
0355: + "there are still "
0356: + userCount
0357: + " users who have this role as their default. "
0358: + "Change their default roles before deleting this role.");
0359: }
0360:
0361: } catch (Exception e) {
0362: throw new UserManagementException(
0363: "Error while deleting role.", e);
0364: } finally {
0365: jdbcHelper.closeStatement(stmt);
0366: jdbcHelper.closeConnection(conn);
0367: }
0368:
0369: // no users exist with their default role the role-to-be-deleted. We can continue.
0370:
0371: try {
0372: conn = context.getDataSource().getConnection();
0373: jdbcHelper.startTransaction(conn);
0374:
0375: RoleImpl role = getRole(roleId, requestingUser);
0376:
0377: stmt = conn
0378: .prepareStatement("delete from user_roles where role_id=?");
0379: stmt.setLong(1, roleId);
0380:
0381: stmt.executeUpdate();
0382: stmt.close();
0383: //went ok? allright. Now we can delete role itself.
0384:
0385: stmt = conn
0386: .prepareStatement("delete from roles where id=?");
0387: stmt.setLong(1, roleId);
0388:
0389: int modifiedRecords = stmt.executeUpdate();
0390: if (modifiedRecords != 1) {
0391: throw new UserManagementException(
0392: "Something went wrong "
0393: + "when trying to delete role with id "
0394: + roleId + ". "
0395: + "Most likely the role didn't exist."
0396: + modifiedRecords
0397: + " records modified.");
0398: }
0399: stmt.close();
0400:
0401: eventHelper.createEvent(createRoleDeletedEvent(role),
0402: "RoleDeleted", conn);
0403:
0404: conn.commit();
0405:
0406: } catch (Throwable e) {
0407: jdbcHelper.rollback(conn);
0408: throw new UserManagementException(
0409: "Error deleting the role with ID " + roleId + ".",
0410: e);
0411: } finally {
0412: jdbcHelper.closeStatement(stmt);
0413: jdbcHelper.closeConnection(conn);
0414: }
0415:
0416: // fire synchronous events
0417: context.getCommonRepository().fireRepositoryEvent(
0418: RepositoryEventType.ROLE_DELETED, new Long(roleId), -1);
0419: }
0420:
0421: private RoleDeletedDocument createRoleDeletedEvent(RoleImpl role) {
0422: RoleDeletedDocument roleDeletedDocument = RoleDeletedDocument.Factory
0423: .newInstance();
0424: RoleDeletedDocument.RoleDeleted roleDeleted = roleDeletedDocument
0425: .addNewRoleDeleted();
0426: roleDeleted.addNewDeletedRole()
0427: .setRole(role.getXml().getRole());
0428: roleDeleted.setDeletedTime(new GregorianCalendar());
0429: roleDeleted.setDeleterId(role.getIntimateAccess(this )
0430: .getCurrentUser().getId());
0431: return roleDeletedDocument;
0432: }
0433:
0434: public UserImpl getUser(String userLogin,
0435: AuthenticatedUser requestingUser)
0436: throws UserManagementException {
0437: Connection conn = null;
0438: PreparedStatement stmt = null;
0439: UserImpl user = null;
0440:
0441: try {
0442: conn = context.getDataSource().getConnection();
0443: stmt = conn.prepareStatement(SELECT_USER_WHERE_LOGIN);
0444: stmt.setString(1, userLogin);
0445: ResultSet rs = stmt.executeQuery();
0446:
0447: if (rs.next()) {
0448: user = getUserFromResultSet(rs, requestingUser);
0449:
0450: if (user.getId() != requestingUser.getId()
0451: && !requestingUser.isInAdministratorRole())
0452: throw new UserManagementException(
0453: "Non-Administrator users can only access their own user record.");
0454:
0455: } else {
0456: throw new UserNotFoundException(userLogin);
0457: }
0458:
0459: rs.close();
0460: } catch (Exception e) {
0461: if (e instanceof UserManagementException)
0462: throw (UserManagementException) e;
0463: else
0464: throw new UserManagementException(
0465: "Error while loading user with login "
0466: + userLogin + ".", e);
0467: } finally {
0468: jdbcHelper.closeStatement(stmt);
0469: jdbcHelper.closeConnection(conn);
0470: }
0471:
0472: return user;
0473: }
0474:
0475: /**
0476: * returns array of Role objects to which the user with userid id belongs
0477: */
0478: private Role[] getUserRoles(long id,
0479: AuthenticatedUser requestingUser)
0480: throws UserManagementException {
0481: if (logger.isDebugEnabled())
0482: logger.debug("start loading roles for user with id " + id);
0483: Connection conn = null;
0484: PreparedStatement stmt = null;
0485: List<Long> ids = new ArrayList<Long>();
0486: Role[] roles;
0487:
0488: try {
0489: conn = context.getDataSource().getConnection();
0490: stmt = conn.prepareStatement(SELECT_ROLES_WHERE_USERID);
0491: stmt.setLong(1, id);
0492: ResultSet rs = stmt.executeQuery();
0493:
0494: while (rs.next()) {
0495: long roleId = rs.getLong(1);
0496: if (logger.isDebugEnabled())
0497: logger.debug("role found with id " + roleId);
0498: ids.add(new Long(roleId));
0499: }
0500: rs.close();
0501: } catch (Exception e) {
0502: throw new UserManagementException(
0503: "Error while loading role list for user with id "
0504: + id + ".", e);
0505: } finally {
0506: jdbcHelper.closeStatement(stmt);
0507: jdbcHelper.closeConnection(conn);
0508: }
0509:
0510: Iterator iter = ids.iterator();
0511: roles = new Role[ids.size()];
0512: for (int i = 0; i < roles.length; i++) {
0513: long roleId = ((Long) iter.next()).longValue();
0514: roles[i] = getRoleWhereId(roleId, requestingUser);
0515: }
0516:
0517: return roles;
0518:
0519: }
0520:
0521: public RoleImpl getRole(String roleName,
0522: AuthenticatedUser requestingUser)
0523: throws UserManagementException {
0524: Connection conn = null;
0525: PreparedStatement stmt = null;
0526: RoleImpl role = null;
0527:
0528: try {
0529: conn = context.getDataSource().getConnection();
0530: stmt = conn.prepareStatement(SELECT_ROLE_WHERE_NAME);
0531: stmt.setString(1, roleName);
0532: ResultSet rs = stmt.executeQuery();
0533:
0534: if (rs.next()) {
0535: long id = rs.getLong(1);
0536: String name = rs.getString(2);
0537: String description = rs.getString(3);
0538: Date lastModified = rs.getTimestamp(4);
0539: long lastModifier = rs.getLong(5);
0540: long updateCount = rs.getLong(6);
0541:
0542: role = new RoleImpl(this , name, requestingUser);
0543: RoleImpl.IntimateAccess roleInt = role
0544: .getIntimateAccess(this );
0545: roleInt.saved(id, name, description, updateCount);
0546: roleInt.setLastModified(lastModified);
0547: roleInt.setLastModifier(lastModifier);
0548:
0549: } else {
0550: throw new RoleNotFoundException(roleName);
0551: }
0552: rs.close();
0553: } catch (Exception e) {
0554: if (e instanceof UserManagementException)
0555: throw (UserManagementException) e;
0556: else
0557: throw new UserManagementException(
0558: "Error while loading role with name "
0559: + roleName + ".", e);
0560: } finally {
0561: jdbcHelper.closeStatement(stmt);
0562: jdbcHelper.closeConnection(conn);
0563: }
0564:
0565: return role;
0566: }
0567:
0568: private Role getRoleWhereId(long roleId,
0569: AuthenticatedUser requestingUser)
0570: throws UserManagementException {
0571: Connection conn = null;
0572: PreparedStatement stmt = null;
0573: RoleImpl role = null;
0574:
0575: try {
0576: conn = context.getDataSource().getConnection();
0577: stmt = conn.prepareStatement(SELECT_ROLE_WHERE_ID);
0578: stmt.setLong(1, roleId);
0579: ResultSet rs = stmt.executeQuery();
0580:
0581: if (rs.next()) {
0582: long id = rs.getLong(1);
0583: String name = rs.getString(2);
0584: String description = rs.getString(3);
0585: Date lastModified = rs.getTimestamp(4);
0586: long lastModifier = rs.getLong(5);
0587: long updateCount = rs.getLong(6);
0588:
0589: role = new RoleImpl(this , name, requestingUser);
0590: RoleImpl.IntimateAccess roleInt = role
0591: .getIntimateAccess(this );
0592: roleInt.saved(id, name, description, updateCount);
0593: roleInt.setLastModified(lastModified);
0594: roleInt.setLastModifier(lastModifier);
0595:
0596: } else {
0597: throw new UserManagementException(
0598: "No role found with id " + roleId);
0599: }
0600: rs.close();
0601: } catch (Exception e) {
0602: throw new UserManagementException(
0603: "Error while loading role with id " + roleId + ".",
0604: e);
0605: } finally {
0606: jdbcHelper.closeStatement(stmt);
0607: jdbcHelper.closeConnection(conn);
0608: }
0609:
0610: return role;
0611: }
0612:
0613: public void store(UserImpl user) throws UserManagementException {
0614: logger.debug("starting storage of user");
0615:
0616: if (user.getId() == 1) {
0617: throw new UserManagementException(
0618: "User $system is read-only.");
0619: }
0620:
0621: UserImpl.IntimateAccess userInt = user.getIntimateAccess(this );
0622:
0623: // New users can only be created by administrators, for restrictions on updating of users, see further on
0624: if (user.getId() == -1
0625: && !userInt.getCurrentUser().isInAdministratorRole())
0626: throw new UserManagementException(
0627: "Only Administrators can update user records.");
0628:
0629: if (user.getId() == -1
0630: && user.getAuthenticationScheme().equals("daisy")
0631: && userInt.getPassword() == null) {
0632: throw new UserManagementException(
0633: "Password is required if the authentication scheme is daisy.");
0634: }
0635:
0636: if (userInt.getPassword() != null
0637: && !UserImpl.isValidPassword(userInt.getPassword())) {
0638: throw new UserManagementException(
0639: "Password does not adhere to password rules.");
0640: }
0641:
0642: if (user.getDefaultRole() != null) {
0643: if (!user.hasRole(user.getDefaultRole().getId())) {
0644: throw new UserManagementException(
0645: "The user has a default role that does not belong to its assigned roles.");
0646: }
0647: }
0648:
0649: if (user.getAllRoles().getArray().length < 1) {
0650: throw new UserManagementException(
0651: "A user must have at least one role.");
0652: }
0653:
0654: long id = user.getId();
0655: boolean isNew = (id == -1);
0656:
0657: Connection conn = null;
0658: PreparedStatement stmt = null;
0659: try {
0660: conn = context.getDataSource().getConnection();
0661: //we need transaction for this one...
0662: jdbcHelper.startTransaction(conn);
0663:
0664: String login = user.getLogin();
0665: java.util.Date lastModified = new Date();
0666: logger
0667: .debug("the last_modified date that will be stored is "
0668: + lastModified);
0669:
0670: /* The (authenticated)user that requested the administrative user object is now persisting it,
0671: * therefore he will be the last modifier
0672: */
0673: long lastModifier = userInt.getCurrentUser().getId();
0674: XmlObject eventDescription;
0675:
0676: if (id == -1) {
0677: // first test if the login already exists so that we can throw a nice exception in that case
0678: stmt = conn
0679: .prepareStatement("select id from users where login = ?");
0680: stmt.setString(1, login);
0681: ResultSet rs = stmt.executeQuery();
0682: if (rs.next())
0683: throw new DuplicateLoginException(login);
0684: stmt.close();
0685:
0686: //a new user must be stored in the data store
0687: stmt = conn
0688: .prepareStatement("insert into users(id, login, password, default_role, first_name, last_name, email, updateable_by_user, confirmed, confirmkey, auth_scheme, last_modified, last_modifier, updatecount) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
0689: id = context.getNextUserId();
0690: stmt.setLong(1, id);
0691: stmt.setString(2, login);
0692: stmt.setString(3, hashPassword(userInt.getPassword()));
0693: stmt.setLong(4, user.getDefaultRole() == null ? -1
0694: : user.getDefaultRole().getId());
0695: stmt.setString(5, user.getFirstName());
0696: stmt.setString(6, user.getLastName());
0697: stmt.setString(7, user.getEmail());
0698: stmt.setBoolean(8, user.isUpdateableByUser());
0699: stmt.setBoolean(9, user.isConfirmed());
0700: stmt.setString(10, user.getConfirmKey());
0701: stmt.setString(11, user.getAuthenticationScheme());
0702: stmt.setTimestamp(12, new Timestamp(lastModified
0703: .getTime()));
0704: stmt.setLong(13, lastModifier);
0705: stmt.setLong(14, 1L);
0706: stmt.executeUpdate();
0707:
0708: storeRolesForUser(user, id, conn);
0709:
0710: eventDescription = createUserCreatedEvent(user, id,
0711: lastModified);
0712: } else {
0713: //we have to update an existing user
0714: UserImpl oldUser = getUser(user.getId(), userInt
0715: .getCurrentUser());
0716:
0717: if (!userInt.getCurrentUser().isInAdministratorRole()) {
0718: if (!oldUser.isUpdateableByUser()
0719: || (user.getId() != userInt
0720: .getCurrentUser().getId())) {
0721: throw new UserManagementException(
0722: "Updating the user "
0723: + user.getId()
0724: + " is not allowed for user "
0725: + userInt.getCurrentUser()
0726: .getId());
0727: }
0728:
0729: if (!oldUser.isConfirmed()) {
0730: throw new UserManagementException(
0731: "A non-confimred user cannot by changed by a non-Administrator.");
0732: }
0733:
0734: if (userInt.hasRoleChanges()
0735: || (user.getDefaultRole() == null && oldUser
0736: .getDefaultRole() != null)
0737: || (user.getDefaultRole() != null && user
0738: .getDefaultRole().getId() != oldUser
0739: .getDefaultRole().getId())
0740: || !user.getLogin().equals(
0741: oldUser.getLogin())) {
0742: throw new UserManagementException(
0743: "Changes to the roles or login of a user can only be done by an Administrator.");
0744: }
0745: }
0746:
0747: String oldPassword;
0748: // check if nobody else changed it in the meantime, and load previous password
0749: stmt = conn
0750: .prepareStatement("select updatecount, password from users where id = ? "
0751: + jdbcHelper.getSharedLockClause());
0752: stmt.setLong(1, id);
0753: ResultSet rs = stmt.executeQuery();
0754: if (!rs.next()) {
0755: throw new UserManagementException(
0756: "Unexpected error: the User with id "
0757: + id
0758: + " does not exist in the database.");
0759: } else {
0760: long dbUpdateCount = rs.getLong(1);
0761: if (dbUpdateCount != user.getUpdateCount()) {
0762: throw new ConcurrentUpdateException(User.class
0763: .getName(), String
0764: .valueOf(user.getId()));
0765: }
0766: oldPassword = rs.getString(2);
0767: }
0768: stmt.close();
0769:
0770: if (!oldUser.getLogin().equals(user.getLogin())) {
0771: // login changed, test if there is already a user with the new login so that we can
0772: // throw a nice exception in that case
0773: stmt = conn
0774: .prepareStatement("select id from users where login = ?");
0775: stmt.setString(1, login);
0776: ResultSet rs2 = stmt.executeQuery();
0777: if (rs2.next() && rs2.getLong(1) != user.getId())
0778: throw new DuplicateLoginException(login);
0779: stmt.close();
0780: }
0781:
0782: //first see if there were role changes
0783: if (userInt.hasRoleChanges()) {
0784: stmt = conn
0785: .prepareStatement("delete from user_roles where user_id=?");
0786: stmt.setLong(1, user.getId());
0787:
0788: stmt.executeUpdate();
0789: stmt.close();
0790: }
0791:
0792: long newUpdateCount = user.getUpdateCount() + 1;
0793:
0794: String password = null;
0795: if (user.getAuthenticationScheme().equals("daisy")) {
0796: password = userInt.getPassword() == null ? oldPassword
0797: : hashPassword(userInt.getPassword());
0798: if (password == null)
0799: throw new UserManagementException(
0800: "If the authentication scheme is daisy, then the password is required.");
0801: }
0802:
0803: stmt = conn
0804: .prepareStatement("update users set login=?, password=?, default_role=?, first_name=?, last_name=?, email=?, updateable_by_user=?, confirmed=?, confirmkey=?, auth_scheme=?, last_modified=?, last_modifier=?, updatecount=? where id=?");
0805: stmt.setString(1, login);
0806: stmt.setString(2, password);
0807: stmt.setLong(3, user.getDefaultRole() == null ? -1
0808: : user.getDefaultRole().getId());
0809: stmt.setString(4, user.getFirstName());
0810: stmt.setString(5, user.getLastName());
0811: stmt.setString(6, user.getEmail());
0812: stmt.setBoolean(7, user.isUpdateableByUser());
0813: stmt.setBoolean(8, user.isConfirmed());
0814: stmt.setString(9, user.getConfirmKey());
0815: stmt.setString(10, user.getAuthenticationScheme());
0816: stmt.setTimestamp(11, new Timestamp(lastModified
0817: .getTime()));
0818: stmt.setLong(12, lastModifier);
0819: stmt.setLong(13, newUpdateCount);
0820: stmt.setLong(14, user.getId());
0821:
0822: stmt.executeUpdate();
0823: storeRolesForUser(user, user.getId(), conn);
0824:
0825: eventDescription = createUserUpdatedEvent(oldUser,
0826: user, lastModified, newUpdateCount);
0827: }
0828:
0829: eventHelper.createEvent(eventDescription,
0830: isNew ? "UserCreated" : "UserUpdated", conn);
0831:
0832: //everything went ok, so we can actively update the user OBJECT as well.
0833: conn.commit();
0834: userInt.saved(id, user.getFirstName(), user.getLastName(),
0835: user.getEmail(), lastModified, lastModifier, user
0836: .getUpdateCount() + 1);
0837:
0838: } catch (Throwable e) {
0839: jdbcHelper.rollback(conn);
0840: if (e instanceof DuplicateLoginException)
0841: throw (DuplicateLoginException) e;
0842: else
0843: throw new UserManagementException(
0844: "Error storing user.", e);
0845: } finally {
0846: jdbcHelper.closeStatement(stmt);
0847: jdbcHelper.closeConnection(conn);
0848: }
0849:
0850: // fire synchronous events
0851: if (isNew)
0852: context.getCommonRepository().fireRepositoryEvent(
0853: RepositoryEventType.USER_CREATED, new Long(id),
0854: user.getUpdateCount());
0855: else
0856: context.getCommonRepository().fireRepositoryEvent(
0857: RepositoryEventType.USER_UPDATED, new Long(id),
0858: user.getUpdateCount());
0859: }
0860:
0861: public static String hashPassword(String password) {
0862: if (password == null)
0863: return null;
0864: try {
0865: byte[] data = password.getBytes("UTF-8");
0866: MessageDigest digest = MessageDigest.getInstance("SHA-1");
0867: digest.update(data);
0868: byte[] result = digest.digest();
0869: return toHexString(result);
0870: } catch (Exception e) {
0871: throw new RuntimeException(
0872: "Problem calculating password hash.", e);
0873: }
0874: }
0875:
0876: public static String toHexString(byte[] b) {
0877: StringBuilder sb = new StringBuilder(b.length * 2);
0878: for (int i = 0; i < b.length; i++) {
0879: sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
0880: sb.append(hexChar[b[i] & 0x0f]);
0881: }
0882: return sb.toString();
0883: }
0884:
0885: static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7',
0886: '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
0887:
0888: private UserCreatedDocument createUserCreatedEvent(UserImpl user,
0889: long id, Date lastModified) {
0890: UserDocument.User userXml = user.getXml().getUser();
0891: userXml.setId(id);
0892: userXml.setLastModified(getCalendar(lastModified));
0893: userXml.setLastModifier(user.getIntimateAccess(this )
0894: .getCurrentUser().getId());
0895: userXml.setUpdateCount(1);
0896: if (userXml.isSetPassword())
0897: userXml.unsetPassword();
0898:
0899: UserCreatedDocument userCreatedDocument = UserCreatedDocument.Factory
0900: .newInstance();
0901: userCreatedDocument.addNewUserCreated().addNewNewUser()
0902: .setUser(userXml);
0903:
0904: return userCreatedDocument;
0905: }
0906:
0907: private UserUpdatedDocument createUserUpdatedEvent(
0908: UserImpl oldUser, UserImpl newUser, Date lastModified,
0909: long newUpdateCount) {
0910: UserUpdatedDocument userUpdatedDocument = UserUpdatedDocument.Factory
0911: .newInstance();
0912: UserUpdatedDocument.UserUpdated userUpdated = userUpdatedDocument
0913: .addNewUserUpdated();
0914:
0915: UserDocument.User oldUserXml = oldUser.getXml().getUser();
0916: if (oldUserXml.isSetPassword())
0917: oldUserXml.unsetPassword();
0918: userUpdated.addNewOldUser().setUser(oldUserXml);
0919:
0920: UserDocument.User newUserXml = newUser.getXml().getUser();
0921: newUserXml.setLastModified(getCalendar(lastModified));
0922: newUserXml.setLastModifier(newUser.getIntimateAccess(this )
0923: .getCurrentUser().getId());
0924: newUserXml.setUpdateCount(newUpdateCount);
0925: if (newUserXml.isSetPassword())
0926: newUserXml.unsetPassword();
0927: userUpdated.addNewNewUser().setUser(newUserXml);
0928:
0929: return userUpdatedDocument;
0930: }
0931:
0932: private Calendar getCalendar(Date date) {
0933: GregorianCalendar calendar = new GregorianCalendar();
0934: calendar.setTime(date);
0935: return calendar;
0936: }
0937:
0938: /**
0939: * @param user the user to store the roles for
0940: * @param conn the connection to the data store containing users and roles
0941: */
0942: private void storeRolesForUser(UserImpl user, long userId,
0943: Connection conn) throws SQLException {
0944: logger.debug("ARRAY SIZE: "
0945: + user.getAllRoles().getArray().length);
0946: UserImpl.IntimateAccess userInt = user.getIntimateAccess(this );
0947:
0948: //can't do this because we haven't called the saved() method yet on the user!!!
0949: //long userId = user.getId();
0950:
0951: if (userInt.hasRoleChanges()) {
0952: logger.debug("there are role changes");
0953: PreparedStatement delRoles = null;
0954: PreparedStatement insertRoles = null;
0955: try {
0956: //first we need to delete the roles the user currently belongs to
0957: delRoles = conn.prepareStatement(DELETE_ROLES);
0958: delRoles.setLong(1, userId);
0959: delRoles.executeUpdate();
0960:
0961: //roles deleted, now we can store the current state
0962: insertRoles = conn.prepareStatement(INSERT_ROLES);
0963: Role[] userRoles = user.getAllRoles().getArray();
0964: for (Role role : userRoles) {
0965: insertRoles.setLong(1, role.getId());
0966: insertRoles.setLong(2, userId);
0967: insertRoles.executeUpdate();
0968: }
0969: } finally {
0970: jdbcHelper.closeStatement(delRoles);
0971: jdbcHelper.closeStatement(insertRoles);
0972: }
0973: }
0974: }
0975:
0976: public void store(RoleImpl role) throws UserManagementException {
0977:
0978: RoleImpl.IntimateAccess roleInt = role.getIntimateAccess(this );
0979:
0980: if (!roleInt.getCurrentUser().isInAdministratorRole())
0981: throw new UserManagementException(
0982: "Only Administrators can create or update roles.");
0983:
0984: long id = role.getId();
0985: boolean isNew = id == -1;
0986:
0987: Connection conn = null;
0988: PreparedStatement stmt = null;
0989: try {
0990: conn = context.getDataSource().getConnection();
0991: jdbcHelper.startTransaction(conn);
0992:
0993: String roleName = role.getName();
0994: java.util.Date lastModified = new Date();
0995:
0996: /* The user that requested the role is now persisting it,
0997: * therefore he will be the last modifier
0998: */
0999: long lastModifier = roleInt.getCurrentUser().getId();
1000: XmlObject eventDescription;
1001:
1002: if (id == -1) {
1003: //a new role must be stored in the data store
1004: stmt = conn
1005: .prepareStatement("insert into roles(id, name, description, last_modified, last_modifier, updatecount) values (?,?,?,?,?,?)");
1006: id = context.getNextRoleId();
1007: stmt.setLong(1, id);
1008: stmt.setString(2, roleName);
1009: stmt.setString(3, role.getDescription());
1010: stmt.setTimestamp(4, new Timestamp(lastModified
1011: .getTime()));
1012: stmt.setLong(5, lastModifier);
1013: stmt.setLong(6, 1);
1014: stmt.executeUpdate();
1015:
1016: eventDescription = createRoleCreatedEvent(role, id,
1017: lastModified);
1018: } else {
1019: //we have to update an existing role
1020:
1021: // check if nobody else changed it in the meantime
1022: stmt = conn
1023: .prepareStatement("select updatecount from roles where id = ? "
1024: + jdbcHelper.getSharedLockClause());
1025: stmt.setLong(1, id);
1026: ResultSet rs = stmt.executeQuery();
1027: if (!rs.next()) {
1028: throw new UserManagementException(
1029: "Unexpected error: the Role with id "
1030: + id
1031: + " does not exist in the database.");
1032: } else {
1033: long dbUpdateCount = rs.getLong(1);
1034: if (dbUpdateCount != role.getUpdateCount()) {
1035: throw new ConcurrentUpdateException(Role.class
1036: .getName(), String
1037: .valueOf(role.getId()));
1038: }
1039: }
1040: stmt.close();
1041:
1042: RoleImpl oldRole = getRole(role.getId(), roleInt
1043: .getCurrentUser());
1044: long newUpdateCount = role.getUpdateCount() + 1;
1045:
1046: stmt = conn
1047: .prepareStatement("update roles set name=?, description=?, last_modified=?, last_modifier=?, updatecount=? where id=?");
1048: stmt.setString(1, roleName);
1049: stmt.setString(2, role.getDescription());
1050: stmt.setTimestamp(3, new Timestamp(lastModified
1051: .getTime()));
1052: stmt.setLong(4, lastModifier);
1053: stmt.setLong(5, newUpdateCount);
1054: stmt.setLong(6, id);
1055: stmt.executeUpdate();
1056:
1057: eventDescription = createRoleUpdatedEvent(oldRole,
1058: role, lastModified, newUpdateCount);
1059: }
1060:
1061: eventHelper.createEvent(eventDescription,
1062: isNew ? "RoleCreated" : "RoleUpdated", conn);
1063:
1064: conn.commit();
1065:
1066: //everything went ok, so we can actively update the role OBJECT as well.
1067: roleInt.saved(id, roleName, role.getDescription(), role
1068: .getUpdateCount() + 1);
1069: roleInt.setLastModified(lastModified);
1070: roleInt.setLastModifier(lastModifier);
1071:
1072: } catch (Throwable e) {
1073: jdbcHelper.rollback(conn);
1074: throw new UserManagementException("Error storing role.", e);
1075: } finally {
1076: jdbcHelper.closeStatement(stmt);
1077: jdbcHelper.closeConnection(conn);
1078: }
1079:
1080: // fire synchronous events
1081: if (isNew)
1082: context.getCommonRepository().fireRepositoryEvent(
1083: RepositoryEventType.ROLE_CREATED, new Long(id),
1084: role.getUpdateCount());
1085: else
1086: context.getCommonRepository().fireRepositoryEvent(
1087: RepositoryEventType.ROLE_UPDATED, new Long(id),
1088: role.getUpdateCount());
1089: }
1090:
1091: private RoleCreatedDocument createRoleCreatedEvent(RoleImpl role,
1092: long id, Date lastModified) {
1093: RoleCreatedDocument roleCreatedDocument = RoleCreatedDocument.Factory
1094: .newInstance();
1095:
1096: RoleDocument.Role roleXml = role.getXml().getRole();
1097: roleXml.setId(id);
1098: roleXml.setLastModified(getCalendar(lastModified));
1099: roleXml.setLastModifier(role.getIntimateAccess(this )
1100: .getCurrentUser().getId());
1101: roleXml.setUpdateCount(1);
1102:
1103: roleCreatedDocument.addNewRoleCreated().addNewNewRole()
1104: .setRole(roleXml);
1105:
1106: return roleCreatedDocument;
1107: }
1108:
1109: private RoleUpdatedDocument createRoleUpdatedEvent(
1110: RoleImpl oldRole, RoleImpl newRole, Date lastModified,
1111: long newUpdateCount) {
1112: RoleUpdatedDocument roleUpdatedDocument = RoleUpdatedDocument.Factory
1113: .newInstance();
1114: RoleUpdatedDocument.RoleUpdated roleUpdated = roleUpdatedDocument
1115: .addNewRoleUpdated();
1116: roleUpdated.addNewOldRole().setRole(oldRole.getXml().getRole());
1117:
1118: RoleDocument.Role newRoleXml = newRole.getXml().getRole();
1119: newRoleXml.setLastModified(getCalendar(lastModified));
1120: newRoleXml.setLastModifier(newRole.getIntimateAccess(this )
1121: .getCurrentUser().getId());
1122: newRoleXml.setUpdateCount(newUpdateCount);
1123:
1124: roleUpdated.addNewNewRole().setRole(newRoleXml);
1125:
1126: return roleUpdatedDocument;
1127: }
1128:
1129: public UserImpl getUser(long userId,
1130: AuthenticatedUser requestingUser)
1131: throws UserManagementException {
1132: if (userId != requestingUser.getId()
1133: && !requestingUser.isInAdministratorRole())
1134: throw new UserManagementException(
1135: "Non-Administrator users can only access their own user record.");
1136:
1137: Connection conn = null;
1138: PreparedStatement stmt = null;
1139: UserImpl user = null;
1140:
1141: try {
1142: conn = context.getDataSource().getConnection();
1143: stmt = conn.prepareStatement(SELECT_USER_WHERE_ID);
1144: stmt.setLong(1, userId);
1145: ResultSet rs = stmt.executeQuery();
1146:
1147: if (rs.next()) {
1148: user = getUserFromResultSet(rs, requestingUser);
1149: } else {
1150: throw new UserNotFoundException(userId);
1151: }
1152:
1153: rs.close();
1154: } catch (Exception e) {
1155: if (e instanceof UserManagementException)
1156: throw (UserManagementException) e;
1157: else
1158: throw new UserManagementException(
1159: "Error while loading user with id " + userId
1160: + ".", e);
1161: } finally {
1162: jdbcHelper.closeStatement(stmt);
1163: jdbcHelper.closeConnection(conn);
1164: }
1165: return user;
1166: }
1167:
1168: public RoleImpl getRole(long roleId,
1169: AuthenticatedUser requestingUser)
1170: throws UserManagementException {
1171: Connection conn = null;
1172: PreparedStatement stmt = null;
1173: RoleImpl role = null;
1174:
1175: try {
1176: conn = context.getDataSource().getConnection();
1177: stmt = conn.prepareStatement(SELECT_ROLE_WHERE_ID);
1178: stmt.setLong(1, roleId);
1179: ResultSet rs = stmt.executeQuery();
1180:
1181: if (rs.next()) {
1182: long id = rs.getLong(1);
1183: String name = rs.getString(2);
1184: String description = rs.getString(3);
1185: Date lastModified = rs.getTimestamp(4);
1186: long lastModifier = rs.getLong(5);
1187: long updateCount = rs.getLong(6);
1188:
1189: role = new RoleImpl(this , name, requestingUser);
1190: RoleImpl.IntimateAccess roleInt = role
1191: .getIntimateAccess(this );
1192: roleInt.saved(id, name, description, updateCount);
1193: roleInt.setLastModified(lastModified);
1194: roleInt.setLastModifier(lastModifier);
1195:
1196: } else {
1197: throw new RoleNotFoundException(roleId);
1198: }
1199: rs.close();
1200: } catch (Exception e) {
1201: if (e instanceof UserManagementException)
1202: throw (UserManagementException) e;
1203: else
1204: throw new UserManagementException(
1205: "Error while loading role with id " + roleId
1206: + ".", e);
1207: } finally {
1208: jdbcHelper.closeStatement(stmt);
1209: jdbcHelper.closeConnection(conn);
1210: }
1211:
1212: return role;
1213: }
1214:
1215: public UsersImpl getUsersByEmail(String email,
1216: AuthenticatedUser requestingUser)
1217: throws RepositoryException {
1218: if (!requestingUser.isInAdministratorRole())
1219: throw new UserManagementException(
1220: "Non-Administrator users cannot retrieve other users then themselve.");
1221:
1222: Connection conn = null;
1223: PreparedStatement stmt = null;
1224: List<User> users = new ArrayList<User>();
1225:
1226: try {
1227: conn = context.getDataSource().getConnection();
1228:
1229: stmt = conn.prepareStatement(SELECT_USERS_WHERE_EMAIL);
1230: stmt.setString(1, email);
1231: ResultSet rs = stmt.executeQuery();
1232:
1233: while (rs.next()) {
1234: UserImpl user = getUserFromResultSet(rs, requestingUser);
1235: users.add(user);
1236: }
1237: } catch (Exception e) {
1238: throw new UserManagementException(
1239: "Error while loading list of users by email.", e);
1240: } finally {
1241: jdbcHelper.closeStatement(stmt);
1242: jdbcHelper.closeConnection(conn);
1243: }
1244:
1245: return new UsersImpl(users.toArray(new User[users.size()]));
1246: }
1247:
1248: public PublicUserInfo getPublicUserInfo(long userId,
1249: AuthenticatedUser user) throws RepositoryException {
1250: return getUser(userId, systemUser).getPublicUserInfo();
1251: }
1252:
1253: public PublicUserInfo getPublicUserInfo(String login,
1254: AuthenticatedUser user) throws RepositoryException {
1255: return getUser(login, systemUser).getPublicUserInfo();
1256: }
1257:
1258: public PublicUserInfos getPublicUserInfos(AuthenticatedUser user)
1259: throws RepositoryException {
1260: Connection conn = null;
1261: PreparedStatement stmt = null;
1262: List<PublicUserInfo> users = new ArrayList<PublicUserInfo>();
1263:
1264: try {
1265: conn = context.getDataSource().getConnection();
1266:
1267: stmt = conn
1268: .prepareStatement("select id, login, first_name, last_name from users");
1269: ResultSet rs = stmt.executeQuery();
1270:
1271: while (rs.next()) {
1272: String login = rs.getString(2);
1273: String firstName = rs.getString(3);
1274: String lastName = rs.getString(4);
1275: String displayName = UserImpl.getDisplayName(firstName,
1276: lastName, login);
1277: users.add(new PublicUserInfoImpl(rs.getLong(1), login,
1278: displayName));
1279: }
1280: } catch (Exception e) {
1281: throw new UserManagementException(
1282: "Error while loading public info of all users.", e);
1283: } finally {
1284: jdbcHelper.closeStatement(stmt);
1285: jdbcHelper.closeConnection(conn);
1286: }
1287:
1288: return new PublicUserInfosImpl(users
1289: .toArray(new PublicUserInfo[users.size()]));
1290: }
1291:
1292: public AuthenticationSchemeInfos getAuthenticationSchemes(
1293: AuthenticatedUser requestingUser) {
1294: return context.getUserAuthenticator()
1295: .getAuthenticationSchemes();
1296: }
1297: }
|