class SecurityServiceImpl extends RemoteServiceServlet implements SecurityService {

	@Override
	public int changePassword(Long requestorUserId, long userId, String oldPassword, String newPassword,
			boolean notify) {
		try {
			UserDAO userDao = (UserDAO) Context.get().getBean(UserDAO.class);
			User user = userDao.findById(userId);
			if (user == null)
				throw new Exception(String.format("User %s not found", userId));
			userDao.initialize(user);

			User currentUser = null;
			try {
				currentUser = ServiceUtil.getSessionUser(getThreadLocalRequest());
			} catch (Throwable t) {
			}

			/*
			 * A non admin user cannot change the password of other users
			 */
			MenuDAO mDao = (MenuDAO) Context.get().getBean(MenuDAO.class);
			if (currentUser != null && currentUser.getId() != userId
					&& !mDao.isReadEnable(Menu.SECURITY, currentUser.getId()))
				throw new Exception(String.format("User %s not allowed to change the password of user %s",
						currentUser.getUsername(), user.getUsername()));

			if (oldPassword != null && !CryptUtil.cryptString(oldPassword).equals(user.getPassword()))
				throw new Exception("Wrong old passord");

			UserHistory history = null;
			// The password was changed
			user.setDecodedPassword(newPassword);
			user.setPasswordChanged(new Date());
			user.setRepass("");

			// Add a user history entry
			history = new UserHistory();
			history.setUser(user);
			history.setEvent(UserEvent.PASSWORDCHANGED.toString());
			history.setComment("");

			/*
			 * If the credentials must be notified, we have to mark the password
			 * as expired for security reasons, so the user will change it at
			 * first login.
			 */
			user.setPasswordExpired(notify || requestorUserId == null || !requestorUserId.equals(userId) ? 1 : 0);

			boolean stored = userDao.store(user, history);

			if (!stored)
				throw new Exception("User not stored");

			if (notify)
				try {
					notifyAccount(user, newPassword);
				} catch (Throwable e) {
					log.warn(e.getMessage(), e);
					return 2;
				}
			return 0;
		} catch (Throwable e) {
			log.error(e.getMessage(), e);
			return 1;
		}
	}

}