package com.brahalla.Cerberus.integration.controller.rest; import com.brahalla.Cerberus.Application; import com.brahalla.Cerberus.integration.util.RequestEntityBuilder; import com.brahalla.Cerberus.integration.util.TestApiConfig; import com.brahalla.Cerberus.model.json.request.AuthenticationRequest; import com.brahalla.Cerberus.model.json.response.AuthenticationResponse; import com.brahalla.Cerberus.security.TokenUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.WebIntegrationTest; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.web.client.RestTemplate; import org.springframework.web.client.HttpClientErrorException; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebIntegrationTest public class AuthenticationControllerTest { private RestTemplate client; private AuthenticationRequest authenticationRequest; private String authenticationToken; @Value("${cerberus.route.authentication}") private String authenticationRoute; @Value("${cerberus.route.authentication.refresh}") private String refreshRoute; @Autowired private TokenUtils tokenUtils; @Before public void setUp() throws Exception { client = new RestTemplate(); } @After public void tearDown() throws Exception { client = null; } @Test public void requestingAuthenticationWithNoCredentialsReturnsBadRequest() throws Exception { this.initializeStateForMakingValidAuthenticationRequest(); try { client.exchange( TestApiConfig.getAbsolutePath(authenticationRoute), HttpMethod.POST, buildAuthenticationRequestEntityWithoutCredentials(), Void.class ); fail("Should have returned an HTTP 400: Bad Request status code"); } catch (HttpClientErrorException e) { assertThat(e.getStatusCode(), is(HttpStatus.BAD_REQUEST)); } catch (Exception e) { fail("Should have returned an HTTP 400: Bad Request status code"); } } @Test public void requestingAuthenticationWithInvalidCredentialsReturnsUnauthorized() throws Exception { this.initializeStateForMakingInvalidAuthenticationRequest(); try { client.exchange( TestApiConfig.getAbsolutePath(authenticationRoute), HttpMethod.POST, buildAuthenticationRequestEntity(), Void.class ); fail("Should have returned an HTTP 401: Unauthorized status code"); } catch (HttpClientErrorException e) { assertThat(e.getStatusCode(), is(HttpStatus.UNAUTHORIZED)); } catch (Exception e) { fail("Should have returned an HTTP 401: Unauthorized status code"); } } @Test public void requestingProtectedWithValidCredentialsReturnsExpected() throws Exception { this.initializeStateForMakingValidAuthenticationRequest(); ResponseEntity<AuthenticationResponse> responseEntity = client.exchange( TestApiConfig.getAbsolutePath(authenticationRoute), HttpMethod.POST, buildAuthenticationRequestEntity(), AuthenticationResponse.class ); AuthenticationResponse authenticationResponse = responseEntity.getBody(); try { assertThat(responseEntity.getStatusCode(), is(HttpStatus.OK)); } catch (Exception e) { fail("Should have returned an HTTP 400: Ok status code"); } try { assertThat(this.tokenUtils.getUsernameFromToken(authenticationResponse.getToken()), is(authenticationRequest.getUsername())); } catch (Exception e) { fail("Should have returned expected username from token"); } } @Test public void requestingAuthenticationRefreshWithNoAuthorizationTokenReturnsUnauthorized() throws Exception { this.initializeStateForMakingValidAuthenticationRefreshRequest(); try { client.exchange( TestApiConfig.getAbsolutePath(String.format("%s/%s", authenticationRoute, refreshRoute)), HttpMethod.GET, buildAuthenticationRefreshRequestEntityWithoutAuthorizationToken(), Void.class ); fail("Should have returned an HTTP 401: Unauthorized status code"); } catch (HttpClientErrorException e) { assertThat(e.getStatusCode(), is(HttpStatus.UNAUTHORIZED)); } catch (Exception e) { fail("Should have returned an HTTP 401: Unauthorized status code"); } } /*@Test public void requestingAuthenticationRefreshWithUnauthorizedCredentialsReturnsBadRequest() throws Exception { this.initializeStateForMakingInvalidAuthenticationRefreshRequest(); try { client.exchange( TestApiConfig.getAbsolutePath(String.format("%s/%s", authenticationRoute, refreshRoute)), HttpMethod.GET, buildAuthenticationRefreshRequestEntity(), Void.class ); fail("Should have returned an HTTP 400: Bad Request status code"); } catch (HttpClientErrorException e) { assertThat(e.getStatusCode(), is(HttpStatus.BAD_REQUEST)); } catch (Exception e) { fail("Should have returned an HTTP 400: Bad Request status code"); } }*/ @Test public void requestingAuthenticationRefreshTokenWithTokenCreatedBeforeLastPasswordResetReturnsBadRequest() throws Exception { this.initializeStateForMakingExpiredAuthenticationRefreshRequest(); try { client.exchange( TestApiConfig.getAbsolutePath(String.format("%s/%s", authenticationRoute, refreshRoute)), HttpMethod.GET, buildAuthenticationRefreshRequestEntity(), Void.class ); fail("Should have returned an HTTP 400: Bad Request status code"); } catch (HttpClientErrorException e) { assertThat(e.getStatusCode(), is(HttpStatus.BAD_REQUEST)); } catch (Exception e) { fail("Should have returned an HTTP 400: Bad Request status code"); } } private void initializeStateForMakingValidAuthenticationRequest() { authenticationRequest = TestApiConfig.USER_AUTHENTICATION_REQUEST; } private void initializeStateForMakingInvalidAuthenticationRequest() { authenticationRequest = TestApiConfig.INVALID_AUTHENTICATION_REQUEST; } private void initializeStateForMakingValidAuthenticationRefreshRequest() { authenticationRequest = TestApiConfig.USER_AUTHENTICATION_REQUEST; ResponseEntity<AuthenticationResponse> authenticationResponse = client.postForEntity( TestApiConfig.getAbsolutePath(authenticationRoute), authenticationRequest, AuthenticationResponse.class ); authenticationToken = authenticationResponse.getBody().getToken(); } private void initializeStateForMakingInvalidAuthenticationRefreshRequest() { authenticationRequest = TestApiConfig.INVALID_AUTHENTICATION_REQUEST; ResponseEntity<AuthenticationResponse> authenticationResponse = client.postForEntity( TestApiConfig.getAbsolutePath(authenticationRoute), authenticationRequest, AuthenticationResponse.class ); authenticationToken = authenticationResponse.getBody().getToken(); } private void initializeStateForMakingExpiredAuthenticationRefreshRequest() { authenticationRequest = TestApiConfig.EXPIRED_AUTHENTICATION_REQUEST; ResponseEntity<AuthenticationResponse> authenticationResponse = client.postForEntity( TestApiConfig.getAbsolutePath(authenticationRoute), authenticationRequest, AuthenticationResponse.class ); authenticationToken = authenticationResponse.getBody().getToken(); } private HttpEntity<Object> buildAuthenticationRequestEntity() { return RequestEntityBuilder.buildRequestEntityWithoutAuthenticationToken(authenticationRequest); } private HttpEntity<Object> buildAuthenticationRequestEntityWithoutCredentials() { return RequestEntityBuilder.buildRequestEntityWithoutBodyOrAuthenticationToken(); } private HttpEntity<Object> buildAuthenticationRefreshRequestEntity() { return RequestEntityBuilder.buildRequestEntityWithoutBody(authenticationToken); } private HttpEntity<Object> buildAuthenticationRefreshRequestEntityWithoutAuthorizationToken() { return RequestEntityBuilder.buildRequestEntityWithoutBodyOrAuthenticationToken(); } }