keycloak-aplcache

composite representations

2/3/2014 8:21:56 PM

Details

diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 559ebc2..5cb4a1d 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -8,7 +8,6 @@ import java.util.List;
  * @version $Revision: 1 $
  */
 public class ApplicationRepresentation {
-    protected String self; // link
     protected String id;
     protected String name;
     protected String adminUrl;
@@ -16,19 +15,10 @@ public class ApplicationRepresentation {
     protected boolean surrogateAuthRequired;
     protected boolean enabled;
     protected List<CredentialRepresentation> credentials;
-    protected List<RoleRepresentation> roles;
     protected String[] defaultRoles;
     protected List<String> redirectUris;
     protected List<String> webOrigins;
 
-    public String getSelf() {
-        return self;
-    }
-
-    public void setSelf(String self) {
-        this.self = self;
-    }
-
     public String getId() {
         return id;
     }
@@ -61,27 +51,6 @@ public class ApplicationRepresentation {
         this.surrogateAuthRequired = surrogateAuthRequired;
     }
 
-    public List<RoleRepresentation> getRoles() {
-        return roles;
-    }
-
-    public void setRoles(List<RoleRepresentation> roles) {
-        this.roles = roles;
-    }
-
-    public ApplicationRepresentation role(RoleRepresentation role) {
-        if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>();
-        this.roles.add(role);
-        return this;
-    }
-
-
-    public ApplicationRepresentation role(String role, String description) {
-        if (this.roles == null) this.roles = new ArrayList<RoleRepresentation>();
-        this.roles.add(new RoleRepresentation(role, description));
-        return this;
-    }
-
     public String getAdminUrl() {
         return adminUrl;
     }
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index 5cb3799..b1fc9be 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -25,7 +25,7 @@ public class RealmRepresentation {
     protected Boolean updateProfileOnInitialSocialLogin;
     protected String privateKey;
     protected String publicKey;
-    protected List<RoleRepresentation> roles;
+    protected RolesRepresentation roles;
     protected List<String> defaultRoles;
     protected Set<String> requiredCredentials;
     protected Set<String> requiredApplicationCredentials;
@@ -206,14 +206,6 @@ public class RealmRepresentation {
         this.accessCodeLifespanUserAction = accessCodeLifespanUserAction;
     }
 
-    public List<RoleRepresentation> getRoles() {
-        return roles;
-    }
-
-    public void setRoles(List<RoleRepresentation> roles) {
-        this.roles = roles;
-    }
-
     public List<String> getDefaultRoles() {
         return defaultRoles;
     }
@@ -317,4 +309,12 @@ public class RealmRepresentation {
     public void setApplicationScopeMappings(Map<String, List<ScopeMappingRepresentation>> applicationScopeMappings) {
         this.applicationScopeMappings = applicationScopeMappings;
     }
+
+    public RolesRepresentation getRoles() {
+        return roles;
+    }
+
+    public void setRoles(RolesRepresentation roles) {
+        this.roles = roles;
+    }
 }
diff --git a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java
index 81d2428..14b4d5c 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RoleRepresentation.java
@@ -1,6 +1,7 @@
 package org.keycloak.representations.idm;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -12,7 +13,29 @@ public class RoleRepresentation {
     protected String name;
     protected String description;
     protected boolean composite;
-    protected List<RoleRepresentation> composites;
+    protected Composites composites;
+
+    public static class Composites {
+        protected Set<String> realm;
+        protected Map<String, List<String>> application;
+
+
+        public Set<String> getRealm() {
+            return realm;
+        }
+
+        public void setRealm(Set<String> realm) {
+            this.realm = realm;
+        }
+
+        public Map<String, List<String>> getApplication() {
+            return application;
+        }
+
+        public void setApplication(Map<String, List<String>> application) {
+            this.application = application;
+        }
+    }
 
     public RoleRepresentation() {
     }
@@ -54,11 +77,11 @@ public class RoleRepresentation {
         this.composite = composite;
     }
 
-    public List<RoleRepresentation> getComposites() {
+    public Composites getComposites() {
         return composites;
     }
 
-    public void setComposites(List<RoleRepresentation> composites) {
+    public void setComposites(Composites composites) {
         this.composites = composites;
     }
 }
diff --git a/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java
new file mode 100755
index 0000000..496f738
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/RolesRepresentation.java
@@ -0,0 +1,29 @@
+package org.keycloak.representations.idm;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class RolesRepresentation {
+    protected List<RoleRepresentation> realm;
+    protected Map<String, List<RoleRepresentation>> application;
+
+    public List<RoleRepresentation> getRealm() {
+        return realm;
+    }
+
+    public void setRealm(List<RoleRepresentation> realm) {
+        this.realm = realm;
+    }
+
+    public Map<String, List<RoleRepresentation>> getApplication() {
+        return application;
+    }
+
+    public void setApplication(Map<String, List<RoleRepresentation>> application) {
+        this.application = application;
+    }
+}
diff --git a/examples/demo-template/testrealm.json b/examples/demo-template/testrealm.json
index 7f39c9a..86cf0f6 100755
--- a/examples/demo-template/testrealm.json
+++ b/examples/demo-template/testrealm.json
@@ -26,16 +26,18 @@
             ]
         }
     ],
-    "roles": [
-        {
-            "name": "user",
-            "description": "User privileges"
-        },
-        {
-            "name": "admin",
-            "description": "Administrator privileges"
-        }
-    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "user",
+                "description": "User privileges"
+            },
+            {
+                "name": "admin",
+                "description": "Administrator privileges"
+            }
+        ]
+    },
     "roleMappings": [
         {
             "username": "bburke@redhat.com",
diff --git a/forms/src/main/java/org/keycloak/forms/UrlBean.java b/forms/src/main/java/org/keycloak/forms/UrlBean.java
index 4637cc2..36ab144 100755
--- a/forms/src/main/java/org/keycloak/forms/UrlBean.java
+++ b/forms/src/main/java/org/keycloak/forms/UrlBean.java
@@ -87,12 +87,7 @@ public class UrlBean {
     }
 
     public String getRegistrationUrl() {
-        if (realm.isSaas()) {
-            // TODO: saas social registration
-            return Urls.saasRegisterPage(baseURI).toString();
-        } else {
-            return Urls.realmRegisterPage(baseURI, getRealmIdentifier()).toString();
-        }
+        return Urls.realmRegisterPage(baseURI, getRealmIdentifier()).toString();
     }
 
     public String getLoginUpdatePasswordUrl() {
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index 721636c..9ca5193 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -77,13 +77,6 @@ public class ApplicationManager {
         realm.grantRole(resourceUser, loginRole);
 
 
-        if (resourceRep.getRoles() != null) {
-            for (RoleRepresentation roleRep : resourceRep.getRoles()) {
-                RoleModel role = applicationModel.addRole(roleRep.getName());
-                if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
-            }
-        }
-
         if (resourceRep.getDefaultRoles() != null) {
             applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
         }
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 c7fb26b..8c55586 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -234,24 +234,87 @@ public class RealmManager {
             }
         }
 
-        if (rep.getRoles() != null) {
-            for (RoleRepresentation roleRep : rep.getRoles()) {
+        if (rep.getApplications() != null) {
+            Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
+            for (ApplicationModel app : appMap.values()) {
+                userMap.put(app.getApplicationUser().getLoginName(), app.getApplicationUser());
+            }
+        }
+
+        if (rep.getRoles() != null && rep.getRoles().getRealm() != null) {
+            for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
                 createRole(newRealm, roleRep);
             }
         }
 
+        if (rep.getRoles() != null) {
+            if (rep.getRoles().getRealm() != null) { // realm roles
+                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+                    createRole(newRealm, roleRep);
+                }
+            }
+            if (rep.getRoles().getApplication() != null) {
+                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    if (app == null) {
+                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+                    }
+                    for (RoleRepresentation roleRep : entry.getValue()) {
+                        RoleModel role = app.addRole(roleRep.getName());
+                        role.setDescription(roleRep.getDescription());
+                        role.setComposite(roleRep.isComposite());
+                    }
+                }
+            }
+            // now that all roles are created, re-interate and set up composites
+            if (rep.getRoles().getRealm() != null) { // realm roles
+                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+                    createRole(newRealm, roleRep);
+                }
+            }
+            if (rep.getRoles().getApplication() != null) {
+                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    if (app == null) {
+                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+                    }
+                    for (RoleRepresentation roleRep : entry.getValue()) {
+                        RoleModel role = app.addRole(roleRep.getName());
+                        role.setDescription(roleRep.getDescription());
+                        role.setComposite(roleRep.isComposite());
+                    }
+                }
+            }
+        }
+
+
         if (rep.getDefaultRoles() != null) {
             for (String roleString : rep.getDefaultRoles()) {
                 newRealm.addDefaultRole(roleString.trim());
             }
         }
 
-        if (rep.getApplications() != null) {
-            Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
-            for (ApplicationModel app : appMap.values()) {
-                userMap.put(app.getApplicationUser().getLoginName(), app.getApplicationUser());
+        if (rep.getRoles() != null) {
+            if (rep.getRoles().getRealm() != null) { // realm roles
+                for (RoleRepresentation roleRep : rep.getRoles().getRealm()) {
+                    RoleModel role = newRealm.getRole(roleRep.getName());
+                    addComposites(role, roleRep, newRealm);
+                }
+            }
+            if (rep.getRoles().getApplication() != null) {
+                for (Map.Entry<String, List<RoleRepresentation>> entry : rep.getRoles().getApplication().entrySet()) {
+                    ApplicationModel app = newRealm.getApplicationByName(entry.getKey());
+                    if (app == null) {
+                        throw new RuntimeException("App doesn't exist in role definitions: " + entry.getKey());
+                    }
+                    for (RoleRepresentation roleRep : entry.getValue()) {
+                        RoleModel role = app.getRole(roleRep.getName());
+                        addComposites(role, roleRep, newRealm);
+                    }
+                }
             }
         }
+
         if (rep.getOauthClients() != null) {
             Map<String, OAuthClientModel> oauthMap = createOAuthClients(rep, newRealm);
             for (OAuthClientModel app : oauthMap.values()) {
@@ -334,11 +397,44 @@ public class RealmManager {
         }
     }
 
+    public void addComposites(RoleModel role, RoleRepresentation roleRep, RealmModel realm) {
+        if (!roleRep.isComposite() || roleRep.getComposites() == null) return;
+        if (roleRep.getComposites().getRealm() != null) {
+            for (String roleStr : roleRep.getComposites().getRealm()) {
+                RoleModel realmRole = realm.getRole(roleStr);
+                if (realmRole == null) throw new RuntimeException("Unable to find composite realm role: " + roleStr);
+                role.addCompositeRole(realmRole);
+            }
+        }
+        if (roleRep.getComposites().getApplication() != null) {
+            for (Map.Entry<String, List<String>> entry : roleRep.getComposites().getApplication().entrySet()) {
+                ApplicationModel app = realm.getApplicationByName(entry.getKey());
+                if (app == null) {
+                    throw new RuntimeException("App doesn't exist in role definitions: " + roleRep.getName());
+                }
+                for (String roleStr : entry.getValue()) {
+                    RoleModel appRole = app.getRole(roleStr);
+                    if (appRole == null) throw new RuntimeException("Unable to find composite app role: " + roleStr);
+                    role.addCompositeRole(appRole);
+                }
+
+            }
+
+        }
+
+    }
+
     public void createRole(RealmModel newRealm, RoleRepresentation roleRep) {
         RoleModel role = newRealm.addRole(roleRep.getName());
         if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
     }
 
+    public void createRole(RealmModel newRealm, ApplicationModel app, RoleRepresentation roleRep) {
+        RoleModel role = app.addRole(roleRep.getName());
+        if (roleRep.getDescription() != null) role.setDescription(roleRep.getDescription());
+    }
+
+
     public UserModel createUser(RealmModel newRealm, UserRepresentation userRep) {
         UserModel user = newRealm.addUser(userRep.getUsername());
         user.setEnabled(userRep.isEnabled());
diff --git a/services/src/test/resources/testrealm.json b/services/src/test/resources/testrealm.json
index 4c20b70..76f90a9 100755
--- a/services/src/test/resources/testrealm.json
+++ b/services/src/test/resources/testrealm.json
@@ -58,12 +58,6 @@
             "enabled": true
         }
     ],
-    "roleMappings": [
-        {
-            "username": "admin",
-            "roles": ["admin"]
-        }
-    ],
     "socialMappings": [
         {
             "username": "mySocialUser",
@@ -86,20 +80,30 @@
     "applications": [
         {
             "name": "Application",
-            "enabled": true,
-            "roles": [
+            "enabled": true
+        },
+        {
+            "name": "OtherApp",
+            "enabled": true
+        }
+
+    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "admin"
+            }
+        ],
+        "application" : {
+            "Application" : [
                 {
                     "name": "admin"
                 },
                 {
                     "name": "user"
                 }
-            ]
-        },
-        {
-            "name": "OtherApp",
-            "enabled": true,
-            "roles": [
+            ],
+            "OtherApp" : [
                 {
                     "name": "admin"
                 },
@@ -108,7 +112,12 @@
                 }
             ]
         }
-
+    },
+    "roleMappings": [
+        {
+            "username": "admin",
+            "roles": ["admin"]
+        }
     ],
     "applicationRoleMappings": {
         "Application": [
diff --git a/services/src/test/resources/testrealm-demo.json b/services/src/test/resources/testrealm-demo.json
index 753dfb0..be00dce 100755
--- a/services/src/test/resources/testrealm-demo.json
+++ b/services/src/test/resources/testrealm-demo.json
@@ -34,16 +34,19 @@
             ]
         }
     ],
-    "roles": [
-        {
-            "name": "user",
-            "description": "Have User privileges"
-        },
-        {
-            "name": "admin",
-            "description": "Have Administrator privileges"
-        }
-    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "user",
+                "description": "Have User privileges"
+            },
+            {
+                "name": "admin",
+                "description": "Have Administrator privileges"
+            }
+        ]
+    },
+
     "roleMappings": [
         {
             "username": "bburke@redhat.com",
diff --git a/testsuite/integration/src/test/resources/testrealm.json b/testsuite/integration/src/test/resources/testrealm.json
index 755d9ea..855959e 100755
--- a/testsuite/integration/src/test/resources/testrealm.json
+++ b/testsuite/integration/src/test/resources/testrealm.json
@@ -40,16 +40,6 @@
             ]
         }
     ],
-    "roles": [
-        {
-            "name": "user",
-            "description": "Have User privileges"
-        },
-        {
-            "name": "admin",
-            "description": "Have Administrator privileges"
-        }
-    ],
     "roleMappings": [
         {
             "username": "test-user@localhost",
@@ -77,8 +67,22 @@
                     "type": "password",
                     "value": "password"
                 }
-            ],
-            "roles": [
+            ]
+         }
+    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "user",
+                "description": "Have User privileges"
+            },
+            {
+                "name": "admin",
+                "description": "Have Administrator privileges"
+            }
+        ],
+        "application" : {
+            "test-app" : [
                 {
                     "name": "customer-user",
                     "description": "Have Customer User privileges"
@@ -88,8 +92,10 @@
                     "description": "Have Customer Admin privileges"
                 }
             ]
-         }
-    ],
+        }
+
+    },
+
     "applicationRoleMappings": {
         "test-app": [
             {