Search in sources :

Example 6 with RequiredActionProviderRepresentation

use of org.keycloak.representations.idm.RequiredActionProviderRepresentation in project keycloak by keycloak.

the class ResetCredentialsAlternativeFlowsTest method deviceNameOptionalForFirstOTPCredentialButRequiredForEachNextOne.

// KEYCLOAK-12168 Verify the 'Device Name' label is optional for the first OTP credential created
// (either via Account page or by registering new user), but required for each next created OTP credential
@Test
// TODO remove this (KEYCLOAK-16228)
@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true)
public void deviceNameOptionalForFirstOTPCredentialButRequiredForEachNextOne() {
    // Enable 'Default Action' on 'Configure OTP' RA for the 'test' realm
    RequiredActionProviderRepresentation otpRequiredAction = testRealm().flows().getRequiredAction("CONFIGURE_TOTP");
    otpRequiredAction.setDefaultAction(true);
    testRealm().flows().updateRequiredAction("CONFIGURE_TOTP", otpRequiredAction);
    try {
        // Make a copy of the default Reset Credentials flow, but:
        // * Without 'Send Reset Email' authenticator,
        // * Without 'Reset Password' authenticator
        final String newFlowAlias = "resetcred - KEYCLOAK-12168 - firstOTP - account - test";
        configureResetCredentialsRemoveExecutionsAndBindTheFlow(newFlowAlias, Arrays.asList("reset-credential-email", "reset-password"));
        /* Verify the 'Device Name' is optional when creating new OTP credential via the Account page */
        // Login & set up the initial OTP code for the user
        loginPage.open();
        loginPage.login("login@test.com", "password");
        accountTotpPage.open();
        Assert.assertTrue(accountTotpPage.isCurrent());
        String pageSource = driver.getPageSource();
        // Check the One-time code label is followed by asterisk character (since always required)
        final String oneTimeCodeLabelFollowedByAsterisk = "(?s)<label for=\"totp\"((?!</span>).)+((?=<span class=\"required\">\\*).)*";
        Assert.assertTrue(Pattern.compile(oneTimeCodeLabelFollowedByAsterisk).matcher(pageSource).find());
        // Check the Device Name label is not followed by asterisk character (since optional if no OTP credential defined yet)
        final String asteriskPrecededByDeviceNameLabel = "(?s)((?<=<label for=\"userLabel\").)+.*<span class=\"required\">\\s+\\*";
        Assert.assertFalse(Pattern.compile(asteriskPrecededByDeviceNameLabel).matcher(pageSource).find());
        // Create OTP credential with empty label
        final String emptyOtpLabel = "";
        accountTotpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), emptyOtpLabel);
        // Get the updated Account TOTP page source post OTP credential creation
        pageSource = driver.getPageSource();
        // Check if OTP credential with empty label was created successfully
        assertThat(driver.findElements(By.className("provider")).stream().map(WebElement::getText).collect(Collectors.toList()), Matchers.hasItem(""));
        accountTotpPage.removeTotp();
        // Logout
        oauth.openLogout();
        /* Verify the 'Device Name' is optional when creating the first OTP credential via the login config TOTP page */
        // Register new user
        loginPage.open();
        loginPage.clickRegister();
        registerPage.assertCurrent();
        registerPage.register("Bruce", "Wilson", "bwilson@keycloak.org", "bwilson", "password", "password");
        Assert.assertTrue(totpPage.isCurrent());
        pageSource = driver.getPageSource();
        // Check the One-time code label is required
        Assert.assertTrue(Pattern.compile(oneTimeCodeLabelFollowedByAsterisk).matcher(pageSource).find());
        // Check the Device Name label is optional
        Assert.assertFalse(Pattern.compile(asteriskPrecededByDeviceNameLabel).matcher(pageSource).find());
        // Create OTP credential with empty label
        totpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), emptyOtpLabel);
        Assert.assertNull(totpPage.getAlertError());
        Assert.assertNull(totpPage.getInputCodeError());
        Assert.assertNull(totpPage.getInputLabelError());
        // Assert user authenticated
        appPage.assertCurrent();
        Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
        Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
        accountTotpPage.open();
        Assert.assertTrue(accountTotpPage.isCurrent());
        // Check if OTP credential with empty label was created successfully
        assertThat(driver.findElements(By.className("provider")).stream().map(WebElement::getText).collect(Collectors.toList()), Matchers.hasItem(""));
        ;
        // Logout
        oauth.openLogout();
        /* Verify the 'Device Name' is required for each next OTP credential created via the login config TOTP page */
        // Click "Forgot password" to define another OTP credential
        loginPage.open();
        loginPage.resetPassword();
        // Should be on reset password page now. Provide email of previously registered user & click Submit button
        Assert.assertTrue(resetPasswordPage.isCurrent());
        resetPasswordPage.changePassword("bwilson@keycloak.org");
        pageSource = driver.getPageSource();
        // Check the One-time code label is required
        Assert.assertTrue(Pattern.compile(oneTimeCodeLabelFollowedByAsterisk).matcher(pageSource).find());
        // Check the Device Name label is required (since one OTP credential already defined)
        final String deviceNameLabelFollowedByAsterisk = "(?s)<label for=\"userLabel\"((?!</span>).)+((?=<span class=\"required\">\\*).)*";
        Assert.assertTrue(Pattern.compile(deviceNameLabelFollowedByAsterisk).matcher(pageSource).find());
        // Try to create another OTP credential with empty label again. This
        // should fail with error since OTP label is required in this case already
        final String deviceNameLabelRequiredErrorMessage = "Please specify device name.";
        totpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), emptyOtpLabel);
        Assert.assertTrue(totpPage.getInputLabelError().equals(deviceNameLabelRequiredErrorMessage));
        // Create 2nd OTP credential with valid (non-empty) Device Name label. This should pass
        final String secondOtpLabel = "My 2nd OTP device";
        totpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), secondOtpLabel);
        Assert.assertNull(totpPage.getAlertError());
        Assert.assertNull(totpPage.getInputCodeError());
        Assert.assertNull(totpPage.getInputLabelError());
        // Assert user authenticated
        appPage.assertCurrent();
        Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
        Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
        accountTotpPage.open();
        Assert.assertTrue(accountTotpPage.isCurrent());
        // Get the updated Account TOTP page source after both the OTP credentials were created
        pageSource = driver.getPageSource();
        // Verify 2nd OTP credential was successfully created too
        Assert.assertTrue(pageSource.contains(secondOtpLabel));
        // Remove both OTP credentials
        accountTotpPage.removeTotp();
        accountTotpPage.removeTotp();
        // Logout
        oauth.openLogout();
    // Undo setup changes performed within the test
    } finally {
        revertFlows();
        // Disable 'Default Action' on 'Configure OTP' RA for the 'test' realm
        otpRequiredAction.setDefaultAction(false);
        testRealm().flows().updateRequiredAction("CONFIGURE_TOTP", otpRequiredAction);
        // Remove the within test registered 'bwilson' user
        testingClient.server("test").run(session -> {
            UserManager um = new UserManager(session);
            UserModel user = session.users().getUserByUsername(session.getContext().getRealm(), "bwilson");
            if (user != null) {
                um.removeUser(session.getContext().getRealm(), user);
            }
        });
    }
}
Also used : RequiredActionProviderRepresentation(org.keycloak.representations.idm.RequiredActionProviderRepresentation) UserModel(org.keycloak.models.UserModel) UserManager(org.keycloak.models.UserManager) WebElement(org.openqa.selenium.WebElement) DisableFeature(org.keycloak.testsuite.arquillian.annotation.DisableFeature) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest) AbstractAuthenticationTest(org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest)

Example 7 with RequiredActionProviderRepresentation

use of org.keycloak.representations.idm.RequiredActionProviderRepresentation in project keycloak by keycloak.

the class BrowserFlowTest method testLoginWithWithNoOTPCredentialAndNoRequiredActionProviderRegistered.

/**
 * This test checks that if a REQUIRED authentication execution which has isUserSetupAllowed -> true
 * has its requiredActionProvider in a not registered state, then it will not try to create the required action,
 * and will instead raise an credential setup required error.
 */
@Test
@AuthServerContainerExclude(REMOTE)
public void testLoginWithWithNoOTPCredentialAndNoRequiredActionProviderRegistered() {
    String newFlowAlias = "browser - copy 1";
    configureBrowserFlowWithRequiredOTP(newFlowAlias);
    RequiredActionProviderRepresentation otpRequiredAction = testRealm().flows().getRequiredAction("CONFIGURE_TOTP");
    testRealm().flows().removeRequiredAction("CONFIGURE_TOTP");
    try {
        provideUsernamePassword("test-user@localhost");
        // Assert that the login evaluates to an error, as all required elements to not validate to successful
        errorPage.assertCurrent();
    } finally {
        revertFlows("browser - copy 1");
        RequiredActionProviderSimpleRepresentation simpleRepresentation = new RequiredActionProviderSimpleRepresentation();
        simpleRepresentation.setProviderId("CONFIGURE_TOTP");
        simpleRepresentation.setName(otpRequiredAction.getName());
        testRealm().flows().registerRequiredAction(simpleRepresentation);
    }
}
Also used : RequiredActionProviderRepresentation(org.keycloak.representations.idm.RequiredActionProviderRepresentation) RequiredActionProviderSimpleRepresentation(org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation) Matchers.containsString(org.hamcrest.Matchers.containsString) AuthServerContainerExclude(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude) SocialLoginTest(org.keycloak.testsuite.broker.SocialLoginTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest) AbstractAuthenticationTest(org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest)

Example 8 with RequiredActionProviderRepresentation

use of org.keycloak.representations.idm.RequiredActionProviderRepresentation in project keycloak by keycloak.

the class BrowserFlowTest method testLoginWithWithNoWebAuthnCredentialAndRequiredActionProviderDisabled.

/**
 * This test checks that if a REQUIRED authentication execution which has isUserSetupAllowed -> true
 * has its requiredActionProvider disabled, then it will not try to create the required action,
 * and will instead raise an credential setup required error.
 * NOTE: webauthn currently isn't configured by default in the realm. When this changes, this test will need to be adapted
 */
@Test
@AuthServerContainerExclude(REMOTE)
public void testLoginWithWithNoWebAuthnCredentialAndRequiredActionProviderDisabled() {
    String newFlowAlias = "browser - copy 1";
    configureBrowserFlowWithRequiredWebAuthn(newFlowAlias);
    RequiredActionProviderSimpleRepresentation requiredActionRepresentation = new RequiredActionProviderSimpleRepresentation();
    requiredActionRepresentation.setName("WebAuthn Required Action");
    requiredActionRepresentation.setProviderId(WebAuthnRegisterFactory.PROVIDER_ID);
    testRealm().flows().registerRequiredAction(requiredActionRepresentation);
    RequiredActionProviderRepresentation rapr = testRealm().flows().getRequiredAction(WebAuthnRegisterFactory.PROVIDER_ID);
    rapr.setEnabled(false);
    testRealm().flows().updateRequiredAction(WebAuthnRegisterFactory.PROVIDER_ID, rapr);
    try {
        provideUsernamePassword("test-user@localhost");
        // Assert that the login evaluates to an error, as all required elements to not validate to successful
        errorPage.assertCurrent();
    } finally {
        revertFlows("browser - copy 1");
        testRealm().flows().removeRequiredAction(WebAuthnRegisterFactory.PROVIDER_ID);
    }
}
Also used : RequiredActionProviderRepresentation(org.keycloak.representations.idm.RequiredActionProviderRepresentation) RequiredActionProviderSimpleRepresentation(org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation) Matchers.containsString(org.hamcrest.Matchers.containsString) AuthServerContainerExclude(org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude) SocialLoginTest(org.keycloak.testsuite.broker.SocialLoginTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest) AbstractAuthenticationTest(org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest)

Example 9 with RequiredActionProviderRepresentation

use of org.keycloak.representations.idm.RequiredActionProviderRepresentation in project keycloak by keycloak.

the class AuthenticationManagementResource method toRepresentation.

public static RequiredActionProviderRepresentation toRepresentation(RequiredActionProviderModel model) {
    RequiredActionProviderRepresentation rep = new RequiredActionProviderRepresentation();
    rep.setAlias(model.getAlias());
    rep.setProviderId(model.getProviderId());
    rep.setName(model.getName());
    rep.setDefaultAction(model.isDefaultAction());
    rep.setPriority(model.getPriority());
    rep.setEnabled(model.isEnabled());
    rep.setConfig(model.getConfig());
    return rep;
}
Also used : RequiredActionProviderRepresentation(org.keycloak.representations.idm.RequiredActionProviderRepresentation)

Example 10 with RequiredActionProviderRepresentation

use of org.keycloak.representations.idm.RequiredActionProviderRepresentation in project keycloak by keycloak.

the class ManyUsersTest method before.

@Before
public void before() {
    log.infof("Reading users after create is %s", READ_USER_AFTER_CREATE ? "ENABLED" : "DISABLED");
    users = new LinkedList<>();
    for (int i = 0; i < COUNT; i++) {
        users.add(createUserRep("user" + i));
    }
    realmTimer.reset("create realm before test");
    createRealm(REALM);
    if (CREATE_OBJECTS) {
        // Assuming default groups and required action already created
        if (realmResource().getDefaultGroups().isEmpty()) {
            log.infof("Creating default groups 'group1' and 'group2'.");
            setDefaultGroup("group1");
            setDefaultGroup("group2");
            RequiredActionProviderRepresentation updatePassword = realmResource().flows().getRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString());
            updatePassword.setDefaultAction(true);
            realmResource().flows().updateRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD.toString(), updatePassword);
        }
    }
    refreshToken();
}
Also used : RequiredActionProviderRepresentation(org.keycloak.representations.idm.RequiredActionProviderRepresentation) Before(org.junit.Before)

Aggregations

RequiredActionProviderRepresentation (org.keycloak.representations.idm.RequiredActionProviderRepresentation)33 Test (org.junit.Test)13 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)6 UserRepresentation (org.keycloak.representations.idm.UserRepresentation)5 ArrayList (java.util.ArrayList)4 RealmResource (org.keycloak.admin.client.resource.RealmResource)4 RequiredActionProviderSimpleRepresentation (org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation)4 AbstractAuthenticationTest (org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest)4 LinkedList (java.util.LinkedList)3 Matchers.containsString (org.hamcrest.Matchers.containsString)3 Before (org.junit.Before)3 AuthServerContainerExclude (org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude)3 SocialLoginTest (org.keycloak.testsuite.broker.SocialLoginTest)3 HashMap (java.util.HashMap)2 NotFoundException (javax.ws.rs.NotFoundException)2 SigningInPage (org.keycloak.testsuite.ui.account2.page.SigningInPage)2 HashSet (java.util.HashSet)1 List (java.util.List)1 Map (java.util.Map)1 Response (javax.ws.rs.core.Response)1