From 4fbf0712e2ceaba8397e487a4ddaee08f017582b Mon Sep 17 00:00:00 2001 From: Art Date: Wed, 8 Sep 2021 16:15:38 +0300 Subject: [PATCH] 63. Test Brute force attack (#6) --- support-portal-backend/pom.xml | 7 +++ .../backend/controller/UserResourceTest.java | 61 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/support-portal-backend/pom.xml b/support-portal-backend/pom.xml index f414d90..addf18c 100644 --- a/support-portal-backend/pom.xml +++ b/support-portal-backend/pom.xml @@ -84,6 +84,13 @@ test + + org.apache.httpcomponents + httpclient + 4.5.13 + test + + diff --git a/support-portal-backend/src/test/java/net/shyshkin/study/fullstack/supportportal/backend/controller/UserResourceTest.java b/support-portal-backend/src/test/java/net/shyshkin/study/fullstack/supportportal/backend/controller/UserResourceTest.java index 2f192eb..69cdc12 100644 --- a/support-portal-backend/src/test/java/net/shyshkin/study/fullstack/supportportal/backend/controller/UserResourceTest.java +++ b/support-portal-backend/src/test/java/net/shyshkin/study/fullstack/supportportal/backend/controller/UserResourceTest.java @@ -6,6 +6,7 @@ import net.shyshkin.study.fullstack.supportportal.backend.common.BaseUserTest; 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.UserPrincipal; +import net.shyshkin.study.fullstack.supportportal.backend.service.LoginAttemptService; import net.shyshkin.study.fullstack.supportportal.backend.utility.JwtTokenProvider; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; @@ -266,4 +267,64 @@ class UserResourceTest extends BaseUserTest { log.debug("Token: {}", token); assertThat(token).isNull(); } + + @Test + @Order(60) + void loginUser_bruteForceDetectionTest() throws InterruptedException { + + //given + User fakeUser = createRandomUser(); + String correctPassword = fakeUser.getPassword().replace("{noop}", ""); + String username = fakeUser.getUsername(); + userRepository.save(fakeUser); + String wrongPassword = "wrongPass"; + + //when + User userLogin = User.builder() + .username(username) + .password(wrongPassword) + .build(); + + for (int i = 0; i < LoginAttemptService.MAX_ATTEMPTS; i++) { + + var responseEntity = restTemplate.postForEntity("/user/login", userLogin, HttpResponse.class); + + //then + log.debug("Response Entity: {}", responseEntity); + assertThat(responseEntity.getStatusCode()).isEqualTo(BAD_REQUEST); + assertThat(responseEntity.getBody()) + .isNotNull() + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("httpStatusCode", 400) + .hasFieldOrPropertyWithValue("httpStatus", BAD_REQUEST) + .hasFieldOrPropertyWithValue("reason", "BAD REQUEST") + .hasFieldOrPropertyWithValue("message", "USERNAME / PASSWORD INCORRECT. PLEASE TRY AGAIN"); + } + + for (int i = 0; i < 5; i++) { + + if (i > 3) { + // Even correct password should not allow access to locked account + userLogin = User.builder() + .username(username) + .password(correctPassword) + .build(); + } + + var responseEntity = restTemplate.postForEntity("/user/login", userLogin, HttpResponse.class); + + //then + log.debug("Response Entity: {}", responseEntity); + assertThat(responseEntity.getStatusCode()).isEqualTo(UNAUTHORIZED); + assertThat(responseEntity.getBody()) + .isNotNull() + .hasNoNullFieldsOrProperties() + .hasFieldOrPropertyWithValue("httpStatusCode", 401) + .hasFieldOrPropertyWithValue("httpStatus", UNAUTHORIZED) + .hasFieldOrPropertyWithValue("reason", "UNAUTHORIZED") + .hasFieldOrPropertyWithValue("message", "YOUR ACCOUNT HAS BEEN LOCKED. PLEASE CONTACT ADMINISTRATION"); + } + + + } } \ No newline at end of file