Skip to content

Commit

Permalink
Refactored and improved MfaAuthenticatorImplTest
Browse files Browse the repository at this point in the history
Signed-off-by: Alberto Codutti <alberto.codutti@eurotech.com>
  • Loading branch information
Coduz committed Nov 4, 2022
1 parent 837bfe2 commit 6048f47
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public interface MfaAuthenticator {
* Whether the {@link MfaAuthenticator} service is enabled or not.
*
* @return {@code true} if the {@link MfaAuthenticator} is enabled, {@code false} otherwise.
* @throws KapuaException
* @since 1.3.0
*/
boolean isEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.commons.security.KapuaSecurityUtils;
import org.eclipse.kapua.locator.KapuaLocator;
import org.eclipse.kapua.service.authentication.ApiKeyCredentials;
Expand Down Expand Up @@ -78,20 +79,20 @@ public boolean doCredentialsMatch(AuthenticationToken authenticationToken, Authe
// FIXME: if true cache token password for authentication performance improvement
} else {

// first check if 2FA is enabled for the current user
// Check if MFA is enabled for the current user
MfaOption mfaOption;
try {
mfaOption = KapuaSecurityUtils.doPrivileged(() -> MFA_OPTION_SERVICE.findByUserId(infoUser.getScopeId(),
infoUser.getId()));
mfaOption = KapuaSecurityUtils.doPrivileged(() -> MFA_OPTION_SERVICE.findByUserId(infoUser.getScopeId(), infoUser.getId()));
} catch (AuthenticationException ae) {
throw ae;
} catch (Exception e) {
throw new ShiroException("Error while finding Mfa Option!", e);
}

if (mfaOption != null) {
if (tokenAuthenticationCode != null) {

// do 2fa match
// Do MFA match
boolean isCodeValid;
try {
isCodeValid = MFA_AUTHENTICATOR.authorize(mfaOption.getMfaSecretKey(), Integer.parseInt(tokenAuthenticationCode));
Expand All @@ -101,29 +102,33 @@ public boolean doCredentialsMatch(AuthenticationToken authenticationToken, Authe
throw new ShiroException("Error while authenticating Mfa Option!", e);
}

// code is not valid, try scratch code login
if (!isCodeValid) {
// Code is not valid, try scratch codes login
ScratchCodeListResult scratchCodeListResult;
try {
scratchCodeListResult = KapuaSecurityUtils.doPrivileged(() -> SCRATCH_CODE_SERVICE.findByMfaOptionId(
mfaOption.getScopeId(), mfaOption.getId()));
scratchCodeListResult = KapuaSecurityUtils.doPrivileged(() -> SCRATCH_CODE_SERVICE.findByMfaOptionId(mfaOption.getScopeId(), mfaOption.getId()));
} catch (AuthenticationException ae) {
throw ae;
} catch (Exception e) {
throw new ShiroException("Error while finding scratch codes!", e);
}

for (ScratchCode code : scratchCodeListResult.getItems()) {
if (MFA_AUTHENTICATOR.authorize(code.getCode(), tokenAuthenticationCode)) {
isCodeValid = true;
try {
KapuaSecurityUtils.doPrivileged(() -> SCRATCH_CODE_SERVICE.delete(code.getScopeId(), code.getId()));
} catch (AuthenticationException ae) {
throw ae;
} catch (Exception e) {
throw new ShiroException("Error while removing used scratch code!", e);
try {
if (MFA_AUTHENTICATOR.authorize(code.getCode(), tokenAuthenticationCode)) {
isCodeValid = true;
try {
// Delete the used scratch code
KapuaSecurityUtils.doPrivileged(() -> SCRATCH_CODE_SERVICE.delete(code.getScopeId(), code.getId()));
} catch (AuthenticationException ae) {
throw ae;
} catch (Exception e) {
throw new ShiroException("Error while removing used scratch code!", e);
}
break;
}
break;
} catch (KapuaException e) {
throw new ShiroException("Error while validating scratch codes!", e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
package org.eclipse.kapua.service.authentication.shiro.mfa;

import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.KapuaIllegalArgumentException;
import org.eclipse.kapua.KapuaIllegalNullArgumentException;
import org.eclipse.kapua.qa.markers.junit.JUnitTests;
import org.eclipse.kapua.service.authentication.shiro.utils.AuthenticationUtils;
import org.eclipse.kapua.service.authentication.shiro.utils.CryptAlgorithm;
Expand All @@ -21,8 +23,10 @@
import org.junit.Test;
import org.junit.experimental.categories.Category;

import java.util.List;

@Category(JUnitTests.class)
public class MfaAuthenticatorImplTest extends Assert {
public class MfaAuthenticatorImplTest {

MfaAuthenticatorImpl mfaAuthenticatorImpl;
String[] encryptedSecrets, hashedScratchCodes, stringVerificationCodes;
Expand All @@ -31,77 +35,122 @@ public class MfaAuthenticatorImplTest extends Assert {
@Before
public void initialize() throws KapuaException {
mfaAuthenticatorImpl = new MfaAuthenticatorImpl();
encryptedSecrets = new String[]{AuthenticationUtils.encryptAes("value to encrypt"), AuthenticationUtils.encryptAes("value@#$ en-999crypt"), AuthenticationUtils.encryptAes("!<>v87a-lue to encrypt"),
AuthenticationUtils.encryptAes("value_to$#encr-0y()pt"), AuthenticationUtils.encryptAes("va09l-ue|,,,.to00encrypt")};
verificationCodes = new int[]{-2147483648, -100000, -100, -1, 0, 1, 100, 100000, 2147483647};
hashedScratchCodes = new String[]{AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, "val-ue99_<11>"), AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, " !@#$v66a0l-ueee"),
AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, "val *&^%087,...ueee "), AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, "_877V.A;;LUE")};
stringVerificationCodes = new String[]{"-2147483648", "-100000", "-100", "-1", "0", " 1", "100", "100000", "2147483647"};

encryptedSecrets = new String[]{
AuthenticationUtils.encryptAes("value to encrypt"),
AuthenticationUtils.encryptAes("value@#$ en-999crypt"),
AuthenticationUtils.encryptAes("!<>v87a-lue to encrypt"),
AuthenticationUtils.encryptAes("value_to$#encr-0y()pt"),
AuthenticationUtils.encryptAes("va09l-ue|,,,.to00encrypt")
};

verificationCodes = new int[]{
-2147483648,
-100000,
-100,
-1,
0,
1,
100,
100000,
2147483647
};

hashedScratchCodes = new String[]{
AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, "val-ue99_<11>"),
AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, " !@#$v66a0l-ueee"),
AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, "val *&^%087,...ueee "),
AuthenticationUtils.cryptCredential(CryptAlgorithm.BCRYPT, "_877V.A;;LUE")
};

stringVerificationCodes = new String[]{
"0",
" 1",
"100",
"100000",
"2147483647"
};
}

@Test
public void isEnabledTest() {
assertTrue("True expected.", mfaAuthenticatorImpl.isEnabled());
Assert.assertTrue("True expected.", mfaAuthenticatorImpl.isEnabled());
}

@Test
public void authorizeEncryptedSecretVerificationCodeParametersTest() {
public void authorizeEncryptedSecretVerificationCodeParametersTest() throws KapuaException {
for (String encryptedSecret : encryptedSecrets) {
for (int verificationCode : verificationCodes) {
assertFalse("False expected.", mfaAuthenticatorImpl.authorize(encryptedSecret, verificationCode));
if (verificationCode >= 0) {
Assert.assertFalse(mfaAuthenticatorImpl.authorize(encryptedSecret, verificationCode));
} else {
try {
mfaAuthenticatorImpl.authorize(encryptedSecret, verificationCode);

Assert.fail("This should have thrown KapuaIllegalArgumentException");
} catch (KapuaIllegalArgumentException e) {
Assert.assertEquals("verificationCode", e.getArgumentName());
Assert.assertNull(e.getArgumentValue());
}
}
}
}
}

@Test(expected = NullPointerException.class)
public void authorizeNullEncryptedSecretVerificationCodeParametersTest() {
for (int verificationCode : verificationCodes) {
assertFalse("False expected.", mfaAuthenticatorImpl.authorize(null, verificationCode));
}
}
@Test
public void authorizeNullVerificationCodeParametersTest() throws KapuaException {
try {
mfaAuthenticatorImpl.authorize(encryptedSecrets[0], null);

@Test(expected = IllegalArgumentException.class)
public void authorizeEncryptedSecretNullVerificationCodeParametersTest() {
for (String encryptedSecret : encryptedSecrets) {
assertFalse("False expected.", mfaAuthenticatorImpl.authorize(encryptedSecret, null));
Assert.fail("This should have thrown KapuaIllegalNullArgumentException");
} catch (KapuaIllegalNullArgumentException e) {
Assert.assertEquals("verificationCode", e.getArgumentName());
Assert.assertNull(e.getArgumentValue());
}
}

@Test
public void authorizeHasedScratchCodeVerificationCodeParametersFalseTest() {
for (String hasedScratchCode : hashedScratchCodes) {
for (String stringVerificationCode : stringVerificationCodes) {
assertFalse("False expected.", mfaAuthenticatorImpl.authorize(hasedScratchCode, stringVerificationCode));
}
public void authorizeNullEncryptedSecretVerificationCodeParametersTest() throws KapuaException {
try {
mfaAuthenticatorImpl.authorize(null, "123456");

Assert.fail("This should have thrown KapuaIllegalNullArgumentException");
} catch (KapuaIllegalNullArgumentException e) {
Assert.assertEquals("hashedScratchCode", e.getArgumentName());
Assert.assertNull(e.getArgumentValue());
}
}

@Test
public void authorizeHasedScratchCodeVerificationCodeParametersTrueTest() {
assertTrue("True expected.", mfaAuthenticatorImpl.authorize("$2a$12$2AZYOAvilJyNvG8b6rBDaOSIcM3mKc6iyNQUYIXOF4ZFEAYdzM7Jm", "plainValue"));
}

@Test(expected = NullPointerException.class)
public void authorizeNullHasedScratchCodeVerificationCodeParametersTest() {
for (String stringVerificationCode : stringVerificationCodes) {
mfaAuthenticatorImpl.authorize(null, stringVerificationCode);
public void authorizeHashedScratchCodeVerificationCodeParametersFalseTest() throws KapuaException {
for (String hashedScratchCode : hashedScratchCodes) {
for (String stringVerificationCode : stringVerificationCodes) {
Assert.assertFalse(mfaAuthenticatorImpl.authorize(hashedScratchCode, stringVerificationCode));
}
}
}

@Test
public void authorizeHasedScratchCodeVerificationNullCodeParametersTest() {
for (String hasedScratchCode : hashedScratchCodes) {
assertFalse("False expected.", mfaAuthenticatorImpl.authorize(hasedScratchCode, null));
}
public void authorizeHashedScratchCodeVerificationCodeParametersTrueTest() throws KapuaException {
Assert.assertTrue(mfaAuthenticatorImpl.authorize("$2a$12$2AZYOAvilJyNvG8b6rBDaOSIcM3mKc6iyNQUYIXOF4ZFEAYdzM7Jm", "plainValue"));
}

@Test
public void generateKeyTest() {
assertEquals("Expected and actual values should be the same.", 32, mfaAuthenticatorImpl.generateKey().length());
String generatedKey = mfaAuthenticatorImpl.generateKey();

Assert.assertNotNull(generatedKey);
Assert.assertEquals(32, generatedKey.length());
}

@Test
public void generateCodesTest() {
assertEquals("Expected and actual values should be the same.", 5, mfaAuthenticatorImpl.generateCodes().size());
List<String> generatedScratchCodes = mfaAuthenticatorImpl.generateCodes();

Assert.assertNotNull(generatedScratchCodes);
Assert.assertEquals(5, generatedScratchCodes.size());
for (String generatedScratchCode : generatedScratchCodes) {
Assert.assertNotNull(generatedScratchCode);
}
}
}

0 comments on commit 6048f47

Please sign in to comment.