#1141 Check that user is logged in before changing TOTP key
- Use PlayerCache to check that user is logged in where appropriate - Add log statements
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package fr.xephi.authme.command.executable.totp;
|
||||
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.data.auth.PlayerCache;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.message.Messages;
|
||||
import fr.xephi.authme.security.totp.GenerateTotpService;
|
||||
@@ -32,21 +32,21 @@ public class AddTotpCommandTest {
|
||||
@Mock
|
||||
private GenerateTotpService generateTotpService;
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
private PlayerCache playerCache;
|
||||
@Mock
|
||||
private Messages messages;
|
||||
|
||||
@Test
|
||||
public void shouldHandleNonExistentUser() {
|
||||
public void shouldHandleNonLoggedInUser() {
|
||||
// given
|
||||
Player player = mockPlayerWithName("bob");
|
||||
given(dataSource.getAuth("bob")).willReturn(null);
|
||||
given(playerCache.getAuth("bob")).willReturn(null);
|
||||
|
||||
// when
|
||||
addTotpCommand.runCommand(player, Collections.emptyList());
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.REGISTER_MESSAGE);
|
||||
verify(messages).send(player, MessageKey.NOT_LOGGED_IN);
|
||||
verifyZeroInteractions(generateTotpService);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class AddTotpCommandTest {
|
||||
Player player = mockPlayerWithName("arend");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("arend")
|
||||
.totpKey("TOTP2345").build();
|
||||
given(dataSource.getAuth("arend")).willReturn(auth);
|
||||
given(playerCache.getAuth("arend")).willReturn(auth);
|
||||
|
||||
// when
|
||||
addTotpCommand.runCommand(player, Collections.emptyList());
|
||||
@@ -71,7 +71,7 @@ public class AddTotpCommandTest {
|
||||
// given
|
||||
Player player = mockPlayerWithName("charles");
|
||||
PlayerAuth auth = PlayerAuth.builder().name("charles").build();
|
||||
given(dataSource.getAuth("charles")).willReturn(auth);
|
||||
given(playerCache.getAuth("charles")).willReturn(auth);
|
||||
|
||||
TotpGenerationResult generationResult = new TotpGenerationResult(
|
||||
"777Key214", "http://example.org/qr-code/link");
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package fr.xephi.authme.command.executable.totp;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.data.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.message.Messages;
|
||||
import fr.xephi.authme.security.totp.GenerateTotpService;
|
||||
import fr.xephi.authme.security.totp.TotpAuthenticator.TotpGenerationResult;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -15,7 +18,10 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -37,8 +43,15 @@ public class ConfirmTotpCommandTest {
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
@Mock
|
||||
private PlayerCache playerCache;
|
||||
@Mock
|
||||
private Messages messages;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpLogger() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddTotpCodeToUserAfterSuccessfulConfirmation() {
|
||||
// given
|
||||
@@ -46,10 +59,12 @@ public class ConfirmTotpCommandTest {
|
||||
String playerName = "George";
|
||||
given(player.getName()).willReturn(playerName);
|
||||
PlayerAuth auth = PlayerAuth.builder().name(playerName).build();
|
||||
given(dataSource.getAuth(playerName)).willReturn(auth);
|
||||
given(generateTotpService.getGeneratedTotpKey(player)).willReturn(new TotpGenerationResult("totp-key", "url-not-relevant"));
|
||||
given(playerCache.getAuth(playerName)).willReturn(auth);
|
||||
String generatedTotpKey = "totp-key";
|
||||
given(generateTotpService.getGeneratedTotpKey(player)).willReturn(new TotpGenerationResult(generatedTotpKey, "url-not-relevant"));
|
||||
String totpCode = "954321";
|
||||
given(generateTotpService.isTotpCodeCorrectForGeneratedTotpKey(player, totpCode)).willReturn(true);
|
||||
given(dataSource.setTotpKey(anyString(), anyString())).willReturn(true);
|
||||
|
||||
// when
|
||||
command.runCommand(player, Collections.singletonList(totpCode));
|
||||
@@ -57,8 +72,10 @@ public class ConfirmTotpCommandTest {
|
||||
// then
|
||||
verify(generateTotpService).isTotpCodeCorrectForGeneratedTotpKey(player, totpCode);
|
||||
verify(generateTotpService).removeGenerateTotpKey(player);
|
||||
verify(dataSource).setTotpKey(playerName, "totp-key");
|
||||
verify(dataSource).setTotpKey(playerName, generatedTotpKey);
|
||||
verify(playerCache).updatePlayer(auth);
|
||||
verify(messages).send(player, MessageKey.TWO_FACTOR_ENABLE_SUCCESS);
|
||||
assertThat(auth.getTotpKey(), equalTo(generatedTotpKey));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -68,7 +85,7 @@ public class ConfirmTotpCommandTest {
|
||||
String playerName = "George";
|
||||
given(player.getName()).willReturn(playerName);
|
||||
PlayerAuth auth = PlayerAuth.builder().name(playerName).build();
|
||||
given(dataSource.getAuth(playerName)).willReturn(auth);
|
||||
given(playerCache.getAuth(playerName)).willReturn(auth);
|
||||
given(generateTotpService.getGeneratedTotpKey(player)).willReturn(new TotpGenerationResult("totp-key", "url-not-relevant"));
|
||||
String totpCode = "754321";
|
||||
given(generateTotpService.isTotpCodeCorrectForGeneratedTotpKey(player, totpCode)).willReturn(false);
|
||||
@@ -79,8 +96,9 @@ public class ConfirmTotpCommandTest {
|
||||
// then
|
||||
verify(generateTotpService).isTotpCodeCorrectForGeneratedTotpKey(player, totpCode);
|
||||
verify(generateTotpService, never()).removeGenerateTotpKey(any(Player.class));
|
||||
verify(dataSource, only()).getAuth(playerName);
|
||||
verify(playerCache, only()).getAuth(playerName);
|
||||
verify(messages).send(player, MessageKey.TWO_FACTOR_ENABLE_ERROR_WRONG_CODE);
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,7 +108,7 @@ public class ConfirmTotpCommandTest {
|
||||
String playerName = "George";
|
||||
given(player.getName()).willReturn(playerName);
|
||||
PlayerAuth auth = PlayerAuth.builder().name(playerName).build();
|
||||
given(dataSource.getAuth(playerName)).willReturn(auth);
|
||||
given(playerCache.getAuth(playerName)).willReturn(auth);
|
||||
given(generateTotpService.getGeneratedTotpKey(player)).willReturn(null);
|
||||
|
||||
// when
|
||||
@@ -98,8 +116,9 @@ public class ConfirmTotpCommandTest {
|
||||
|
||||
// then
|
||||
verify(generateTotpService, only()).getGeneratedTotpKey(player);
|
||||
verify(dataSource, only()).getAuth(playerName);
|
||||
verify(playerCache, only()).getAuth(playerName);
|
||||
verify(messages).send(player, MessageKey.TWO_FACTOR_ENABLE_ERROR_NO_CODE);
|
||||
verifyZeroInteractions(dataSource);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,14 +128,14 @@ public class ConfirmTotpCommandTest {
|
||||
String playerName = "George";
|
||||
given(player.getName()).willReturn(playerName);
|
||||
PlayerAuth auth = PlayerAuth.builder().name(playerName).totpKey("A987234").build();
|
||||
given(dataSource.getAuth(playerName)).willReturn(auth);
|
||||
given(playerCache.getAuth(playerName)).willReturn(auth);
|
||||
|
||||
// when
|
||||
command.runCommand(player, Collections.singletonList("871634"));
|
||||
|
||||
// then
|
||||
verify(dataSource, only()).getAuth(playerName);
|
||||
verifyZeroInteractions(generateTotpService);
|
||||
verify(playerCache, only()).getAuth(playerName);
|
||||
verifyZeroInteractions(generateTotpService, dataSource);
|
||||
verify(messages).send(player, MessageKey.TWO_FACTOR_ALREADY_ENABLED);
|
||||
}
|
||||
|
||||
@@ -126,14 +145,14 @@ public class ConfirmTotpCommandTest {
|
||||
Player player = mock(Player.class);
|
||||
String playerName = "George";
|
||||
given(player.getName()).willReturn(playerName);
|
||||
given(dataSource.getAuth(playerName)).willReturn(null);
|
||||
given(playerCache.getAuth(playerName)).willReturn(null);
|
||||
|
||||
// when
|
||||
command.runCommand(player, Collections.singletonList("984685"));
|
||||
|
||||
// then
|
||||
verify(dataSource, only()).getAuth(playerName);
|
||||
verifyZeroInteractions(generateTotpService);
|
||||
verify(messages).send(player, MessageKey.REGISTER_MESSAGE);
|
||||
verify(playerCache, only()).getAuth(playerName);
|
||||
verifyZeroInteractions(generateTotpService, dataSource);
|
||||
verify(messages).send(player, MessageKey.NOT_LOGGED_IN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
package fr.xephi.authme.command.executable.totp;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.data.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.message.Messages;
|
||||
import fr.xephi.authme.security.totp.TotpAuthenticator;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.only;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
|
||||
/**
|
||||
* Test for {@link RemoveTotpCommand}.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RemoveTotpCommandTest {
|
||||
|
||||
@InjectMocks
|
||||
private RemoveTotpCommand command;
|
||||
|
||||
@Mock
|
||||
private DataSource dataSource;
|
||||
@Mock
|
||||
private PlayerCache playerCache;
|
||||
@Mock
|
||||
private TotpAuthenticator totpAuthenticator;
|
||||
@Mock
|
||||
private Messages messages;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpLogger() {
|
||||
TestHelper.setupLogger();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveTotpKey() {
|
||||
// given
|
||||
String name = "aws";
|
||||
PlayerAuth auth = PlayerAuth.builder().name(name).totpKey("some-totp-key").build();
|
||||
given(playerCache.getAuth(name)).willReturn(auth);
|
||||
String inputCode = "93847";
|
||||
given(totpAuthenticator.checkCode(auth, inputCode)).willReturn(true);
|
||||
given(dataSource.removeTotpKey(name)).willReturn(true);
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
|
||||
// when
|
||||
command.runCommand(player, singletonList(inputCode));
|
||||
|
||||
// then
|
||||
verify(dataSource).removeTotpKey(name);
|
||||
verify(messages, only()).send(player, MessageKey.TWO_FACTOR_REMOVED_SUCCESS);
|
||||
verify(playerCache).updatePlayer(auth);
|
||||
assertThat(auth.getTotpKey(), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleDatabaseError() {
|
||||
// given
|
||||
String name = "aws";
|
||||
PlayerAuth auth = PlayerAuth.builder().name(name).totpKey("some-totp-key").build();
|
||||
given(playerCache.getAuth(name)).willReturn(auth);
|
||||
String inputCode = "93847";
|
||||
given(totpAuthenticator.checkCode(auth, inputCode)).willReturn(true);
|
||||
given(dataSource.removeTotpKey(name)).willReturn(false);
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
|
||||
// when
|
||||
command.runCommand(player, singletonList(inputCode));
|
||||
|
||||
// then
|
||||
verify(dataSource).removeTotpKey(name);
|
||||
verify(messages, only()).send(player, MessageKey.ERROR);
|
||||
verify(playerCache, only()).getAuth(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleInvalidCode() {
|
||||
// given
|
||||
String name = "cesar";
|
||||
PlayerAuth auth = PlayerAuth.builder().name(name).totpKey("some-totp-key").build();
|
||||
given(playerCache.getAuth(name)).willReturn(auth);
|
||||
String inputCode = "93847";
|
||||
given(totpAuthenticator.checkCode(auth, inputCode)).willReturn(false);
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
|
||||
// when
|
||||
command.runCommand(player, singletonList(inputCode));
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(dataSource);
|
||||
verify(messages, only()).send(player, MessageKey.TWO_FACTOR_INVALID_CODE);
|
||||
verify(playerCache, only()).getAuth(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleUserWithoutTotpKey() {
|
||||
// given
|
||||
String name = "cesar";
|
||||
PlayerAuth auth = PlayerAuth.builder().name(name).build();
|
||||
given(playerCache.getAuth(name)).willReturn(auth);
|
||||
String inputCode = "654684";
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
|
||||
// when
|
||||
command.runCommand(player, singletonList(inputCode));
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(dataSource, totpAuthenticator);
|
||||
verify(messages, only()).send(player, MessageKey.TWO_FACTOR_NOT_ENABLED_ERROR);
|
||||
verify(playerCache, only()).getAuth(name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleNonLoggedInUser() {
|
||||
// given
|
||||
String name = "cesar";
|
||||
given(playerCache.getAuth(name)).willReturn(null);
|
||||
String inputCode = "654684";
|
||||
Player player = mock(Player.class);
|
||||
given(player.getName()).willReturn(name);
|
||||
|
||||
// when
|
||||
command.runCommand(player, singletonList(inputCode));
|
||||
|
||||
// then
|
||||
verifyZeroInteractions(dataSource, totpAuthenticator);
|
||||
verify(messages, only()).send(player, MessageKey.NOT_LOGGED_IN);
|
||||
verify(playerCache, only()).getAuth(name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user