Details
diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml
index 01ad7e6..4dc4b32 100755
--- a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml
@@ -130,15 +130,14 @@ cd <WILDFLY_HOME>/bin
<section>
<title>Admin User</title>
<para>
- To access the admin console you need an account to login. Currently, there's a default account added
- with the username <literal>admin</literal> and password <literal>admin</literal>. You will be required
- to change the password on first login. We are planning on removing the built-in account soon and will
- instead have an initial step to create the user.
+ To access the admin console to configure Keycloak you need an account to login. There is no built in user,
+ instead you have to first create an admin account. This can done either by opening <ulink url="http://localhost:8080/auth">http://localhost:8080/auth</ulink>
+ (creating a user through the browser can only be done through localhost) or you can use the add-user script from
+ the command-line.
</para>
<para>
- You can also create a user with the <literal>add-user</literal> script found in <literal>bin</literal>.
- This script will create a temporary file with the details of the user, which are imported at startup.
- To add a user with this script run:
+ The <literal>add-user</literal> script creates a temporary file with the details of the user,
+ which are imported at startup. To add a user with this script run:
<programlisting><![CDATA[
bin/add-user.[sh|bat] -r master -u <username> -p <password>
]]></programlisting>
diff --git a/services/src/main/java/org/keycloak/exportimport/ExportImportManager.java b/services/src/main/java/org/keycloak/exportimport/ExportImportManager.java
index cedcbdd..4f94b52 100644
--- a/services/src/main/java/org/keycloak/exportimport/ExportImportManager.java
+++ b/services/src/main/java/org/keycloak/exportimport/ExportImportManager.java
@@ -2,10 +2,9 @@ package org.keycloak.exportimport;
import org.jboss.logging.Logger;
-import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.services.managers.ApplianceBootstrap;
+
+import java.io.IOException;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -14,76 +13,82 @@ public class ExportImportManager {
private static final Logger logger = Logger.getLogger(ExportImportManager.class);
- public void checkExportImport(KeycloakSessionFactory sessionFactory, String contextPath) {
+ private KeycloakSession session;
+
+ private final String realmName;
+
+ private ExportProvider exportProvider;
+ private ImportProvider importProvider;
+
+ public ExportImportManager(KeycloakSession session) {
+ this.session = session;
+
+ realmName = ExportImportConfig.getRealmName();
+
+ String providerId = ExportImportConfig.getProvider();
String exportImportAction = ExportImportConfig.getAction();
- String realmName = ExportImportConfig.getRealmName();
- boolean export = false;
- boolean importt = false;
if (ExportImportConfig.ACTION_EXPORT.equals(exportImportAction)) {
- export = true;
+ exportProvider = session.getProvider(ExportProvider.class, providerId);
+ if (exportProvider == null) {
+ throw new RuntimeException("Export provider not found");
+ }
} else if (ExportImportConfig.ACTION_IMPORT.equals(exportImportAction)) {
- importt = true;
+ importProvider = session.getProvider(ImportProvider.class, providerId);
+ if (importProvider == null) {
+ throw new RuntimeException("Import provider not found");
+ }
+ }
+ }
+
+ public boolean isRunImport() {
+ return importProvider != null;
+ }
+
+ public boolean isImportMasterIncluded() {
+ if (!isRunImport()) {
+ throw new IllegalStateException("Import not enabled");
+ }
+ try {
+ return importProvider.isMasterRealmExported();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
+ }
+
+ public boolean isRunExport() {
+ return exportProvider != null;
+ }
- if (export || importt) {
- String exportImportProviderId = ExportImportConfig.getProvider();
- logger.debug("Will use provider: " + exportImportProviderId);
- KeycloakSession session = sessionFactory.create();
-
- try {
- if (export) {
- ExportProvider exportProvider = session.getProvider(ExportProvider.class, exportImportProviderId);
-
- if (exportProvider == null) {
- logger.errorf("Invalid Export Provider %s", exportImportProviderId);
- } else {
- if (realmName == null) {
- logger.info("Full model export requested");
- exportProvider.exportModel(sessionFactory);
- } else {
- logger.infof("Export of realm '%s' requested", realmName);
- exportProvider.exportRealm(sessionFactory, realmName);
- }
- logger.info("Export finished successfully");
- }
- } else {
- ImportProvider importProvider = session.getProvider(ImportProvider.class, exportImportProviderId);
-
- if (importProvider == null) {
- logger.errorf("Invalid Import Provider %s", exportImportProviderId);
- } else {
-
- Strategy strategy = ExportImportConfig.getStrategy();
- if (realmName == null) {
- logger.infof("Full model import requested. Strategy: %s", strategy.toString());
-
- // Check if master realm was exported. If it's not, then it needs to be created before other realms are imported
- if (!importProvider.isMasterRealmExported()) {
- ApplianceBootstrap.setupDefaultRealm(sessionFactory, contextPath);
- ApplianceBootstrap.setupDefaultUser(sessionFactory);
- }
-
- importProvider.importModel(sessionFactory, strategy);
- } else {
- logger.infof("Import of realm '%s' requested. Strategy: %s", realmName, strategy.toString());
-
- if (!realmName.equals(Config.getAdminRealm())) {
- // Check if master realm exists. If it's not, then it needs to be created before other realm is imported
- ApplianceBootstrap.setupDefaultRealm(sessionFactory, contextPath);
- ApplianceBootstrap.setupDefaultUser(sessionFactory);
- }
-
- importProvider.importRealm(sessionFactory, realmName, strategy);
- }
- logger.info("Import finished successfully");
- }
- }
- } catch (Throwable ioe) {
- logger.error("Error during export/import", ioe);
- } finally {
- session.close();
+ public void runImport() {
+ try {
+ Strategy strategy = ExportImportConfig.getStrategy();
+ if (realmName == null) {
+ logger.infof("Full model import requested. Strategy: %s", strategy.toString());
+ importProvider.importModel(session.getKeycloakSessionFactory(), strategy);
+ } else {
+ logger.infof("Import of realm '%s' requested. Strategy: %s", realmName, strategy.toString());
+ importProvider.importRealm(session.getKeycloakSessionFactory(), realmName, strategy);
}
+ logger.info("Import finished successfully");
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to run import", e);
}
}
+
+ public void runExport() {
+ try {
+ if (realmName == null) {
+ logger.info("Full model export requested");
+ exportProvider.exportModel(session.getKeycloakSessionFactory());
+ } else {
+ logger.infof("Export of realm '%s' requested", realmName);
+ exportProvider.exportRealm(session.getKeycloakSessionFactory(), realmName);
+ }
+ logger.info("Export finished successfully");
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to run export");
+ }
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index 8402016..829dd6c 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -4,15 +4,7 @@ import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.common.Version;
import org.keycloak.common.enums.SslRequired;
-import org.keycloak.models.AdminRoles;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.Constants;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserCredentialModel;
-import org.keycloak.models.UserModel;
+import org.keycloak.models.*;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.CredentialRepresentation;
@@ -23,17 +15,34 @@ import org.keycloak.representations.idm.CredentialRepresentation;
public class ApplianceBootstrap {
private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class);
+ private final KeycloakSession session;
- public static boolean setupDefaultRealm(KeycloakSessionFactory sessionFactory, String contextPath) {
- KeycloakSession session = sessionFactory.create();
- session.getTransaction().begin();
+ public ApplianceBootstrap(KeycloakSession session) {
+ this.session = session;
+ }
+
+ public boolean isNewInstall() {
+ if (session.realms().getRealms().size() > 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ public boolean isNoMasterUser() {
+ RealmModel realm = session.realms().getRealm(Config.getAdminRealm());
+ return session.users().getUsersCount(realm) == 0;
+ }
+
+ public boolean createMasterRealm(String contextPath) {
+ if (!isNewInstall()) {
+ throw new IllegalStateException("Can't create default realm as realms already exists");
+ }
+
+ KeycloakSession session = this.session.getKeycloakSessionFactory().create();
try {
+ session.getTransaction().begin();
String adminRealmName = Config.getAdminRealm();
- if (session.realms().getRealm(adminRealmName) != null) {
- return false;
- }
-
logger.info("Initializing " + adminRealmName + " realm");
RealmManager manager = new RealmManager(session);
@@ -58,41 +67,29 @@ public class ApplianceBootstrap {
KeycloakModelUtils.generateRealmKeys(realm);
session.getTransaction().commit();
- return true;
} finally {
session.close();
}
- }
- public static boolean setupDefaultUser(KeycloakSessionFactory sessionFactory) {
- KeycloakSession session = sessionFactory.create();
- session.getTransaction().begin();
+ return true;
+ }
- try {
- RealmModel realm = session.realms().getRealm(Config.getAdminRealm());
- if (session.users().getUserByUsername("admin", realm) == null) {
- UserModel adminUser = session.users().addUser(realm, "admin");
-
- adminUser.setEnabled(true);
- UserCredentialModel usrCredModel = new UserCredentialModel();
- usrCredModel.setType(UserCredentialModel.PASSWORD);
- usrCredModel.setValue("admin");
- session.users().updateCredential(realm, adminUser, usrCredModel);
- adminUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
-
- RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
- adminUser.grantRole(adminRole);
-
- ClientModel accountApp = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
- for (String r : accountApp.getDefaultRoles()) {
- adminUser.grantRole(accountApp.getRole(r));
- }
- }
- session.getTransaction().commit();
- return true;
- } finally {
- session.close();
+ public void createMasterRealmUser(KeycloakSession session, String username, String password) {
+ RealmModel realm = session.realms().getRealm(Config.getAdminRealm());
+ if (session.users().getUsersCount(realm) > 0) {
+ throw new IllegalStateException("Can't create initial user as users already exists");
}
+
+ UserModel adminUser = session.users().addUser(realm, username);
+ adminUser.setEnabled(true);
+
+ UserCredentialModel usrCredModel = new UserCredentialModel();
+ usrCredModel.setType(UserCredentialModel.PASSWORD);
+ usrCredModel.setValue(password);
+ session.users().updateCredential(realm, adminUser, usrCredModel);
+
+ RoleModel adminRole = realm.getRole(AdminRoles.ADMIN);
+ adminUser.grantRole(adminRole);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
index 5c22200..50e33dd 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
@@ -264,10 +264,7 @@ public class AdminConsole {
if (!uriInfo.getRequestUri().getPath().endsWith("/")) {
return Response.status(302).location(uriInfo.getRequestUriBuilder().path("/").build()).build();
} else {
- String adminTheme = realm.getAdminTheme();
- if (adminTheme == null) {
- adminTheme = "keycloak";
- }
+ Theme theme = getTheme();
Map<String, Object> map = new HashMap<>();
@@ -277,11 +274,8 @@ public class AdminConsole {
authUrl = authUrl.substring(0, authUrl.length() - 1);
map.put("authUrl", authUrl);
- map.put("resourceUrl", Urls.themeRoot(baseUri) + "/admin/" + adminTheme);
+ map.put("resourceUrl", Urls.themeRoot(baseUri) + "/admin/" + theme.getName());
map.put("resourceVersion", Version.RESOURCES_VERSION);
-
- Theme theme = getTheme();
-
map.put("properties", theme.getProperties());
FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 88569b6..2d49464 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -74,24 +74,51 @@ public class KeycloakApplication extends Application {
classes.add(QRCodeResource.class);
classes.add(ThemeResource.class);
classes.add(JsResource.class);
- classes.add(WelcomeResource.class);
singletons.add(new ObjectMapperResolver(Boolean.parseBoolean(System.getProperty("keycloak.jsonPrettyPrint", "false"))));
- boolean defaultRealmCreated = ApplianceBootstrap.setupDefaultRealm(sessionFactory, context.getContextPath());
-
migrateModel();
sessionFactory.publish(new PostMigrationEvent());
- new ExportImportManager().checkExportImport(this.sessionFactory, context.getContextPath());
- importRealms(context);
+ boolean bootstrapAdminUser = false;
+
+ KeycloakSession session = sessionFactory.create();
+ try {
+ session.getTransaction().begin();
+
+ ApplianceBootstrap applianceBootstrap = new ApplianceBootstrap(session);
+ ExportImportManager exportImportManager = new ExportImportManager(session);
+
+ boolean createMasterRealm = applianceBootstrap.isNewInstall();
+ if (exportImportManager.isRunImport() && exportImportManager.isImportMasterIncluded()) {
+ createMasterRealm = false;
+ }
+
+ if (createMasterRealm) {
+ applianceBootstrap.createMasterRealm(contextPath);
+ }
+
+ if (exportImportManager.isRunImport()) {
+ exportImportManager.runImport();
+ } else {
+ importRealms();
+ }
+
+ importAddUser();
- importAddUser();
+ if (exportImportManager.isRunExport()) {
+ exportImportManager.runExport();
+ }
+
+ bootstrapAdminUser = applianceBootstrap.isNoMasterUser();
- if (defaultRealmCreated) {
- ApplianceBootstrap.setupDefaultUser(sessionFactory);
+ session.getTransaction().commit();
+ } finally {
+ session.close();
}
+ singletons.add(new WelcomeResource(bootstrapAdminUser));
+
setupScheduledTasks(sessionFactory);
}
@@ -185,34 +212,13 @@ public class KeycloakApplication extends Application {
return singletons;
}
- public void importRealms(ServletContext context) {
- importRealmFile();
- importRealmResources(context);
- }
-
- public void importRealmResources(ServletContext context) {
- String resources = context.getInitParameter("keycloak.import.realm.resources");
- if (resources != null) {
- StringTokenizer tokenizer = new StringTokenizer(resources, ",");
- while (tokenizer.hasMoreTokens()) {
- String resource = tokenizer.nextToken().trim();
- InputStream is = context.getResourceAsStream(resource);
- if (is == null) {
- log.warn("Could not find realm resource to import: " + resource);
- }
- RealmRepresentation rep = loadJson(is, RealmRepresentation.class);
- importRealm(rep, "resource " + resource);
- }
- }
- }
-
- public void importRealmFile() {
+ public void importRealms() {
String files = System.getProperty("keycloak.import");
if (files != null) {
StringTokenizer tokenizer = new StringTokenizer(files, ",");
while (tokenizer.hasMoreTokens()) {
String file = tokenizer.nextToken().trim();
- RealmRepresentation rep = null;
+ RealmRepresentation rep;
try {
rep = loadJson(new FileInputStream(file), RealmRepresentation.class);
} catch (FileNotFoundException e) {
diff --git a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
index 7aa6b01..e778de3 100755
--- a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
@@ -2,22 +2,24 @@ package org.keycloak.services.resources;
import org.jboss.logging.Logger;
import org.keycloak.Config;
+import org.keycloak.freemarker.FreeMarkerUtil;
import org.keycloak.freemarker.Theme;
import org.keycloak.freemarker.ThemeProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.common.util.MimeTypeUtil;
+import org.keycloak.services.managers.ApplianceBootstrap;
+import org.keycloak.services.util.CacheControlUtil;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.CacheControl;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -27,12 +29,18 @@ public class WelcomeResource {
private static final Logger logger = Logger.getLogger(WelcomeResource.class);
+ private boolean bootstrap;
+
@Context
private UriInfo uriInfo;
@Context
protected KeycloakSession session;
+ public WelcomeResource(boolean bootstrap) {
+ this.bootstrap = bootstrap;
+ }
+
/**
* Welcome page of Keycloak
*
@@ -42,11 +50,56 @@ public class WelcomeResource {
@GET
@Produces("text/html")
public Response getWelcomePage() throws URISyntaxException {
+ checkBootstrap();
+
String requestUri = uriInfo.getRequestUri().toString();
if (!requestUri.endsWith("/")) {
return Response.seeOther(new URI(requestUri + "/")).build();
} else {
- return getResource("index.html");
+ return createWelcomePage(null, null);
+ }
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public Response createUser(final MultivaluedMap<String, String> formData) {
+ checkBootstrap();
+
+ if (!bootstrap) {
+ return createWelcomePage(null, null);
+ } else {
+ if (!isLocal()) {
+ logger.errorv("Rejected non-local attempt to create initial user from {0}", session.getContext().getConnection().getRemoteAddr());
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ String username = formData.getFirst("username");
+ String password = formData.getFirst("password");
+ String passwordConfirmation = formData.getFirst("passwordConfirmation");
+
+ if (username == null || username.length() == 0) {
+ return createWelcomePage(null, "Username is missing");
+ }
+
+ if (password == null || password.length() == 0) {
+ return createWelcomePage(null, "Password is missing");
+ }
+
+ if (!password.equals(passwordConfirmation)) {
+ return createWelcomePage(null, "Password and confirmation doesn't match");
+ }
+
+ ApplianceBootstrap applianceBootstrap = new ApplianceBootstrap(session);
+ if (applianceBootstrap.isNoMasterUser()) {
+ bootstrap = false;
+ applianceBootstrap.createMasterRealmUser(session, username, password);
+
+ logger.infov("Created initial admin user with username {0}", username);
+ return createWelcomePage("User created", null);
+ } else {
+ logger.warnv("Rejected attempt to create initial user as user is already created");
+ return createWelcomePage(null, "Users already exists");
+ }
}
}
@@ -61,26 +114,62 @@ public class WelcomeResource {
@Produces("text/html")
public Response getResource(@PathParam("path") String path) {
try {
- Config.Scope config = Config.scope("theme");
-
- ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
- Theme theme = themeProvider.getTheme(config.get("welcomeTheme"), Theme.Type.WELCOME);
- InputStream resource = theme.getResourceAsStream(path);
+ InputStream resource = getTheme().getResourceAsStream(path);
if (resource != null) {
String contentType = MimeTypeUtil.getContentType(path);
-
- CacheControl cacheControl = new CacheControl();
- cacheControl.setNoTransform(false);
- cacheControl.setMaxAge(config.getInt("staticMaxAge", -1));
-
- Response.ResponseBuilder builder = Response.ok(resource).type(contentType).cacheControl(cacheControl);
+ Response.ResponseBuilder builder = Response.ok(resource).type(contentType).cacheControl(CacheControlUtil.getDefaultCacheControl());
return builder.build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
+ } catch (IOException e) {
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ private Response createWelcomePage(String successMessage, String errorMessage) {
+ try {
+ Map<String, Object> map = new HashMap<>();
+ map.put("bootstrap", bootstrap);
+ if (bootstrap) {
+ map.put("localUser", isLocal());
+ }
+ if (successMessage != null) {
+ map.put("successMessage", successMessage);
+ }
+ if (errorMessage != null) {
+ map.put("errorMessage", errorMessage);
+ }
+ FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
+ String result = freeMarkerUtil.processTemplate(map, "index.ftl", getTheme());
+ return Response.status(errorMessage == null ? Response.Status.OK : Response.Status.BAD_REQUEST).entity(result).cacheControl(CacheControlUtil.noCache()).build();
} catch (Exception e) {
- logger.warn("Failed to get theme resource", e);
- return Response.serverError().build();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ private Theme getTheme() {
+ Config.Scope config = Config.scope("theme");
+ ThemeProvider themeProvider = session.getProvider(ThemeProvider.class, "extending");
+ try {
+ return themeProvider.getTheme(config.get("welcomeTheme"), Theme.Type.WELCOME);
+ } catch (IOException e) {
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ private void checkBootstrap() {
+ if (bootstrap) {
+ bootstrap = new ApplianceBootstrap(session).isNoMasterUser();
+ }
+ }
+
+ private boolean isLocal() {
+ try {
+ InetAddress inetAddress = InetAddress.getByName(session.getContext().getConnection().getRemoteAddr());
+ return inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress();
+ } catch (UnknownHostException e) {
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
diff --git a/services/src/main/java/org/keycloak/services/util/CacheControlUtil.java b/services/src/main/java/org/keycloak/services/util/CacheControlUtil.java
index 259083a..0e2f1e0 100644
--- a/services/src/main/java/org/keycloak/services/util/CacheControlUtil.java
+++ b/services/src/main/java/org/keycloak/services/util/CacheControlUtil.java
@@ -19,7 +19,12 @@ public class CacheControlUtil {
cacheControl.setNoCache(true);
}
return cacheControl;
+ }
+ public static CacheControl noCache() {
+ CacheControl cacheControl = new CacheControl();
+ cacheControl.setNoCache(true);
+ return cacheControl;
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
index 28f0915..2466f36 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/KeycloakServer.java
@@ -33,10 +33,10 @@ import org.jboss.resteasy.spi.ResteasyDeployment;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.filters.ClientConnectionFilter;
import org.keycloak.services.filters.KeycloakSessionServletFilter;
+import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.util.JsonSerialization;
@@ -273,19 +273,17 @@ public class KeycloakServer {
}
protected void setupDevConfig() {
- KeycloakSession session = sessionFactory.create();
- session.getTransaction().begin();
-
- try {
- RealmManager manager = new RealmManager(session);
-
- RealmModel adminRealm = manager.getKeycloakAdminstrationRealm();
- UserModel admin = session.users().getUserByUsername("admin", adminRealm);
- admin.removeRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
-
- session.getTransaction().commit();
- } finally {
- session.close();
+ if (System.getProperty("keycloak.createAdminUser", "true").equals("true")) {
+ KeycloakSession session = sessionFactory.create();
+ try {
+ session.getTransaction().begin();
+ if (new ApplianceBootstrap(session).isNoMasterUser()) {
+ new ApplianceBootstrap(session).createMasterRealmUser(session, "admin", "admin");
+ }
+ session.getTransaction().commit();
+ } finally {
+ session.close();
+ }
}
}
@@ -311,7 +309,6 @@ public class KeycloakServer {
di.setDefaultEncoding("UTF-8");
di.setDefaultServletConfig(new DefaultServletConfig(true));
- di.addWelcomePage("theme/keycloak/welcome/resources/index.html");
FilterInfo filter = Servlets.filter("SessionFilter", KeycloakSessionServletFilter.class);
di.addFilter(filter);
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/WelcomePage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/WelcomePage.java
new file mode 100644
index 0000000..3adbbac
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/WelcomePage.java
@@ -0,0 +1,44 @@
+package org.keycloak.testsuite.auth.page;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class WelcomePage extends AuthServer {
+
+ @FindBy(id = "username")
+ private WebElement usernameInput;
+
+ @FindBy(id = "password")
+ private WebElement passwordInput;
+
+ @FindBy(id = "passwordConfirmation")
+ private WebElement passwordConfirmationInput;
+
+ @FindBy(id = "create-button")
+ private WebElement createButton;
+
+ public boolean isPasswordSet() {
+ return !driver.getPageSource().contains("Please create an initial admin user to get started.");
+ }
+
+ public void setPassword(String username, String password) {
+ usernameInput.clear();
+ usernameInput.sendKeys(username);
+
+ passwordInput.clear();
+ passwordInput.sendKeys(password);
+
+ passwordConfirmationInput.clear();
+ passwordConfirmationInput.sendKeys(password);
+
+ createButton.click();
+
+ if (!driver.getPageSource().contains("User created")) {
+ throw new RuntimeException("Failed to updated password");
+ }
+ }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
index 063347a..13ec96e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
@@ -20,6 +20,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import static org.keycloak.testsuite.admin.Users.setPasswordFor;
import org.keycloak.testsuite.arquillian.SuiteContext;
+import org.keycloak.testsuite.auth.page.WelcomePage;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.WebDriver;
import org.keycloak.testsuite.auth.page.AuthServer;
@@ -76,6 +77,9 @@ public abstract class AbstractKeycloakTest {
@Page
protected UpdatePassword updatePasswordPage;
+ @Page
+ protected WelcomePage welcomePage;
+
protected UserRepresentation adminUser;
@Before
@@ -103,11 +107,10 @@ public abstract class AbstractKeycloakTest {
}
private void updateMasterAdminPassword() {
- accountPage.navigateTo();
- loginPage.form().login(ADMIN, ADMIN);
- updatePasswordPage.updatePasswords(ADMIN, ADMIN);
- assertCurrentUrlStartsWith(accountPage);
- deleteAllCookiesForMasterRealm();
+ welcomePage.navigateTo();
+ if (!welcomePage.isPasswordSet()) {
+ welcomePage.setPassword("admin", "admin");
+ }
}
public void deleteAllCookiesForMasterRealm() {