keycloak-uncached
Changes
services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleOTPFormAuthenticator.java 6(+3 -3)
services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleUsernamePasswordAuthenticator.java 7(+2 -5)
services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleTermsAndConditions.java 8(+2 -6)
services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdatePassword.java 9(+2 -7)
services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdateTotp.java 15(+3 -12)
services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleVerifyEmail.java 17(+3 -14)
services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java 23(+14 -9)
Details
diff --git a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
index db96f11..502ac6d 100755
--- a/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
+++ b/services/src/main/java/org/keycloak/authentication/AuthenticationProcessor.java
@@ -254,6 +254,19 @@ public class AuthenticationProcessor {
getAuthenticationSession().setAuthenticatedUser(null);
}
+ public URI getRefreshUrl(boolean authSessionIdParam) {
+ UriBuilder uriBuilder = LoginActionsService.loginActionsBaseUrl(getUriInfo())
+ .path(AuthenticationProcessor.this.flowPath)
+ .queryParam(Constants.CLIENT_ID, getAuthenticationSession().getClient().getClientId())
+ .queryParam(Constants.TAB_ID, getAuthenticationSession().getTabId());
+ if (authSessionIdParam) {
+ uriBuilder.queryParam(LoginActionsService.AUTH_SESSION_ID, getAuthenticationSession().getParentSession().getId());
+ }
+ return uriBuilder
+ .build(getRealm().getName());
+ }
+
+
public class Result implements AuthenticationFlowContext, ClientAuthenticationFlowContext {
AuthenticatorConfigModel authenticatorConfig;
AuthenticationExecutionModel execution;
@@ -546,15 +559,7 @@ public class AuthenticationProcessor {
@Override
public URI getRefreshUrl(boolean authSessionIdParam) {
- UriBuilder uriBuilder = LoginActionsService.loginActionsBaseUrl(getUriInfo())
- .path(AuthenticationProcessor.this.flowPath)
- .queryParam(Constants.CLIENT_ID, getAuthenticationSession().getClient().getClientId())
- .queryParam(Constants.TAB_ID, getAuthenticationSession().getTabId());
- if (authSessionIdParam) {
- uriBuilder.queryParam(LoginActionsService.AUTH_SESSION_ID, getAuthenticationSession().getParentSession().getId());
- }
- return uriBuilder
- .build(getRealm().getName());
+ return AuthenticationProcessor.this.getRefreshUrl(authSessionIdParam);
}
@Override
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleOTPFormAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleOTPFormAuthenticator.java
index fff2c80..0335b17 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleOTPFormAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleOTPFormAuthenticator.java
@@ -19,7 +19,7 @@ package org.keycloak.authentication.authenticators.console;
import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.Authenticator;
-import org.keycloak.authentication.TextChallenge;
+import org.keycloak.authentication.ConsoleDisplayMode;
import org.keycloak.authentication.authenticators.browser.OTPFormAuthenticator;
import org.keycloak.representations.idm.CredentialRepresentation;
@@ -37,8 +37,8 @@ public class ConsoleOTPFormAuthenticator extends OTPFormAuthenticator implements
return context.getActionUrl(context.generateAccessCode(), true);
}
- protected TextChallenge challenge(AuthenticationFlowContext context) {
- return TextChallenge.challenge(context)
+ protected ConsoleDisplayMode challenge(AuthenticationFlowContext context) {
+ return ConsoleDisplayMode.challenge(context)
.header()
.param(CredentialRepresentation.TOTP)
.label("console-otp")
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleUsernamePasswordAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleUsernamePasswordAuthenticator.java
index 4595df5..720e4e5 100755
--- a/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleUsernamePasswordAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/console/ConsoleUsernamePasswordAuthenticator.java
@@ -24,11 +24,8 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.services.messages.Messages;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import java.net.URI;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -43,8 +40,8 @@ public class ConsoleUsernamePasswordAuthenticator extends AbstractUsernameFormAu
return false;
}
- protected TextChallenge challenge(AuthenticationFlowContext context) {
- return TextChallenge.challenge(context)
+ protected ConsoleDisplayMode challenge(AuthenticationFlowContext context) {
+ return ConsoleDisplayMode.challenge(context)
.header()
.param("username")
.label("console-username")
diff --git a/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java b/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java
index ac0c5e1..21b5a60 100755
--- a/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java
+++ b/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java
@@ -70,7 +70,9 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow {
}
// todo create a provider for handling lack of display support
if (OAuth2Constants.DISPLAY_CONSOLE.equalsIgnoreCase(display)) {
- throw new AuthenticationFlowException(AuthenticationFlowError.DISPLAY_NOT_SUPPORTED, TextChallenge.browserRequired(processor.getSession()));
+ processor.getAuthenticationSession().removeClientNote(OAuth2Constants.DISPLAY);
+ throw new AuthenticationFlowException(AuthenticationFlowError.DISPLAY_NOT_SUPPORTED,
+ ConsoleDisplayMode.browserContinue(processor.getSession(), processor.getRefreshUrl(true).toString()));
} else {
return factory.create(processor.getSession());
diff --git a/services/src/main/java/org/keycloak/authentication/RequiredActionContextResult.java b/services/src/main/java/org/keycloak/authentication/RequiredActionContextResult.java
index 38b9c2f..f793234 100755
--- a/services/src/main/java/org/keycloak/authentication/RequiredActionContextResult.java
+++ b/services/src/main/java/org/keycloak/authentication/RequiredActionContextResult.java
@@ -65,6 +65,10 @@ public class RequiredActionContextResult implements RequiredActionContext {
this.factory = factory;
}
+ public RequiredActionFactory getFactory() {
+ return factory;
+ }
+
@Override
public EventBuilder getEvent() {
return eventBuilder;
@@ -170,7 +174,6 @@ public class RequiredActionContextResult implements RequiredActionContext {
uri = UriBuilder.fromUri(uri).queryParam(LoginActionsService.AUTH_SESSION_ID, getAuthenticationSession().getParentSession().getId()).build();
}
return uri;
-
}
@Override
diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleTermsAndConditions.java b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleTermsAndConditions.java
index 24c6938..1db910d 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleTermsAndConditions.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleTermsAndConditions.java
@@ -17,14 +17,10 @@
package org.keycloak.authentication.requiredactions;
-import org.keycloak.Config;
import org.keycloak.authentication.RequiredActionContext;
-import org.keycloak.authentication.RequiredActionFactory;
import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.authentication.TextChallenge;
+import org.keycloak.authentication.ConsoleDisplayMode;
import org.keycloak.common.util.Time;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
import javax.ws.rs.core.Response;
import java.util.Arrays;
@@ -45,7 +41,7 @@ public class ConsoleTermsAndConditions implements RequiredActionProvider {
@Override
public void requiredActionChallenge(RequiredActionContext context) {
- Response challenge = TextChallenge.challenge(context)
+ Response challenge = ConsoleDisplayMode.challenge(context)
.header()
.param("accept")
.label("console-accept-terms")
diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdatePassword.java b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdatePassword.java
index d499ead..461007a 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdatePassword.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdatePassword.java
@@ -18,7 +18,6 @@
package org.keycloak.authentication.requiredactions;
import org.jboss.logging.Logger;
-import org.keycloak.Config;
import org.keycloak.authentication.*;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
@@ -28,11 +27,7 @@ import org.keycloak.models.*;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import java.net.URI;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -45,8 +40,8 @@ public class ConsoleUpdatePassword extends UpdatePassword implements RequiredAct
public static final String PASSWORD_NEW = "password-new";
public static final String PASSWORD_CONFIRM = "password-confirm";
- protected TextChallenge challenge(RequiredActionContext context) {
- return TextChallenge.challenge(context)
+ protected ConsoleDisplayMode challenge(RequiredActionContext context) {
+ return ConsoleDisplayMode.challenge(context)
.header()
.param(PASSWORD_NEW)
.label("console-new-password")
diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdateTotp.java b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdateTotp.java
index 89ef89b..32751b9 100644
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdateTotp.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleUpdateTotp.java
@@ -17,28 +17,19 @@
package org.keycloak.authentication.requiredactions;
-import org.keycloak.Config;
import org.keycloak.authentication.RequiredActionContext;
-import org.keycloak.authentication.RequiredActionFactory;
import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.authentication.TextChallenge;
+import org.keycloak.authentication.ConsoleDisplayMode;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
-import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.forms.login.freemarker.model.TotpBean;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
import org.keycloak.models.utils.CredentialValidation;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import java.net.URI;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -61,8 +52,8 @@ public class ConsoleUpdateTotp implements RequiredActionProvider {
context.challenge(challenge);
}
- protected TextChallenge challenge(RequiredActionContext context) {
- return TextChallenge.challenge(context)
+ protected ConsoleDisplayMode challenge(RequiredActionContext context) {
+ return ConsoleDisplayMode.challenge(context)
.header()
.param("totp")
.label("console-otp")
diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleVerifyEmail.java b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleVerifyEmail.java
index e136ceb..e3c6ec5 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleVerifyEmail.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/ConsoleVerifyEmail.java
@@ -18,35 +18,24 @@
package org.keycloak.authentication.requiredactions;
import org.jboss.logging.Logger;
-import org.keycloak.Config;
import org.keycloak.authentication.RequiredActionContext;
-import org.keycloak.authentication.RequiredActionFactory;
import org.keycloak.authentication.RequiredActionProvider;
-import org.keycloak.authentication.TextChallenge;
-import org.keycloak.authentication.actiontoken.verifyemail.VerifyEmailActionToken;
+import org.keycloak.authentication.ConsoleDisplayMode;
import org.keycloak.common.util.RandomString;
-import org.keycloak.common.util.Time;
import org.keycloak.email.EmailException;
import org.keycloak.email.EmailTemplateProvider;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
-import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.*;
-import org.keycloak.services.Urls;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
-import org.keycloak.sessions.AuthenticationSessionCompoundId;
import org.keycloak.sessions.AuthenticationSessionModel;
import javax.ws.rs.core.*;
-import java.net.URI;
-import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.TimeUnit;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -114,8 +103,8 @@ public class ConsoleVerifyEmail implements RequiredActionProvider {
}
public static String EMAIL_CODE="email_code";
- protected TextChallenge challenge(RequiredActionContext context) {
- return TextChallenge.challenge(context)
+ protected ConsoleDisplayMode challenge(RequiredActionContext context) {
+ return ConsoleDisplayMode.challenge(context)
.header()
.param(EMAIL_CODE)
.label("console-email-code")
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index edb9b51..d6512d4 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -966,21 +966,22 @@ public class AuthenticationManager {
authSession.setProtocolMappers(requestedProtocolMappers);
}
- public static RequiredActionProvider createRequiredAction(KeycloakSession session, RequiredActionFactory factory, AuthenticationSessionModel authSession) {
- String display = authSession.getClientNote(OAuth2Constants.DISPLAY);
- if (display == null) return factory.create(session);
+ public static RequiredActionProvider createRequiredAction(RequiredActionContextResult context) {
+ String display = context.getAuthenticationSession().getClientNote(OAuth2Constants.DISPLAY);
+ if (display == null) return context.getFactory().create(context.getSession());
- if (factory instanceof DisplayTypeRequiredActionFactory) {
- RequiredActionProvider provider = ((DisplayTypeRequiredActionFactory)factory).createDisplay(session, display);
+ if (context.getFactory() instanceof DisplayTypeRequiredActionFactory) {
+ RequiredActionProvider provider = ((DisplayTypeRequiredActionFactory)context.getFactory()).createDisplay(context.getSession(), display);
if (provider != null) return provider;
}
// todo create a provider for handling lack of display support
if (OAuth2Constants.DISPLAY_CONSOLE.equalsIgnoreCase(display)) {
- throw new AuthenticationFlowException(AuthenticationFlowError.DISPLAY_NOT_SUPPORTED, TextChallenge.browserRequired(session));
+ context.getAuthenticationSession().removeClientNote(OAuth2Constants.DISPLAY);
+ throw new AuthenticationFlowException(AuthenticationFlowError.DISPLAY_NOT_SUPPORTED, ConsoleDisplayMode.browserContinue(context.getSession(), context.getUriInfo().getRequestUri().toString()));
} else {
- return factory.create(session);
+ return context.getFactory().create(context.getSession());
}
}
@@ -1002,16 +1003,16 @@ public class AuthenticationManager {
if (factory == null) {
throw new RuntimeException("Unable to find factory for Required Action: " + model.getProviderId() + " did you forget to declare it in a META-INF/services file?");
}
+ RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, user, factory);
RequiredActionProvider actionProvider = null;
try {
- actionProvider = createRequiredAction(session, factory, authSession);
+ actionProvider = createRequiredAction(context);
} catch (AuthenticationFlowException e) {
if (e.getResponse() != null) {
return e.getResponse();
}
throw e;
}
- RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, user, factory);
actionProvider.requiredActionChallenge(context);
if (context.getStatus() == RequiredActionContext.Status.FAILURE) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
index 09892cb..f689f6e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java
@@ -306,6 +306,16 @@ public class AuthenticationManagementResource {
logger.debug("flow not found: " + flowAlias);
return Response.status(NOT_FOUND).build();
}
+ AuthenticationFlowModel copy = copyFlow(realm, flow, newName);
+
+ data.put("id", copy.getId());
+ adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
+
+ return Response.status(Response.Status.CREATED).build();
+
+ }
+
+ public static AuthenticationFlowModel copyFlow(RealmModel realm, AuthenticationFlowModel flow, String newName) {
AuthenticationFlowModel copy = new AuthenticationFlowModel();
copy.setAlias(newName);
copy.setDescription(flow.getDescription());
@@ -313,16 +323,11 @@ public class AuthenticationManagementResource {
copy.setBuiltIn(false);
copy.setTopLevel(flow.isTopLevel());
copy = realm.addAuthenticationFlow(copy);
- copy(newName, flow, copy);
-
- data.put("id", copy.getId());
- adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success();
-
- return Response.status(Response.Status.CREATED).build();
-
+ copy(realm, newName, flow, copy);
+ return copy;
}
- protected void copy(String newName, AuthenticationFlowModel from, AuthenticationFlowModel to) {
+ public static void copy(RealmModel realm, String newName, AuthenticationFlowModel from, AuthenticationFlowModel to) {
for (AuthenticationExecutionModel execution : realm.getAuthenticationExecutions(from.getId())) {
if (execution.isAuthenticatorFlow()) {
AuthenticationFlowModel subFlow = realm.getAuthenticationFlowById(execution.getFlowId());
@@ -334,7 +339,7 @@ public class AuthenticationManagementResource {
copy.setTopLevel(false);
copy = realm.addAuthenticationFlow(copy);
execution.setFlowId(copy.getId());
- copy(newName, subFlow, copy);
+ copy(realm, newName, subFlow, copy);
}
execution.setId(null);
execution.setParentFlow(to.getId());
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index ef9525a..f517c7d 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -929,9 +929,15 @@ public class LoginActionsService {
event.error(Errors.INVALID_CODE);
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, Messages.INVALID_CODE));
}
+ RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, authSession.getAuthenticatedUser(), factory) {
+ @Override
+ public void ignore() {
+ throw new RuntimeException("Cannot call ignore within processAction()");
+ }
+ };
RequiredActionProvider provider = null;
try {
- provider = AuthenticationManager.createRequiredAction(session, factory, authSession);
+ provider = AuthenticationManager.createRequiredAction(context);
} catch (AuthenticationFlowException e) {
if (e.getResponse() != null) {
return e.getResponse();
@@ -939,12 +945,6 @@ public class LoginActionsService {
throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, Messages.DISPLAY_UNSUPPORTED));
}
- RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, authSession.getAuthenticatedUser(), factory) {
- @Override
- public void ignore() {
- throw new RuntimeException("Cannot call ignore within processAction()");
- }
- };
Response response;
provider.processAction(context);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java
index f23a63c..0ff37f8 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/KcinitTest.java
@@ -31,14 +31,18 @@ import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.*;
+import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
+import org.keycloak.services.resources.admin.AuthenticationManagementResource;
import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.AssertEvents;
+import org.keycloak.testsuite.authentication.PushButtonAuthenticator;
+import org.keycloak.testsuite.authentication.PushButtonAuthenticatorFactory;
import org.keycloak.testsuite.forms.PassThroughAuthenticator;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.ErrorPage;
@@ -98,6 +102,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
kcinit.setSecret("password");
kcinit.setEnabled(true);
kcinit.addRedirectUri("urn:ietf:wg:oauth:2.0:oob");
+ kcinit.addRedirectUri("http://localhost:*");
kcinit.setPublicClient(false);
ClientModel app = realm.addClient(APP);
@@ -154,13 +159,25 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
execution.setParentFlow(browser.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setPriority(20);
- execution.setAuthenticator(PassThroughAuthenticator.PROVIDER_ID);
+ execution.setAuthenticator(PushButtonAuthenticatorFactory.PROVIDER_ID);
+ realm.addAuthenticatorExecution(execution);
+
+ AuthenticationFlowModel browserBuiltin = realm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
+ AuthenticationFlowModel copy = AuthenticationManagementResource.copyFlow(realm, browserBuiltin, "copy-browser");
+ copy.setTopLevel(false);
+ realm.updateAuthenticationFlow(copy);
+ execution = new AuthenticationExecutionModel();
+ execution.setParentFlow(browser.getId());
+ execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
+ execution.setFlowId(copy.getId());
+ execution.setPriority(30);
+ execution.setAuthenticatorFlow(true);
realm.addAuthenticatorExecution(execution);
});
}
- //@Test
+ @Test
public void testDemo() throws Exception {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
@@ -193,7 +210,9 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
});
+ Thread.sleep(100000000);
+ /*
testInstall();
// login
//System.out.println("login....");
@@ -204,6 +223,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
Assert.assertEquals(1, exe.exitCode());
Assert.assertTrue(exe.stderrString().contains("Browser required to login"));
//Assert.assertEquals("stderr first line", "Browser required to login", exe.stderrLines().get(1));
+ */
testingClient.server().run(session -> {
diff --git a/themes/src/main/resources/theme/base/login/messages/messages_en.properties b/themes/src/main/resources/theme/base/login/messages/messages_en.properties
index 5f4c6a2..65f23c5 100755
--- a/themes/src/main/resources/theme/base/login/messages/messages_en.properties
+++ b/themes/src/main/resources/theme/base/login/messages/messages_en.properties
@@ -36,6 +36,10 @@ codeSuccessTitle=Success code
codeErrorTitle=Error code\: {0}
displayUnsupported=Requested display type unsupported
browserRequired=Browser required to login
+browserContinue=Browser required to complete login
+browserContinuePrompt=Open browser and continue login? [y/n]:
+browserContinueAnswer=y
+
termsTitle=Terms and Conditions
termsText=<p>Terms and conditions to be defined</p>