keycloak-memoizeit

Changes

Details

diff --git a/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java b/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java
old mode 100644
new mode 100755
index 5a41cf7..1a793ee
--- a/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java
+++ b/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java
@@ -12,25 +12,29 @@ import java.util.Properties;
  */
 public class ClassLoaderTheme implements Theme {
 
-    private final String name;
+    private String name;
 
-    private final String parentName;
+    private String parentName;
 
-    private final String importName;
+    private String importName;
 
-    private final Type type;
+    private Type type;
 
-    private final ClassLoader classLoader;
+    private ClassLoader classLoader;
 
-    private final String templateRoot;
+    private String templateRoot;
 
-    private final String resourceRoot;
+    private String resourceRoot;
 
-    private final String messages;
+    private String messages;
 
-    private final Properties properties;
+    private Properties properties;
 
     public ClassLoaderTheme(String name, Type type, ClassLoader classLoader) throws IOException {
+        init(name, type, classLoader);
+    }
+
+    public void init(String name, Type type, ClassLoader classLoader) throws IOException {
         this.name = name;
         this.type = type;
         this.classLoader = classLoader;
@@ -53,6 +57,10 @@ public class ClassLoaderTheme implements Theme {
         }
     }
 
+    public ClassLoaderTheme() {
+
+    }
+
     @Override
     public String getName() {
         return name;
diff --git a/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/styles.css b/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/styles.css
old mode 100644
new mode 100755
index d5ca9aa..e71ad3d
--- a/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/styles.css
+++ b/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/styles.css
@@ -31,4 +31,5 @@
     border-bottom: none;
     border-right-color: rgba(255,255,255,0.15);
     border-top-color: rgba(255,255,255,0.05);
-}
\ No newline at end of file
+}
+
diff --git a/project-integrations/aerogear-ups/app/pom.xml b/project-integrations/aerogear-ups/app/pom.xml
index 3123963..9508f27 100755
--- a/project-integrations/aerogear-ups/app/pom.xml
+++ b/project-integrations/aerogear-ups/app/pom.xml
@@ -85,7 +85,7 @@
     </dependencies>
 
     <build>
-        <finalName>app</finalName>
+        <finalName>aerogear-ups</finalName>
         <plugins>
             <plugin>
                 <groupId>org.jboss.as.plugins</groupId>
diff --git a/project-integrations/aerogear-ups/app/src/main/java/org/keycloak/example/BootstrapListener.java b/project-integrations/aerogear-ups/app/src/main/java/org/keycloak/example/BootstrapListener.java
index 23c632a..2487851 100755
--- a/project-integrations/aerogear-ups/app/src/main/java/org/keycloak/example/BootstrapListener.java
+++ b/project-integrations/aerogear-ups/app/src/main/java/org/keycloak/example/BootstrapListener.java
@@ -15,8 +15,8 @@ public class BootstrapListener implements ServletContextListener {
     public void contextInitialized(ServletContextEvent sce) {
         AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext)sce.getServletContext().getAttribute(AdapterDeploymentContext.class.getName());
         AdapterConfig config = new AdapterConfig();
-        config.setRealm("demo");
-        config.setResource("customer-portal");
+        config.setRealm("aerogear");
+        config.setResource("unified-push-server");
         config.setAuthServerUrl("/auth");
         config.setSslNotRequired(true);
         config.setPublicClient(true);
diff --git a/project-integrations/aerogear-ups/app/src/main/webapp/index.html b/project-integrations/aerogear-ups/app/src/main/webapp/index.html
index 681fa08..83a8042 100755
--- a/project-integrations/aerogear-ups/app/src/main/webapp/index.html
+++ b/project-integrations/aerogear-ups/app/src/main/webapp/index.html
@@ -5,9 +5,9 @@
     <title></title>
 </head>
 <body bgcolor="#E3F6CE">
-<h1>Customer Portal</h1>
+<h1>Aerogear UPS Portal</h1>
 
-<p><a href="customers/view.jsp">Customer Listing</a></p>
+<p><a href="ups/view.jsp">Play with Aerogear UPS</a></p>
 
 </body>
 </html>
\ No newline at end of file
diff --git a/project-integrations/aerogear-ups/app/src/main/webapp/WEB-INF/web.xml b/project-integrations/aerogear-ups/app/src/main/webapp/WEB-INF/web.xml
index 1be2b56..23e2831 100755
--- a/project-integrations/aerogear-ups/app/src/main/webapp/WEB-INF/web.xml
+++ b/project-integrations/aerogear-ups/app/src/main/webapp/WEB-INF/web.xml
@@ -4,7 +4,7 @@
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
       version="3.0">
 
-	<module-name>app</module-name>
+	<module-name>aerogear-ups</module-name>
 
     <listener>
         <listener-class>org.keycloak.example.BootstrapListener</listener-class>
@@ -13,12 +13,17 @@
 
     <security-constraint>
         <web-resource-collection>
-            <web-resource-name>Customers</web-resource-name>
-            <url-pattern>/customers/*</url-pattern>
+            <web-resource-name>UPS</web-resource-name>
+            <url-pattern>/ups/*</url-pattern>
         </web-resource-collection>
         <auth-constraint>
             <role-name>user</role-name>
         </auth-constraint>
+        <!--
+        <user-data-constraint>
+            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
+        </user-data-constraint>
+        -->
     </security-constraint>
 
     <security-constraint>
@@ -29,16 +34,6 @@
         <auth-constraint>
             <role-name>admin</role-name>
         </auth-constraint>
-    </security-constraint>
-
-    <security-constraint>
-        <web-resource-collection>
-            <web-resource-name>Database</web-resource-name>
-            <url-pattern>/rest/*</url-pattern>
-        </web-resource-collection>
-        <auth-constraint>
-            <role-name>user</role-name>
-        </auth-constraint>
         <!--
         <user-data-constraint>
             <transport-guarantee>CONFIDENTIAL</transport-guarantee>
@@ -46,7 +41,7 @@
         -->
     </security-constraint>
 
-    <login-config>
+        <login-config>
         <auth-method>BASIC</auth-method>
         <realm-name>demo</realm-name>
     </login-config>
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/AerogearThemeProvider.java b/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/AerogearThemeProvider.java
new file mode 100755
index 0000000..d8ef5e0
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/java/org/aerogear/ups/security/AerogearThemeProvider.java
@@ -0,0 +1,62 @@
+package org.aerogear.ups.security;
+
+import org.keycloak.freemarker.Theme;
+import org.keycloak.freemarker.ThemeProvider;
+import org.keycloak.theme.ClassLoaderTheme;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class AerogearThemeProvider implements ThemeProvider {
+
+    public static final String AEROGEAR = "aerogear";
+
+    private static Set<String> ACCOUNT_THEMES = new HashSet<String>();
+    private static Set<String> LOGIN_THEMES = new HashSet<String>();
+    private static Set<String> ADMIN_THEMES = new HashSet<String>();
+
+    static {
+        Collections.addAll(ACCOUNT_THEMES, AEROGEAR);
+        Collections.addAll(LOGIN_THEMES, AEROGEAR);
+        Collections.addAll(ADMIN_THEMES, AEROGEAR);
+    }
+
+    @Override
+    public int getProviderPriority() {
+        return 0;
+    }
+
+    @Override
+    public Theme createTheme(String name, Theme.Type type) throws IOException {
+        if (hasTheme(name, type)) {
+            return new ClassLoaderTheme(name, type, getClass().getClassLoader());
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Set<String> nameSet(Theme.Type type) {
+        switch (type) {
+            case LOGIN:
+                return LOGIN_THEMES;
+            case ACCOUNT:
+                return ACCOUNT_THEMES;
+            case ADMIN:
+                return ADMIN_THEMES;
+            default:
+                return Collections.emptySet();
+        }
+    }
+
+    @Override
+    public boolean hasTheme(String name, Theme.Type type) {
+        return nameSet(type).contains(name);
+    }
+
+}
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProvider b/project-integrations/aerogear-ups/auth-server/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProvider
new file mode 100755
index 0000000..89dd874
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/META-INF/services/org.keycloak.freemarker.ThemeProvider
@@ -0,0 +1 @@
+org.aerogear.ups.security.AerogearThemeProvider
\ No newline at end of file
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/resources/css/account.css b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/resources/css/account.css
new file mode 100755
index 0000000..28b20bb
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/resources/css/account.css
@@ -0,0 +1,8 @@
+.navbar-title {
+    background-image: url('../img/logo.png');
+    height: 65px;
+    background-repeat: no-repeat;
+    width: 203px;
+    margin: 3px 10px 5px;
+    text-indent: -99999px;
+}
\ No newline at end of file
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/resources/img/logo.png b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/resources/img/logo.png
new file mode 100755
index 0000000..d55812d
Binary files /dev/null and b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/resources/img/logo.png differ
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/theme.properties b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/theme.properties
new file mode 100755
index 0000000..04feb70
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/account/aerogear/theme.properties
@@ -0,0 +1,4 @@
+parent=keycloak
+import=common/keycloak
+
+styles= ../patternfly/lib/patternfly/css/patternfly.css ../patternfly/css/account.css ../keycloak/css/account.css css/account.css
\ No newline at end of file
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/resources/css/styles.css b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/resources/css/styles.css
new file mode 100755
index 0000000..84300fe
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/resources/css/styles.css
@@ -0,0 +1,45 @@
+@import url("../lib/patternfly/css/patternfly.css");
+@import url("../lib/select2-3.4.1/select2.css");
+
+@import url("admin-console.css");
+@import url("tables.css");
+@import url("sprites.css");
+
+.navbar-pf {
+    background-image: url('../img/header-bkgrnd.png');
+    border-top: 3px solid rgba(255, 255, 255, 0.15);
+}
+
+.navbar-pf .navbar-primary {
+    font-size: 13px;
+    background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,.4) 100%);
+    background-image: linear-gradient(to bottom, rgba(0,0,0,.1) 0%, rgba(0,0,0,.4) 100%);
+}
+
+.navbar-pf .navbar-header {
+    border-bottom: 1px solid rgba(255,255,255,.15);
+}
+
+.navbar-pf .navbar-primary li.dropdown.context > a,
+.navbar-pf .navbar-primary li.dropdown.context > a:hover,
+.navbar-pf .navbar-primary li.dropdown.context.open > a,
+.navbar-pf .navbar-primary > .active > a,
+.navbar-pf .navbar-primary > .active > a:hover{
+    background-color: rgba(0,0,0,0.1);
+    background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0.1) 100%);
+    background-image: linear-gradient(to bottom, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0.1) 100%);
+    border-bottom: none;
+    border-right-color: rgba(255,255,255,0.15);
+    border-top-color: rgba(255,255,255,0.05);
+}
+
+/* this is what I added */
+
+.navbar-title {
+    background-image: url('../img/logo.png');
+    height: 65px;
+    background-repeat: no-repeat;
+    width: 203px;
+    margin: 3px 10px 5px;
+    text-indent: -99999px;
+}
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/resources/img/logo.png b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/resources/img/logo.png
new file mode 100755
index 0000000..d55812d
Binary files /dev/null and b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/resources/img/logo.png differ
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/theme.properties b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/theme.properties
new file mode 100755
index 0000000..e328b3f
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/admin/aerogear/theme.properties
@@ -0,0 +1,4 @@
+parent=keycloak
+import=common/keycloak
+
+styles= ../keycloak/css/styles.css css/styles.css
\ No newline at end of file
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/resources/css/login.css b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/resources/css/login.css
new file mode 100755
index 0000000..3b9207c
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/resources/css/login.css
@@ -0,0 +1,9 @@
+#kc-logo-wrapper {
+    background-image: url("../img/logo.png");
+    background-repeat: no-repeat;
+    background-position: top right;
+
+    height: 65px;
+
+    margin: 100px;
+}
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/resources/img/logo.png b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/resources/img/logo.png
new file mode 100755
index 0000000..d55812d
Binary files /dev/null and b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/resources/img/logo.png differ
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/theme.properties b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/theme.properties
new file mode 100755
index 0000000..d1b98ed
--- /dev/null
+++ b/project-integrations/aerogear-ups/auth-server/src/main/resources/theme/login/aerogear/theme.properties
@@ -0,0 +1,4 @@
+parent=keycloak
+import=common/keycloak
+
+styles= ../patternfly/lib/patternfly/css/patternfly.css ../patternfly/css/login.css ../patternfly/lib/zocial/zocial.css ../keycloak/css/login.css css/login.css
\ No newline at end of file
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/testrealm.json b/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/testrealm.json
index bcbd7ad..7243991 100755
--- a/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/testrealm.json
+++ b/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/testrealm.json
@@ -1,5 +1,5 @@
 {
-    "realm": "demo",
+    "realm": "aerogear",
     "enabled": true,
     "accessTokenLifespan": 3000,
     "accessCodeLifespan": 10,
@@ -7,6 +7,9 @@
     "sslNotRequired": true,
     "registrationAllowed": false,
     "social": false,
+    "adminTheme": "aerogear",
+    "accountTheme": "aerogear",
+    "loginTheme": "aerogear",
     "updateProfileOnInitialSocialLogin": false,
     "requiredCredentials": [ "password" ],
     "users" : [
@@ -24,7 +27,7 @@
         {
             "username" : "admin",
             "enabled": true,
-            "firstName": "Bill",
+            "firstName": "Meister",
             "lastName": "Burke",
             "credentials" : [
                 { "type" : "password",
@@ -59,19 +62,19 @@
     ],
     "scopeMappings": [
         {
-            "client": "customer-portal",
-            "roles": ["user"]
+            "client": "unified-push-server",
+            "roles": ["user", "admin"]
         }
     ],
     "applications": [
         {
-            "name": "customer-portal",
+            "name": "unified-push-server",
             "enabled": true,
             "publicClient": true,
-            "adminUrl": "/app",
-            "baseUrl": "/app",
+            "adminUrl": "/aerogear-ups",
+            "baseUrl": "/aerogear-ups",
             "redirectUris": [
-                "/app/*"
+                "/aerogear-ups/*"
             ]
         }
     ],
@@ -80,9 +83,13 @@
             {
                 "username": "bburke@redhat.com",
                 "roles": ["manage-account"]
+            },
+            {
+                "username": "admin",
+                "roles": ["manage-account"]
             }
         ],
-        "demo-realm": [
+        "realm-management": [
             {
                 "username": "admin",
                 "roles": ["realm-admin"]
diff --git a/project-integrations/aerogear-ups/README.md b/project-integrations/aerogear-ups/README.md
index 7a16c26..2ae6436 100755
--- a/project-integrations/aerogear-ups/README.md
+++ b/project-integrations/aerogear-ups/README.md
@@ -2,14 +2,30 @@ Self Bootstrapping Keycloak Server and Application
 ==========================================================
 
 This is an example of bundling two wars: a keycloak server war and application WAR together so that keycloak is bootstrapped out of the
-box.
+box.  The structure of the example is:
+
+* The aerogear UPS application [http://localhost:8080/aerogear-ups/ups/view.jsp](http://localhost:8080/aerogear-ups/ups/view.jsp)
+* The aerogear UPS admin [http://localhost:8080/aerogear-ups/admin/admin.html](http://localhost:8080/aerogear-ups/admin/admin.html)
+* The aerogear security admin (keycloak)  [http://localhost:8080/auth/admin/aerogear/console/index.html](http://localhost:8080/auth/admin/aerogear/console/index.html)
+* The aerogear user account page (keycloak)  [http://localhost:8080/auth/realms/aerogear/account](http://localhost:8080/auth/realms/aerogear/account)
+* All of these are managed under one realm "aerogear"
+* The login page, admin console, and account pages all use the "aerogear" theme
+
+If you click on any of those URLS, you are brought to a log-in screen.  Username: admin Password: admin.  You will be asked
+to change your password.  Once you are logged in, you have SSO to any of those links.
+
+Notes on implementation:
 
 * There is a testrealm.json file that is used to bootstrap the realm in the auth-server/ project
 * Notice that there is a context-param in auth-server/web.xml called keycloak.import.realm.resources.  This sets up the import of the json file
 * If you open up testrealm.json, notice that all urls are relative.  Keycloak will now extrapolate the host and port based
 on the request if the configured urls are just a path and don't have a schem, host, and port.
+* In the auth project, there is a AerogearThemeProvider class.  This sets up classloader access to the "aerogear" themes
+* In the auth project, there is a UpsSecurityApplication class.  The sole purpose of this class is to disable the "master"
+  realm by deleting the master realm's "admin" user
+* In the auth project resources/, there are files there to set up all the themes
 * In app, there is a BootstrapListener class.  This obtains the config context of the adapter and initializes it.
-* Notice that this class sets up a relative URL.  Also notice that the application is a "public" client.  This is so that
+* Notice that BootstrapListener class sets up a relative URL.  Also notice that the application is a "public" client.  This is so that
 we don't have to query the database for the application's secret.  Also notice that the realm key is not set.  Keycloak adapter
 will now query the auth server url for the public key of the realm.
 
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index 2e229bb..8410776 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -121,10 +121,16 @@ public class RealmManager {
         realm.addScopeMapping(adminConsole, adminRole);
     }
 
-    public String getRealmAdminApplicationName(RealmModel realm) {
+    public String getMasterRealmAdminApplicationName(RealmModel realm) {
         return realm.getName() + "-realm";
     }
 
+    public String getRealmAdminApplicationName(RealmModel realm) {
+        return "realm-management";
+    }
+
+
+
     protected void setupRealmDefaults(RealmModel realm) {
         // brute force
         realm.setBruteForceProtected(false); // default settings off for now todo set it on
@@ -242,7 +248,7 @@ public class RealmManager {
 
         ApplicationManager applicationManager = new ApplicationManager(new RealmManager(identitySession));
 
-        ApplicationModel realmAdminApp = applicationManager.createApplication(adminRealm, getRealmAdminApplicationName(realm));
+        ApplicationModel realmAdminApp = applicationManager.createApplication(adminRealm, getMasterRealmAdminApplicationName(realm));
         realmAdminApp.setBearerOnly(true);
         realm.setMasterAdminApp(realmAdminApp);