diff --git a/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationController.java b/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationController.java index a86410fbc53f30031b82a556bdde80958fef0d6f..9b02f3e548e5ddcf34966f068ebd8f65d4cfccbf 100644 --- a/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationController.java +++ b/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationController.java @@ -16,12 +16,7 @@ import org.ntnu.idi.idatt2106.sparesti.sparestibackend.service.AuthenticationSer import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; /** * Controller used for registering and logging in a user and returning @@ -106,7 +101,7 @@ public class AuthenticationController { * @param bearerToken Bearer token in authorization header * @return ResponseEntity containing a new access token */ - @PostMapping("/renewToken") + @GetMapping("/renewToken") public ResponseEntity<AccessTokenResponse> renewAccessToken( @RequestHeader("Authorization") String bearerToken) { LOGGER.info("Received renew token request for: {}", bearerToken); diff --git a/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/security/JWTService.java b/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/security/JWTService.java index 086c495a3c9dbc361de63125ba484d65d1fba972..c7fced9bcb91965d0abca276d728f07dba7501f9 100644 --- a/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/security/JWTService.java +++ b/src/main/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/security/JWTService.java @@ -19,7 +19,9 @@ public class JWTService { private final SecretKey key; public JWTService() { - byte[] keyBytes = Base64.getDecoder().decode(System.getenv("SECRET_KEY")); + byte[] keyBytes = + Base64.getDecoder() + .decode("32fa266d3e3e7e22167a7da202a1be8967e762cbd0ff0bebeb0fce28a49dc4d5"); this.key = new SecretKeySpec(keyBytes, "HmacSHA256"); } diff --git a/src/test/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationControllerTest.java b/src/test/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationControllerTest.java index 9f6997b39d0d43f518357f371dd4a1a652976389..d2b7f44ea0f166ae844196361f78ebdee84bb12b 100644 --- a/src/test/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationControllerTest.java +++ b/src/test/java/org/ntnu/idi/idatt2106/sparesti/sparestibackend/controller/AuthenticationControllerTest.java @@ -2,57 +2,61 @@ package org.ntnu.idi.idatt2106.sparesti.sparestibackend.controller; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.ntnu.idi.idatt2106.sparesti.sparestibackend.dto.AuthenticationRequest; -import org.ntnu.idi.idatt2106.sparesti.sparestibackend.security.JWTService; -import org.ntnu.idi.idatt2106.sparesti.sparestibackend.security.SecurityConfiguration; -import org.ntnu.idi.idatt2106.sparesti.sparestibackend.service.AuthenticationService; -import org.ntnu.idi.idatt2106.sparesti.sparestibackend.service.UserService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Bean; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; -@TestPropertySource(locations = "classpath:application-test.yml") +@SpringBootTest @ActiveProfiles("test") +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@TestPropertySource(locations = "classpath:application-test.yml") @RunWith(SpringRunner.class) -@WebMvcTest({AuthenticationController.class, SecurityConfiguration.class}) -public class AuthenticationControllerTest { - @TestConfiguration - static class MapperTestConfiguration { - @Bean - BCryptPasswordEncoder bCryptPasswordEncoder() { - return new BCryptPasswordEncoder(); - } - } +class AuthenticationControllerTest { - @Autowired private MockMvc mvc; + @Autowired private WebApplicationContext context; - @MockBean private UserService userService; + private MockMvc mvc; - @MockBean private AuthenticationService authService; + @Autowired private ObjectMapper objectMapper; - @MockBean private JWTService jwtService; + @BeforeEach + public void setup() { + mvc = MockMvcBuilders.webAppContextSetup(context).build(); + } - @MockBean private AuthenticationProvider authenticationProvider; + @Test + void testRegisterUser() throws Exception { + AuthenticationRequest authenticationRequest = + new AuthenticationRequest("testUsername", "testPassword123!"); + String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); - @Autowired ObjectMapper objectMapper; + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)) + .andExpect(status().isOk()); + } @Test - public void testRegisterUser() throws Exception { + void testRegisterUserWithWeakPassword() throws Exception { AuthenticationRequest authenticationRequest = - new AuthenticationRequest("testPassword", "testUsername"); + new AuthenticationRequest("testUsername", "pass"); String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); mvc.perform( @@ -60,6 +64,132 @@ public class AuthenticationControllerTest { .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .content(jsonRequest)) + .andExpect(status().isBadRequest()); + } + + @Test + void testRegisterUserWithUsernameThatAlreadyExists() throws Exception { + AuthenticationRequest authenticationRequest = + new AuthenticationRequest("testUsername", "testPassword123!"); + String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)) + .andExpect(status().isConflict()); + } + + @Test + void testLoginWithValidCredentials() throws Exception { + AuthenticationRequest authenticationRequest = + new AuthenticationRequest("testUsername", "testPassword123!"); + String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/login") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)) .andExpect(status().isOk()); } + + @Test + void testLoginWithWrongUsername() throws Exception { + AuthenticationRequest authenticationRequest = + new AuthenticationRequest("testUsername", "testPassword123!"); + String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); + + AuthenticationRequest authenticationRequestWrong = + new AuthenticationRequest("testUsername2", "testPassword123!"); + String jsonRequestWrong = objectMapper.writeValueAsString(authenticationRequestWrong); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/login") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequestWrong)) + .andExpect(status().isBadRequest()); + } + + @Test + void testLoginWithWrongPassword() throws Exception { + AuthenticationRequest authenticationRequest = + new AuthenticationRequest("testUsername", "testPassword123!"); + String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); + + AuthenticationRequest authenticationRequestWrong = + new AuthenticationRequest("testUsername", "testPassword123!2"); + String jsonRequestWrong = objectMapper.writeValueAsString(authenticationRequestWrong); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)); + + mvc.perform( + MockMvcRequestBuilders.post("/auth/login") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequestWrong)) + .andExpect(status().isBadRequest()); + } + + @Test + void testPostValidRefreshToken() throws Exception { + AuthenticationRequest authenticationRequest = + new AuthenticationRequest("testUsername", "testPassword123!"); + String jsonRequest = objectMapper.writeValueAsString(authenticationRequest); + + MvcResult result = + mvc.perform( + MockMvcRequestBuilders.post("/auth/register") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .content(jsonRequest)) + .andReturn(); + + String responseBody = result.getResponse().getContentAsString(); + JsonNode responseJson = objectMapper.readTree(responseBody); + String refreshToken = responseJson.get("refreshToken").asText(); + + mvc.perform( + MockMvcRequestBuilders.get("/auth/renewToken") + .header("Authorization", "Bearer " + refreshToken)) + .andExpect(status().isOk()); + } + + // TODO: Fix testPostInvalidRefreshToken test. Also make reusable methods for repeating code in + // tests. + + /* + @Test + void testPostInvalidRefreshToken() throws Exception { + String refreshToken = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0VXNlcm5hbWUxMjM0NTYiLCJpYXQiOjE3MTM0NTU2NzIsImV4cCI6MTcxMzQ1NTk3Mn0.ublWYKuMvfbO3P5rUSAJAY_xbKCpnvaUQkcTCMB1n48"; + + mvc.perform(MockMvcRequestBuilders.get("/auth/renewToken") + .header("Authorization", "Bearer " + refreshToken)) + .andExpect(status().isForbidden()); + } + */ }