Skip to content

Commit

Permalink
OIS-46: Added tests for provider class
Browse files Browse the repository at this point in the history
  • Loading branch information
sradziszewski committed Sep 19, 2024
1 parent c5e572f commit 9be3a9a
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,5 @@ protected void additionalAuthenticationChecks(UserDetails userDetails,
}

}

}
7 changes: 7 additions & 0 deletions src/test/java/org/openlmis/auth/UserDataBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,18 @@ public class UserDataBuilder {
private String username = "user" + instanceNumber.incrementAndGet();
private boolean enabled = true;
private String password = null;
private boolean lockedOut = false;

public UserDataBuilder withPassword(String password) {
this.password = password;
return this;
}

public UserDataBuilder asLockedOut(boolean lockedOut) {
this.lockedOut = lockedOut;
return this;
}

/**
* Builds instance of {@link User} without id.
*/
Expand All @@ -41,6 +47,7 @@ public User build() {
user.setUsername(username);
user.setEnabled(enabled);
user.setPassword(password);
user.setLockedOut(lockedOut);

return user;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Affero General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details. You should have received a copy of
* the GNU Affero General Public License along with this program. If not, see
* http://www.gnu.org/licenses.  For additional information contact [email protected].
*/

package org.openlmis.auth.security;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.time.ZonedDateTime;
import java.util.Optional;
import java.util.UUID;
import org.assertj.core.internal.Objects;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.openlmis.auth.UserDataBuilder;
import org.openlmis.auth.domain.UnsuccessfulAuthenticationAttempt;
import org.openlmis.auth.domain.User;
import org.openlmis.auth.repository.UnsuccessfulAuthenticationAttemptRepository;
import org.openlmis.auth.repository.UserRepository;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.util.ReflectionTestUtils;

@RunWith(MockitoJUnitRunner.class)
public class OlmisAuthenticationProviderTest {

@Mock
private UserRepository userRepository;

@Mock
private UnsuccessfulAuthenticationAttemptRepository unsuccessfulAuthenticationAttemptRepository;

@Mock
private UserDetails userDetails;

@Mock
private UsernamePasswordAuthenticationToken authentication;

@Mock
private PasswordEncoder passwordEncoder;

@InjectMocks
private OlmisAuthenticationProvider olmisAuthenticationProvider;

private User user;
private UnsuccessfulAuthenticationAttempt attempt;

@Before
public void setUp() {
ReflectionTestUtils.setField(olmisAuthenticationProvider, "maxUnsuccessfulAuthAttempts", 3);
ReflectionTestUtils.setField(olmisAuthenticationProvider, "lockoutTime", 60);

user = new UserDataBuilder().build();
attempt = new UnsuccessfulAuthenticationAttempt(user);

when(userRepository.findOneByUsernameIgnoreCase(anyString())).thenReturn(user);
when(userDetails.getUsername()).thenReturn(user.getUsername());
when(unsuccessfulAuthenticationAttemptRepository.findByUserId(any(UUID.class)))
.thenReturn(Optional.of(attempt));
}

@Test(expected = LockedException.class)
public void shouldThrowExceptionIfUserLockedOutAndLockoutNotExpired() {
// given
user.setLockedOut(true);
attempt.setLastUnsuccessfulAuthenticationAttemptDate(ZonedDateTime.now().minusSeconds(30));

// when
olmisAuthenticationProvider.additionalAuthenticationChecks(userDetails, authentication);
}

@Test(expected = BadCredentialsException.class)
public void shouldThrowExceptionIfAuthenticationFail() {
// given
doThrow(new BadCredentialsException("Bad credentials")).when(authentication).getCredentials();

// when
olmisAuthenticationProvider.additionalAuthenticationChecks(userDetails, authentication);
}

@Test
public void shouldUnlockLockedOutUserIfLockoutExpired() {
// given
when(authentication.getCredentials()).thenReturn(Objects.instance());
when(userDetails.getPassword()).thenReturn("test-password");
when(passwordEncoder.matches(anyString(), anyString())).thenReturn(Boolean.TRUE);
user.setLockedOut(true);
attempt.setLastUnsuccessfulAuthenticationAttemptDate(ZonedDateTime.now().minusSeconds(61));

// when
olmisAuthenticationProvider.additionalAuthenticationChecks(userDetails, authentication);

// then
assertFalse(user.isLockedOut());
verify(userRepository).save(user);
verify(unsuccessfulAuthenticationAttemptRepository).save(attempt);
}

@Test
public void shouldLockOutUserIfExceedsMaxAttemptNumber() {
// given
user.setLockedOut(false);
attempt.setAttemptCounter(2);
doThrow(new BadCredentialsException("Bad credentials")).when(authentication).getCredentials();

// when
BadCredentialsException exception =
assertThrows(BadCredentialsException.class, () ->
olmisAuthenticationProvider.additionalAuthenticationChecks(userDetails, authentication)
);

// then
assertNotNull(exception);
assertTrue(user.isLockedOut());
verify(userRepository).save(user);
verify(unsuccessfulAuthenticationAttemptRepository).save(attempt);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.junit.MockitoJUnitRunner;
import org.openlmis.auth.SaveAnswer;
import org.openlmis.auth.UserDataBuilder;
import org.openlmis.auth.domain.User;
Expand Down

0 comments on commit 9be3a9a

Please sign in to comment.