in src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/ChangeUserPasswordServlet.java [238:342]
public User changePassword(Session jcrSession,
String name,
String oldPassword,
String newPassword,
String newPasswordConfirm,
List<Modification> changes)
throws RepositoryException {
if ("anonymous".equals(name)) {
throw new RepositoryException(
"Can not change the password of the anonymous user.");
}
User user;
UserManager userManager = AccessControlUtil.getUserManager(jcrSession);
Authorizable authorizable = userManager.getAuthorizable(name);
if (authorizable instanceof User) {
user = (User)authorizable;
} else {
throw new ResourceNotFoundException(
"User to update could not be determined");
}
//SLING-2069: if the current user is an administrator, then a missing oldPwd is ok,
// otherwise the oldPwd must be supplied.
boolean administrator = false;
// check that the submitted parameter values have valid values.
if (oldPassword == null || oldPassword.length() == 0) {
try {
UserManager um = AccessControlUtil.getUserManager(jcrSession);
User currentUser = (User) um.getAuthorizable(jcrSession.getUserID());
administrator = currentUser.isAdmin();
if (!administrator) {
//check if the user is a member of the 'User administrator' group
Authorizable userAdmin = um.getAuthorizable(this.userAdminGroupName);
if (userAdmin instanceof Group) {
boolean isMember = ((Group)userAdmin).isMember(currentUser);
if (isMember) {
administrator = true;
}
}
}
} catch ( Exception ex ) {
log.warn("Failed to determine if the user is an admin, assuming not. Cause: {}", ex.getMessage());
administrator = false;
}
if (!administrator) {
throw new RepositoryException("Old Password was not submitted");
}
}
if (newPassword == null || newPassword.length() == 0) {
throw new RepositoryException("New Password was not submitted");
}
if (!newPassword.equals(newPasswordConfirm)) {
throw new RepositoryException(
"New Password does not match the confirmation password");
}
if (oldPassword != null && oldPassword.length() > 0) {
// verify old password
if (alwaysAllowSelfChangePassword && jcrSession.getUserID().equals(name)) {
// first check if the current user has enough permissions to do this without
// the aid of a service session
AccessControlManager acm = jcrSession.getAccessControlManager();
boolean hasRights = acm.hasPrivileges(authorizable.getPath(), new Privilege[] {
acm.privilegeFromName(PrivilegeConstants.REP_USER_MANAGEMENT)
});
if (hasRights) {
// we are good to do this without an extra service session
user.changePassword(newPassword, oldPassword);
} else {
// the current user doesn't have enough permissions, so we'll need do
// do the work on their behalf as a service user
Session svcSession = null;
try {
svcSession = repository.loginService(null, null);
UserManager um = AccessControlUtil.getUserManager(svcSession);
User user2 = (User) um.getAuthorizable(name);
user2.changePassword(newPassword, oldPassword);
if (svcSession.hasPendingChanges()) {
svcSession.save();
}
} finally {
if (svcSession != null) {
svcSession.logout();
}
}
}
} else {
user.changePassword(newPassword, oldPassword);
}
} else {
user.changePassword(newPassword);
}
final String passwordPath = systemUserManagerPaths.getUserPrefix() + user.getID() + "/rep:password";
changes.add(Modification.onModified(passwordPath));
return user;
}