Skip to content

Commit

Permalink
#35 reserve usernames after name change for 6 month
Browse files Browse the repository at this point in the history
  • Loading branch information
Brutus5000 committed Oct 17, 2017
1 parent bf102be commit 2259ed2
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,6 @@ public static class Challonge {
@Data
public static class User {
private int minimumDaysBetweenUsernameChange = 30;
private int usernameReservationTimeInMonths = 6;
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/faforever/api/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public enum ErrorCode {
VALIDATION_FAILED(158, "Validation failed", "{0}"),
MOD_UID_EXISTS(159, "Duplicate mod UID", "A mod with UID ''{0}'' already exists."),
MOD_STRUCTURE_INVALID(160, "Invalid file structure for mod", "Files in the the root level of the zip file are not allowed. Please ensure all files reside inside a folder."),
MOD_VERSION_NOT_A_NUMBER(161, "Mod version is not a number", "The mod version has to be a whole number like 123, but was ''{0}''");
MOD_VERSION_NOT_A_NUMBER(161, "Mod version is not a number", "The mod version has to be a whole number like 123, but was ''{0}''"),
USERNAME_RESERVED(162, "Invalid account data", "The entered username is currently reserved: {0} (Maximum reservation time is {1} months)");

private final int code;
private final String title;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@
public interface NameRecordRepository extends JpaRepository<NameRecord, Integer> {
@Query(value = "SELECT datediff(now(), change_time) FROM name_history WHERE user_id = :userId AND datediff(now(), change_time) <= :maximumDaysAgo ORDER BY change_time DESC LIMIT 1", nativeQuery = true)
Optional<Integer> getDaysSinceLastNewRecord(@Param("userId") Integer userId, @Param("maximumDaysAgo") Integer maximumDaysAgo);

@Query(value = "SELECT user_id FROM name_history WHERE previous_name = ':name' AND now() > date_add(change_time, INTERVAL :months MONTH) ORDER BY change_time DESC LIMIT 1", nativeQuery = true)
Optional<Integer> getLastUsernameOwnerWithinMonths(@Param("name") String name, @Param("months") Integer months);
}
14 changes: 14 additions & 0 deletions src/main/java/com/faforever/api/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ void register(String username, String email, String password) {
throw new ApiException(new Error(ErrorCode.EMAIL_REGISTERED, email));
}

int usernameReservationTimeInMonths = properties.getUser().getUsernameReservationTimeInMonths();
nameRecordRepository.getLastUsernameOwnerWithinMonths(username, usernameReservationTimeInMonths)
.ifPresent(reservedByUserId -> {
throw new ApiException(new Error(ErrorCode.USERNAME_RESERVED, username, usernameReservationTimeInMonths));
});

String token = createRegistrationToken(username, email, passwordEncoder.encode(password));
String activationUrl = String.format(properties.getRegistration().getActivationUrlFormat(), token);

Expand Down Expand Up @@ -153,6 +159,14 @@ void changeLogin(String newLogin, User user) {
throw new ApiException(new Error(ErrorCode.USERNAME_CHANGE_TOO_EARLY, minDaysBetweenChange - daysSinceLastRecord));
});

int usernameReservationTimeInMonths = properties.getUser().getUsernameReservationTimeInMonths();
nameRecordRepository.getLastUsernameOwnerWithinMonths(newLogin, usernameReservationTimeInMonths)
.ifPresent(reservedByUserId -> {
if (reservedByUserId != user.getId()) {
throw new ApiException(new Error(ErrorCode.USERNAME_RESERVED, newLogin, usernameReservationTimeInMonths));
}
});

NameRecord nameRecord = new NameRecord()
.setName(user.getLogin())
.setPlayer(playerRepository.findOne(user.getId()));
Expand Down
25 changes: 25 additions & 0 deletions src/test/java/com/faforever/api/user/UserServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -142,6 +143,13 @@ public void registerUsernameTaken() throws Exception {
instance.register("junit", TEST_EMAIL, TEST_CURRENT_PASSWORD);
}

@Test
public void registerUsernameReserved() throws Exception {
when(nameRecordRepository.getLastUsernameOwnerWithinMonths(any(), anyInt())).thenReturn(Optional.of(1));
expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_RESERVED));
instance.register("junit", TEST_EMAIL, TEST_CURRENT_PASSWORD);
}

@Test
public void activate() throws Exception {
String token = JwtHelper.encode(objectMapper.writeValueAsString(ImmutableMap.of(
Expand Down Expand Up @@ -252,6 +260,23 @@ public void changeLoginTooEarly() {
instance.changeLogin(TEST_USERNAME_CHANED, user);
}

@Test
public void changeLoginUsernameReserved() {
expectedException.expect(ApiExceptionWithCode.apiExceptionWithCode(ErrorCode.USERNAME_RESERVED));
when(nameRecordRepository.getLastUsernameOwnerWithinMonths(any(), anyInt())).thenReturn(Optional.of(TEST_USERID + 1));

User user = createUser(TEST_USERID, TEST_USERNAME, TEST_CURRENT_PASSWORD, TEST_EMAIL);
instance.changeLogin(TEST_USERNAME_CHANED, user);
}

@Test
public void changeLoginUsernameReservedBySelf() {
when(nameRecordRepository.getLastUsernameOwnerWithinMonths(any(), anyInt())).thenReturn(Optional.of(TEST_USERID));

User user = createUser(TEST_USERID, TEST_USERNAME, TEST_CURRENT_PASSWORD, TEST_EMAIL);
instance.changeLogin(TEST_USERNAME_CHANED, user);
}

@Test
@SneakyThrows
@SuppressWarnings("unchecked")
Expand Down

0 comments on commit 2259ed2

Please sign in to comment.