experimental access code for RbacUserEntity
This commit is contained in:
parent
1451e7b661
commit
2abe88eb15
@ -3,7 +3,12 @@ package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
import lombok.*;
|
||||
import org.springframework.data.annotation.Immutable;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@ -16,8 +21,35 @@ import java.util.UUID;
|
||||
@AllArgsConstructor
|
||||
public class RbacUserEntity {
|
||||
|
||||
private static final int MAX_VALIDITY_DAYS = 21;
|
||||
private static DateTimeFormatter DATE_FORMAT_WITH_FULLHOUR = DateTimeFormatter.ofPattern("MM-dd-yyyy HH");
|
||||
|
||||
@Id
|
||||
private UUID uuid;
|
||||
|
||||
private String name;
|
||||
|
||||
public String generateAccessCode() {
|
||||
return generateAccessCode(LocalDateTime.now());
|
||||
}
|
||||
|
||||
public boolean isValidAccessCode(final String accessCode, final int validityHours) {
|
||||
if (validityHours > 24 * MAX_VALIDITY_DAYS) {
|
||||
throw new IllegalArgumentException("Max validity (%s days) exceeded.".formatted(MAX_VALIDITY_DAYS));
|
||||
}
|
||||
if (generateAccessCode(LocalDateTime.now().minus(validityHours, ChronoUnit.HOURS)).equals(accessCode)) {
|
||||
return true;
|
||||
}
|
||||
if (validityHours < 0) {
|
||||
return false;
|
||||
}
|
||||
return isValidAccessCode(accessCode, validityHours - 1);
|
||||
}
|
||||
|
||||
String generateAccessCode(final LocalDateTime timestamp) {
|
||||
final var compound = name + ":" + uuid + ":" + timestamp.format(DATE_FORMAT_WITH_FULLHOUR);
|
||||
final var code = String.valueOf(1000000 + Math.abs(compound.hashCode()) % 100000);
|
||||
return code.substring(1, 4) + ":" + code.substring(4, 7);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class RbacUserEntityUnitTest {
|
||||
|
||||
RbacUserEntity givenUser = new RbacUserEntity(UUID.randomUUID(), "test@example.org");
|
||||
|
||||
@Test
|
||||
void generatedAccessCodeMatchesDefinedPattern() {
|
||||
final var givenAccessCode = givenUser.generateAccessCode();
|
||||
|
||||
final var actual = givenAccessCode.matches("[0-9]{3}:[0-9]{3}");
|
||||
|
||||
assertThat(actual).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void freshAccessCodeIsValid() {
|
||||
final var givenAccessCode = givenUser.generateAccessCode();
|
||||
|
||||
final var actual = givenUser.isValidAccessCode(givenAccessCode, 4);
|
||||
|
||||
assertThat(actual).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void recentEnoughAccessCodeIsValid() {
|
||||
final var givenAccessCode = givenUser.generateAccessCode(LocalDateTime.now().minus(4, ChronoUnit.HOURS));
|
||||
|
||||
final var actual = givenUser.isValidAccessCode(givenAccessCode, 4);
|
||||
|
||||
assertThat(actual).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void outdatedEnoughAccessCodeIsNotValid() {
|
||||
final var givenAccessCode = givenUser.generateAccessCode(LocalDateTime.now().minus(5, ChronoUnit.HOURS));
|
||||
|
||||
final var actual = givenUser.isValidAccessCode(givenAccessCode, 4);
|
||||
|
||||
assertThat(actual).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noExceptionIsThrowIfMaxValidityIsNotExceeded() {
|
||||
final var givenAccessCode = givenUser.generateAccessCode();
|
||||
|
||||
givenUser.isValidAccessCode(givenAccessCode, 24 * 21);
|
||||
}
|
||||
|
||||
@Test
|
||||
void illegalArgumentExceptionIsThrowIfMaxValidityIsExceeded() {
|
||||
final var givenAccessCode = givenUser.generateAccessCode();
|
||||
|
||||
assertThatThrownBy(() -> {
|
||||
givenUser.isValidAccessCode(givenAccessCode, 24 * 21 + 1);
|
||||
})
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Max validity (21 days) exceeded.");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user