50. User registration - Testing (#4)

This commit is contained in:
Art
2021-09-07 14:59:24 +03:00
parent 25a608615f
commit c4138f9ad3
4 changed files with 124 additions and 28 deletions

View File

@ -0,0 +1,29 @@
package net.shyshkin.study.fullstack.supportportal.backend.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class PasswordEncoderConfig {
@Bean
PasswordEncoder passwordEncoder() {
String idForEncode = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
return new DelegatingPasswordEncoder(idForEncode, encoders);
}
}

View File

@ -5,7 +5,6 @@ import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAccessDenied
import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthenticationEntryPoint; import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthenticationEntryPoint;
import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthorizationFilter; import net.shyshkin.study.fullstack.supportportal.backend.filter.JwtAuthorizationFilter;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@ -13,26 +12,19 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import java.util.HashMap;
import java.util.Map;
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor @RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter { public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtAuthorizationFilter jwtAuthorizationFilter; private final JwtAuthorizationFilter jwtAuthorizationFilter;
private final UserDetailsService userService; private final UserDetailsService userDetailsService;
private final JwtAccessDeniedHandler jwtAccessDeniedHandler; private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
private final PasswordEncoder passwordEncoder;
@Value("${app.public-urls}") @Value("${app.public-urls}")
private String[] publicUrls; private String[] publicUrls;
@ -60,20 +52,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth auth
.userDetailsService(userService) .userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder()); .passwordEncoder(passwordEncoder);
} }
@Bean
PasswordEncoder passwordEncoder() {
String idForEncode = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
return new DelegatingPasswordEncoder(idForEncode, encoders);
}
} }

View File

@ -19,7 +19,7 @@ public abstract class BaseUserTest {
@Autowired @Autowired
protected UserRepository userRepository; protected UserRepository userRepository;
protected User user; protected static User user;
protected User createRandomUser() { protected User createRandomUser() {
return User.builder() return User.builder()

View File

@ -6,20 +6,24 @@ import net.shyshkin.study.fullstack.supportportal.backend.domain.HttpResponse;
import net.shyshkin.study.fullstack.supportportal.backend.domain.User; import net.shyshkin.study.fullstack.supportportal.backend.domain.User;
import net.shyshkin.study.fullstack.supportportal.backend.domain.UserPrincipal; import net.shyshkin.study.fullstack.supportportal.backend.domain.UserPrincipal;
import net.shyshkin.study.fullstack.supportportal.backend.utility.JwtTokenProvider; import net.shyshkin.study.fullstack.supportportal.backend.utility.JwtTokenProvider;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.RequestEntity; import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertAll;
import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.HttpStatus.*;
import static org.springframework.http.HttpStatus.OK;
@Slf4j @Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(value = MethodOrderer.OrderAnnotation.class)
class UserResourceTest extends BaseUserTest { class UserResourceTest extends BaseUserTest {
@Autowired @Autowired
@ -29,6 +33,7 @@ class UserResourceTest extends BaseUserTest {
JwtTokenProvider jwtTokenProvider; JwtTokenProvider jwtTokenProvider;
@Test @Test
@Order(10)
void showUserHome_forbidden() { void showUserHome_forbidden() {
//when //when
@ -49,6 +54,7 @@ class UserResourceTest extends BaseUserTest {
} }
@Test @Test
@Order(20)
void showUserHome_correctToken() { void showUserHome_correctToken() {
//given //given
@ -71,4 +77,86 @@ class UserResourceTest extends BaseUserTest {
.isNotNull() .isNotNull()
.isEqualTo("Application works"); .isEqualTo("Application works");
} }
@Test
@Order(30)
void registerUser_new() {
//given
User fakeUser = createRandomUser();
//when
ResponseEntity<User> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, User.class);
//then
log.debug("Response Entity: {}", responseEntity);
assertThat(responseEntity.getStatusCode()).isEqualTo(OK);
User registeredUser = responseEntity.getBody();
assertThat(registeredUser)
.isNotNull()
.hasNoNullFieldsOrPropertiesExcept("lastLoginDate", "lastLoginDateDisplay")
.hasFieldOrPropertyWithValue("username", fakeUser.getUsername())
.hasFieldOrPropertyWithValue("email", fakeUser.getEmail())
.hasFieldOrPropertyWithValue("firstName", fakeUser.getFirstName())
.hasFieldOrPropertyWithValue("lastName", fakeUser.getLastName())
.hasFieldOrPropertyWithValue("isActive", true)
.hasFieldOrPropertyWithValue("isNotLocked", true)
.hasFieldOrPropertyWithValue("role", "ROLE_USER")
;
user = registeredUser;
}
@Test
@Order(40)
void registerUser_usernameExists() {
//given
User fakeUser = createRandomUser();
String username = user.getUsername();
fakeUser.setUsername(username);
String expectedMessage = ("Username `" + username + "` is already taken. Please select another one").toUpperCase();
//when
ResponseEntity<HttpResponse> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, HttpResponse.class);
//then
log.debug("Response Entity: {}", responseEntity);
assertThat(responseEntity.getStatusCode()).isEqualTo(BAD_REQUEST);
assertThat(responseEntity.getBody())
.isNotNull()
.hasNoNullFieldsOrProperties()
.satisfies(httpResponse -> assertAll(
() -> assertThat(httpResponse.getHttpStatusCode()).isEqualTo(400),
() -> assertThat(httpResponse.getHttpStatus()).isEqualTo(BAD_REQUEST),
() -> assertThat(httpResponse.getReason()).isEqualTo("BAD REQUEST"),
() -> assertThat(httpResponse.getMessage()).isEqualTo(expectedMessage)
));
}
@Test
@Order(41)
void registerUser_emailExists() {
//given
User fakeUser = createRandomUser();
String email = user.getEmail();
fakeUser.setEmail(email);
String expectedMessage = ("User with email `" + email + "` is already registered").toUpperCase();
//when
ResponseEntity<HttpResponse> responseEntity = restTemplate.postForEntity("/user/register", fakeUser, HttpResponse.class);
//then
log.debug("Response Entity: {}", responseEntity);
assertThat(responseEntity.getStatusCode()).isEqualTo(BAD_REQUEST);
assertThat(responseEntity.getBody())
.isNotNull()
.hasNoNullFieldsOrProperties()
.satisfies(httpResponse -> assertAll(
() -> assertThat(httpResponse.getHttpStatusCode()).isEqualTo(400),
() -> assertThat(httpResponse.getHttpStatus()).isEqualTo(BAD_REQUEST),
() -> assertThat(httpResponse.getReason()).isEqualTo("BAD REQUEST"),
() -> assertThat(httpResponse.getMessage()).isEqualTo(expectedMessage)
));
}
} }