increase minimum password strength

This commit is contained in:
Athou
2022-07-13 16:01:10 +02:00
parent 9bbfc2de3f
commit 899a8d746a
7 changed files with 89 additions and 13 deletions

View File

@@ -409,6 +409,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.passay</groupId>
<artifactId>passay</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>

View File

@@ -92,19 +92,9 @@ public class UserService {
public User register(String name, String password, String email, Collection<Role> roles, boolean forceRegistration) {
Preconditions.checkNotNull(name);
Preconditions.checkArgument(StringUtils.length(name) <= 32, "Name too long (32 characters maximum)");
Preconditions.checkNotNull(password);
if (!forceRegistration) {
Preconditions.checkState(config.getApplicationSettings().getAllowRegistrations(),
"Registrations are closed on this CommaFeed instance");
Preconditions.checkNotNull(email);
Preconditions.checkArgument(StringUtils.length(name) >= 3, "Name too short (3 characters minimum)");
Preconditions.checkArgument(forceRegistration || StringUtils.length(password) >= 6,
"Password too short (6 characters maximum)");
Preconditions.checkArgument(StringUtils.contains(email, "@"), "Invalid email address");
}
Preconditions.checkArgument(userDAO.findByName(name) == null, "Name already taken");

View File

@@ -0,0 +1,54 @@
package com.commafeed.frontend.auth;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.passay.CharacterRule;
import org.passay.EnglishCharacterData;
import org.passay.LengthRule;
import org.passay.PasswordData;
import org.passay.PasswordValidator;
import org.passay.RuleResult;
import org.passay.WhitespaceRule;
public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword, String> {
@Override
public void initialize(ValidPassword constraintAnnotation) {
// nothing to do
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
PasswordValidator validator = buildPasswordValidator();
RuleResult result = validator.validate(new PasswordData(value));
if (result.isValid()) {
return true;
}
List<String> messages = validator.getMessages(result);
String message = String.join(System.lineSeparator(), messages);
context.buildConstraintViolationWithTemplate(message).addConstraintViolation().disableDefaultConstraintViolation();
return false;
}
private PasswordValidator buildPasswordValidator() {
return new PasswordValidator(
// length
new LengthRule(8, 128),
// 1 uppercase char
new CharacterRule(EnglishCharacterData.UpperCase, 1),
// 1 lowercase char
new CharacterRule(EnglishCharacterData.LowerCase, 1),
// 1 digit
new CharacterRule(EnglishCharacterData.Digit, 1),
// 1 special char
new CharacterRule(EnglishCharacterData.Special, 1),
// no whitespace
new WhitespaceRule());
}
}

View File

@@ -0,0 +1,23 @@
package com.commafeed.frontend.auth;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {
String message() default "Invalid Password";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@@ -2,6 +2,8 @@ package com.commafeed.frontend.model.request;
import java.io.Serializable;
import com.commafeed.frontend.auth.ValidPassword;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -15,6 +17,7 @@ public class ProfileModificationRequest implements Serializable {
private String email;
@ApiModelProperty(value = "changes password of the user, if specified")
@ValidPassword
private String password;
@ApiModelProperty(value = "generate a new api key")

View File

@@ -6,6 +6,8 @@ import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import com.commafeed.frontend.auth.ValidPassword;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -21,7 +23,7 @@ public class RegistrationRequest implements Serializable {
private String name;
@ApiModelProperty(value = "password, minimum 6 characters", required = true)
@Length(min = 6)
@ValidPassword
@NotEmpty
private String password;

View File

@@ -192,8 +192,7 @@ public class UserREST {
@ApiOperation(value = "Save user's profile")
@Timed
public Response saveUserProfile(@ApiParam(hidden = true) @SecurityCheck User user,
@ApiParam(required = true) ProfileModificationRequest request) {
Preconditions.checkArgument(StringUtils.isBlank(request.getPassword()) || request.getPassword().length() >= 6);
@Valid @ApiParam(required = true) ProfileModificationRequest request) {
if (StringUtils.isNotBlank(request.getEmail())) {
User u = userDAO.findByEmail(request.getEmail());
Preconditions.checkArgument(u == null || user.getId().equals(u.getId()));