Skip to content

Commit

Permalink
increase minimum password strength
Browse files Browse the repository at this point in the history
  • Loading branch information
Athou committed Jul 13, 2022
1 parent 9bbfc2d commit 899a8d7
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 13 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Expand Up @@ -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>
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/com/commafeed/backend/service/UserService.java
Expand Up @@ -92,19 +92,9 @@ public User register(String name, String password, String email, Collection<Role

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");
Expand Down
@@ -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());
}

}
23 changes: 23 additions & 0 deletions src/main/java/com/commafeed/frontend/auth/ValidPassword.java
@@ -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 {};
}
Expand Up @@ -2,6 +2,8 @@

import java.io.Serializable;

import com.commafeed.frontend.auth.ValidPassword;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
Expand All @@ -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")
Expand Down
Expand Up @@ -6,6 +6,8 @@
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;
Expand All @@ -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;

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/commafeed/frontend/resource/UserREST.java
Expand Up @@ -192,8 +192,7 @@ public Response getUserProfile(@ApiParam(hidden = true) @SecurityCheck User user
@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()));
Expand Down

0 comments on commit 899a8d7

Please sign in to comment.