Skip to content

Commit

Permalink
[backend] Ensure uniqueness of email field when creating a user account
Browse files Browse the repository at this point in the history
  • Loading branch information
RomuDeuxfois authored Feb 29, 2024
1 parent 1090caa commit 7546e5d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
40 changes: 36 additions & 4 deletions openex-api/src/test/java/io/openex/rest/UserApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.openex.database.model.User;
import io.openex.database.repository.UserRepository;
import io.openex.rest.user.form.login.LoginUserInput;
import io.openex.rest.user.form.user.CreateUserInput;
import io.openex.rest.utils.fixtures.UserFixture;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -12,6 +13,7 @@
import org.springframework.test.web.servlet.MockMvc;

import static io.openex.rest.utils.JsonUtils.asJsonString;
import static io.openex.rest.utils.fixtures.UserFixture.EMAIL;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
Expand All @@ -32,7 +34,7 @@ class UserApiTest extends IntegrationTest {
public void setup() {
// Create user
User user = new User();
user.setEmail(UserFixture.EMAIL);
user.setEmail(EMAIL);
user.setPassword(UserFixture.ENCODED_PASSWORD);

savedUser = this.userRepository.save(user);
Expand Down Expand Up @@ -60,7 +62,7 @@ void given_known_login_user_input_should_return_user() throws Exception {
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(loginUserInput)))
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("user_email").value(UserFixture.EMAIL));
.andExpect(jsonPath("user_email").value(EMAIL));

}

Expand All @@ -87,7 +89,7 @@ void given_known_login_user_in_uppercase_input_should_return_user() throws Excep
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(loginUserInput)))
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("user_email").value(UserFixture.EMAIL));
.andExpect(jsonPath("user_email").value(EMAIL));

}

Expand All @@ -101,8 +103,38 @@ void given_known_login_user_in_alternatingcase_input_should_return_user() throws
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(loginUserInput)))
.andExpect(status().is2xxSuccessful())
.andExpect(jsonPath("user_email").value(UserFixture.EMAIL));
.andExpect(jsonPath("user_email").value(EMAIL));
}
}
}

@Nested
@DisplayName("Create user")
class Creating {
@DisplayName("Create existing user by email in lowercase gives a conflict")
@Test
@WithMockUser(roles = {"ADMIN"})
void given_known_create_user_in_lowercase_input_should_return_conflict() throws Exception {
CreateUserInput input = new CreateUserInput();
input.setEmail(EMAIL);

mvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(input)))
.andExpect(status().isConflict());
}

@DisplayName("Create existing user by email in uppercase gives a conflict")
@Test
@WithMockUser(roles = {"ADMIN"})
void given_known_create_user_in_uppercase_input_should_return_conflict() throws Exception {
CreateUserInput input = new CreateUserInput();
input.setEmail(EMAIL.toUpperCase());

mvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(input)))
.andExpect(status().isConflict());
}
}
}
18 changes: 15 additions & 3 deletions openex-model/src/main/java/io/openex/database/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import java.util.stream.Collectors;

import static java.time.Instant.now;
import static java.util.Optional.ofNullable;
import static java.util.stream.StreamSupport.stream;
import static lombok.AccessLevel.NONE;

@Getter
@Entity
Expand Down Expand Up @@ -57,17 +59,19 @@ public class User implements Base {
@JsonProperty("user_lastname")
private String lastname;

@Getter(NONE)
@Setter
@Column(name = "user_lang")
@JsonProperty("user_lang")
private String lang = LANG_AUTO;

@Getter(NONE)
@Setter
@Column(name = "user_theme")
@JsonProperty("user_theme")
private String theme = THEME_DEFAULT;

@Setter
@Getter(NONE)
@Column(name = "user_email")
@JsonProperty("user_email")
@NotBlank
Expand Down Expand Up @@ -179,11 +183,19 @@ public class User implements Base {
private List<ComcheckStatus> comcheckStatuses = new ArrayList<>();

public String getLang() {
return Optional.ofNullable(this.lang).orElse(LANG_AUTO);
return ofNullable(this.lang).orElse(LANG_AUTO);
}

public String getTheme() {
return Optional.ofNullable(this.theme).orElse(THEME_DEFAULT);
return ofNullable(this.theme).orElse(THEME_DEFAULT);
}

public String getEmail() {
return ofNullable(this.email).map(String::toLowerCase).orElse(null);
}

public void setEmail(final String email) {
this.email = ofNullable(email).map(String::toLowerCase).orElseThrow(() -> new IllegalArgumentException("Email can't be null"));
}

private transient List<Inject> injects = new ArrayList<>();
Expand Down

0 comments on commit 7546e5d

Please sign in to comment.