diff --git a/spring-security-login-and-registration/pom.xml b/spring-security-login-and-registration/pom.xml
index 89ef8d571c..2f0988ea2d 100644
--- a/spring-security-login-and-registration/pom.xml
+++ b/spring-security-login-and-registration/pom.xml
@@ -67,6 +67,14 @@
test
+
+
+ org.passay
+ passay
+ 1.0
+
+
+
org.springframework.data
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/IUserService.java b/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/IUserService.java
index 50466449a1..7ec07e9488 100644
--- a/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/IUserService.java
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/IUserService.java
@@ -32,4 +32,6 @@ public interface IUserService {
User getUserByID(long id);
void changeUserPassword(User user, String password);
+
+ boolean checkIfValidOldPassword(User user, String password);
}
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserDto.java b/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserDto.java
index feaa3351e3..627aac81c4 100644
--- a/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserDto.java
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserDto.java
@@ -1,32 +1,32 @@
package org.baeldung.persistence.service;
import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
import org.baeldung.validation.PasswordMatches;
import org.baeldung.validation.ValidEmail;
-import org.hibernate.validator.constraints.NotEmpty;
+import org.baeldung.validation.ValidPassword;
@PasswordMatches
public class UserDto {
@NotNull
- @NotEmpty
+ @Size(min = 1)
private String firstName;
@NotNull
- @NotEmpty
+ @Size(min = 1)
private String lastName;
- @NotNull
- @NotEmpty
+ @ValidPassword
private String password;
@NotNull
- @NotEmpty
+ @Size(min = 1)
private String matchingPassword;
@ValidEmail
@NotNull
- @NotEmpty
+ @Size(min = 1)
private String email;
public String getEmail() {
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserService.java b/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserService.java
index b9509f4f3a..fafe52953f 100644
--- a/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserService.java
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/persistence/service/UserService.java
@@ -120,6 +120,11 @@ public class UserService implements IUserService {
repository.save(user);
}
+ @Override
+ public boolean checkIfValidOldPassword(final User user, final String oldPassword) {
+ return passwordEncoder.matches(oldPassword, user.getPassword());
+ }
+
private boolean emailExist(final String email) {
final User user = repository.findByEmail(email);
if (user != null) {
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/security/AuthenticationFailureListener.java b/spring-security-login-and-registration/src/main/java/org/baeldung/security/AuthenticationFailureListener.java
index 3f1702defe..dc550d8c04 100644
--- a/spring-security-login-and-registration/src/main/java/org/baeldung/security/AuthenticationFailureListener.java
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/security/AuthenticationFailureListener.java
@@ -14,6 +14,8 @@ public class AuthenticationFailureListener implements ApplicationListener {
+
+ @Override
+ public void initialize(final ValidPassword arg0) {
+
+ }
+
+ @Override
+ public boolean isValid(final String password, final ConstraintValidatorContext context) {
+ final PasswordValidator validator = new PasswordValidator(Arrays.asList(new LengthRule(8, 30), new UppercaseCharacterRule(1), new DigitCharacterRule(1), new SpecialCharacterRule(1), new WhitespaceRule()));
+ final RuleResult result = validator.validate(new PasswordData(password));
+ if (result.isValid()) {
+ return true;
+ }
+ context.disableDefaultConstraintViolation();
+ context.buildConstraintViolationWithTemplate(Joiner.on("\n").join(validator.getMessages(result))).addConstraintViolation();
+ return false;
+ }
+
+}
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/validation/ValidPassword.java b/spring-security-login-and-registration/src/main/java/org/baeldung/validation/ValidPassword.java
new file mode 100644
index 0000000000..37b217213a
--- /dev/null
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/validation/ValidPassword.java
@@ -0,0 +1,27 @@
+package org.baeldung.validation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Documented
+@Constraint(validatedBy = PasswordConstraintValidator.class)
+@Target({ TYPE, FIELD, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+public @interface ValidPassword {
+
+ String message() default "Invalid Password";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+}
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/web/controller/RegistrationController.java b/spring-security-login-and-registration/src/main/java/org/baeldung/web/controller/RegistrationController.java
index 10f2c64bc5..ab8d3feb66 100644
--- a/spring-security-login-and-registration/src/main/java/org/baeldung/web/controller/RegistrationController.java
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/web/controller/RegistrationController.java
@@ -14,6 +14,7 @@ import org.baeldung.persistence.service.IUserService;
import org.baeldung.persistence.service.UserDto;
import org.baeldung.registration.OnRegistrationCompleteEvent;
import org.baeldung.validation.EmailExistsException;
+import org.baeldung.web.error.InvalidOldPasswordException;
import org.baeldung.web.error.UserAlreadyExistException;
import org.baeldung.web.error.UserNotFoundException;
import org.baeldung.web.util.GenericResponse;
@@ -133,7 +134,6 @@ public class RegistrationController {
final String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
final SimpleMailMessage email = constructResetTokenEmail(appUrl, request.getLocale(), token, user);
mailSender.send(email);
-
return new GenericResponse(messages.getMessage("message.resetPasswordEmail", null, request.getLocale()));
}
@@ -168,6 +168,19 @@ public class RegistrationController {
return new GenericResponse(messages.getMessage("message.resetPasswordSuc", null, locale));
}
+ // change user password
+
+ @RequestMapping(value = "/user/updatePassword", method = RequestMethod.POST)
+ @ResponseBody
+ public GenericResponse changeUserPassword(final Locale locale, @RequestParam("password") final String password, @RequestParam("oldpassword") final String oldPassword) {
+ final User user = userService.findUserByEmail(SecurityContextHolder.getContext().getAuthentication().getName());
+ if (!userService.checkIfValidOldPassword(user, oldPassword)) {
+ throw new InvalidOldPasswordException();
+ }
+ userService.changeUserPassword(user, password);
+ return new GenericResponse(messages.getMessage("message.updatePasswordSuc", null, locale));
+ }
+
// NON-API
private final SimpleMailMessage constructResendVerificationTokenEmail(final String contextPath, final Locale locale, final VerificationToken newToken, final User user) {
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/InvalidOldPasswordException.java b/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/InvalidOldPasswordException.java
new file mode 100644
index 0000000000..74b4e04c1a
--- /dev/null
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/InvalidOldPasswordException.java
@@ -0,0 +1,23 @@
+package org.baeldung.web.error;
+
+public final class InvalidOldPasswordException extends RuntimeException {
+
+ private static final long serialVersionUID = 5861310537366287163L;
+
+ public InvalidOldPasswordException() {
+ super();
+ }
+
+ public InvalidOldPasswordException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidOldPasswordException(final String message) {
+ super(message);
+ }
+
+ public InvalidOldPasswordException(final Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java b/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java
index 58c089a733..c74cf25c2b 100644
--- a/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java
+++ b/spring-security-login-and-registration/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java
@@ -29,7 +29,7 @@ public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionH
// 400
@Override
- protected ResponseEntity