package org.keycloak.services.managers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserModel.RequiredAction;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.AuthenticationManager.AuthenticationStatus;
import org.keycloak.test.common.AbstractKeycloakTest;
import org.keycloak.test.common.SessionFactoryTestContext;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import java.util.UUID;
public class AuthenticationManagerTest extends AbstractKeycloakTest {
private AuthenticationManager am;
private MultivaluedMap<String, String> formData;
private TimeBasedOTP otp;
private RealmModel realm;
private UserModel user;
public AuthenticationManagerTest(SessionFactoryTestContext testContext) {
super(testContext);
}
@Test
public void authForm() {
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
}
@Test
public void authFormInvalidPassword() {
formData.remove(CredentialRepresentation.PASSWORD);
formData.add(CredentialRepresentation.PASSWORD, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormMissingPassword() {
formData.remove(CredentialRepresentation.PASSWORD);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.MISSING_PASSWORD, status);
}
@Test
public void authFormRequiredAction() {
realm.addRequiredCredential(CredentialRepresentation.TOTP);
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.ACTIONS_REQUIRED, status);
}
@Test
public void authFormUserDisabled() {
user.setEnabled(false);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.ACCOUNT_DISABLED, status);
}
@Test
public void authFormWithTotp() {
realm.addRequiredCredential(CredentialRepresentation.TOTP);
String totpSecret = UUID.randomUUID().toString();
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.TOTP);
credential.setValue(totpSecret);
realm.updateCredential(user, credential);
user.setTotp(true);
String token = otp.generate(totpSecret);
formData.add(CredentialRepresentation.TOTP, token);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.SUCCESS, status);
}
@Test
public void authFormWithTotpInvalidPassword() {
authFormWithTotp();
formData.remove(CredentialRepresentation.PASSWORD);
formData.add(CredentialRepresentation.PASSWORD, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormWithTotpInvalidTotp() {
authFormWithTotp();
formData.remove(CredentialRepresentation.TOTP);
formData.add(CredentialRepresentation.TOTP, "invalid");
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.INVALID_CREDENTIALS, status);
}
@Test
public void authFormWithTotpMissingTotp() {
authFormWithTotp();
formData.remove(CredentialRepresentation.TOTP);
AuthenticationStatus status = am.authenticateForm(realm, user, formData);
Assert.assertEquals(AuthenticationStatus.MISSING_TOTP, status);
}
@Before
public void before() throws Exception {
super.before();
realm = getRealmManager().createRealm("Test");
realm.setAccessCodeLifespan(100);
realm.setEnabled(true);
realm.setName("Test");
realm.setPrivateKeyPem("0234234");
realm.setPublicKeyPem("0234234");
realm.setTokenLifespan(1000);
realm.addRequiredCredential(CredentialRepresentation.PASSWORD);
am = new AuthenticationManager();
user = realm.addUser("test");
user.setEnabled(true);
UserCredentialModel credential = new UserCredentialModel();
credential.setType(CredentialRepresentation.PASSWORD);
credential.setValue("password");
realm.updateCredential(user, credential);
formData = new MultivaluedHashMap<String, String>();
formData.add(CredentialRepresentation.PASSWORD, "password");
otp = new TimeBasedOTP();
}
}