added configurable password validator and fixed mapstruct bugs

This commit is contained in:
Peter Straßer
2021-04-17 12:51:55 +02:00
parent fbe2a75d09
commit 76385f2c02
19 changed files with 73 additions and 47 deletions

View File

@@ -16,8 +16,9 @@
<description>Business logic for demo project</description>
<properties>
<java.version>14</java.version>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
<org.lombok.version>1.18.12</org.lombok.version>
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
<org.lombok.version>1.18.16</org.lombok.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
<dependencies>
<dependency>
@@ -49,7 +50,11 @@
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</dependency>
</dependencies>
<build>
@@ -72,6 +77,11 @@
<artifactId>lombok</artifactId>
<version>${org.lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
<compilerArgs>

View File

@@ -18,10 +18,10 @@ import java.util.Map;
public class Customer {
private final BigInteger id;
private String name;
private String hashedPassword;
private LocalDate birthday;
private int age;
private Map<Address.AddressType, Address> addresses;
private final String hashedPassword;
private final LocalDate birthday;
private final int age;
private final Map<Address.AddressType, Address> addresses;
private boolean active;
private Customer(

View File

@@ -1,7 +1,7 @@
package de.strasser.peter.hexagonal.application.customer.port.in.commands;
import de.strasser.peter.hexagonal.common.validators.SecurePassword;
import de.strasser.peter.hexagonal.application.customer.validator.SecurePassword;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -0,0 +1,48 @@
package de.strasser.peter.hexagonal.application.customer.validator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = SecurePassword.PasswordValidator.class)
public @interface SecurePassword {
String message() default
"# a digit must occur at least once\n"
+ "# a lower case letter must occur at least once\n"
+ "# an upper case letter must occur at least once\n"
+ "# a special character must occur at least once ( one of !@#$%^&*(),.?\":{}|<>) \n"
+ "# no whitespace allowed in the entire string\n"
+ "# anything, at least eight places though";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Component
class PasswordValidator implements ConstraintValidator<SecurePassword, String> {
private static final String DEFAULT_PASSWORD_REQUIREMENTS =
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?\":{}|<>])(?=\\S+$).{8,}$";
@Value("${password.format:" + DEFAULT_PASSWORD_REQUIREMENTS + "}")
private String pwFormat;
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
return s != null && s.matches(pwFormat);
}
}
}

View File

@@ -1,12 +1,13 @@
package de.strasser.peter.hexagonal.application;
import de.strasser.peter.hexagonal.application.customer.mapper.AddAddressMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.mock.mockito.SpyBean;
@Slf4j
@SpringBootApplication
public class TestConfiguration {
@SpyBean public AddAddressMapper addAddressMapperMock;
}

View File

@@ -2,7 +2,9 @@ package de.strasser.peter.hexagonal.application.customer.domain;
import de.strasser.peter.hexagonal.application.customer.exception.TooOldToDeactivateExc;
import de.strasser.peter.hexagonal.application.customer.exception.TooYoungExc;
import de.strasser.peter.hexagonal.application.customer.mapper.AddAddressMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import java.time.LocalDate;
import java.util.Collections;
@@ -11,6 +13,7 @@ import static org.junit.jupiter.api.Assertions.*;
class CustomerTest {
@Test
public void should_CreateNewCustomer() {
final var customer = Customer.newCustomer("name", "pw", LocalDate.of(1980, 1, 1));
@@ -58,4 +61,6 @@ class CustomerTest {
final Customer customer = Customer.newCustomer("name", "pw", LocalDate.of(1950, 1, 1));
assertThrows(TooOldToDeactivateExc.class, customer::deactivate);
}
}

View File

@@ -32,7 +32,6 @@ class AddressServiceTest {
@MockBean private SaveCustomerPort saveCustomerAdapterMock;
@MockBean private AddressValidatorPort addressValidatorAdapterMock;
@MockBean private LoadCustomerPort loadCustomerAdapterMock;
@SpyBean private AddAddressMapper addAddressMapperMock;
@Test
public void should_AddAddress() {

View File

@@ -30,8 +30,7 @@ class RegisterCustomerServiceTest {
private AddressValidatorPort addressValidatorAdapterMock;
@MockBean
private LoadCustomerPort loadCustomerAdapterMock;
@MockBean
private AddAddressMapper addAddressMapperMock;
@BeforeEach
public void setUp() {

View File

@@ -0,0 +1 @@
# password.format: ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*(),.?":{}|<>])(?=\S+$).{8,}$