public User changePassword()

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;
    }