private void checkPasswordChangeIsAllowed(String userId, String oldPassword) {
    if (securityContextAccessor.isClient()) {
      // Trusted client (not acting on behalf of user)
      return;
    }

    // Call is by or on behalf of end user
    String currentUser = securityContextAccessor.getUserId();

    if (securityContextAccessor.isAdmin()) {

      // even an admin needs to provide the old value to change his
      // password
      if (userId.equals(currentUser) && !StringUtils.hasText(oldPassword)) {
        throw new InvalidPasswordException("Previous password is required even for admin");
      }

    } else {

      if (!userId.equals(currentUser)) {
        logger.warn(
            "User with id " + currentUser + " attempting to change password for user " + userId);
        // TODO: This should be audited when we have non-authentication
        // events in the log
        throw new InvalidPasswordException("Not permitted to change another user's password");
      }

      // User is changing their own password, old password is required
      if (!StringUtils.hasText(oldPassword)) {
        throw new InvalidPasswordException("Previous password is required");
      }
    }
  }
 @Test
 public void clientCanChangeUserPasswordWithoutCurrentPassword() {
   SecurityContextAccessor sca = mockSecurityContext(joel);
   when(sca.isClient()).thenReturn(true);
   endpoints.setSecurityContextAccessor(sca);
   PasswordChangeRequest change = new PasswordChangeRequest();
   change.setPassword("newpassword");
   endpoints.changePassword(joel.getId(), change);
 }
  private void checkPasswordChangeIsAllowed(ClientDetails clientDetails, String oldSecret) {

    if (!securityContextAccessor.isClient()) {
      // Trusted client (not acting on behalf of user)
      throw new IllegalStateException("Only a client can change client secret");
    }

    String clientId = clientDetails.getClientId();

    // Call is by client
    String currentClientId = securityContextAccessor.getClientId();

    if (securityContextAccessor.isAdmin()) {

      // even an admin needs to provide the old value to change password
      if (clientId.equals(currentClientId) && !StringUtils.hasText(oldSecret)) {
        throw new IllegalStateException("Previous secret is required even for admin");
      }

    } else {

      if (!clientId.equals(currentClientId)) {
        logger.warn(
            "Client with id "
                + currentClientId
                + " attempting to change password for client "
                + clientId);
        // TODO: This should be audited when we have non-authentication events in the log
        throw new IllegalStateException(
            "Bad request. Not permitted to change another client's secret");
      }

      // Client is changing their own secret, old password is required
      if (!StringUtils.hasText(oldSecret)) {
        throw new IllegalStateException("Previous secret is required");
      }
    }
  }