keycloak-aplcache

Merge pull request #1929 from stianst/1.7.x-add-usr KEYCLOAK-2176

12/3/2015 10:30:37 AM

Details

diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index dfa2e46..87c13a3 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -1044,35 +1044,14 @@ public class RepresentationToModel {
                 user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction));
             }
         }
-        if (userRep.getCredentials() != null) {
-            for (CredentialRepresentation cred : userRep.getCredentials()) {
-                updateCredential(user, cred);
-            }
-        }
+        createCredentials(userRep, user);
         if (userRep.getFederatedIdentities() != null) {
             for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
                 FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
                 session.users().addFederatedIdentity(newRealm, user, mappingModel);
             }
         }
-        if (userRep.getRealmRoles() != null) {
-            for (String roleString : userRep.getRealmRoles()) {
-                RoleModel role = newRealm.getRole(roleString.trim());
-                if (role == null) {
-                    role = newRealm.addRole(roleString.trim());
-                }
-                user.grantRole(role);
-            }
-        }
-        if (userRep.getClientRoles() != null) {
-            for (Map.Entry<String, List<String>> entry : userRep.getClientRoles().entrySet()) {
-                ClientModel client = clientMap.get(entry.getKey());
-                if (client == null) {
-                    throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey());
-                }
-                createClientRoleMappings(client, user, entry.getValue());
-            }
-        }
+        createRoleMappings(userRep, user, newRealm);
         if (userRep.getClientConsents() != null) {
             for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
                 UserConsentModel consentModel = toModel(newRealm, consentRep);
@@ -1100,6 +1079,14 @@ public class RepresentationToModel {
         return user;
     }
 
+    public static void createCredentials(UserRepresentation userRep, UserModel user) {
+        if (userRep.getCredentials() != null) {
+            for (CredentialRepresentation cred : userRep.getCredentials()) {
+                updateCredential(user, cred);
+            }
+        }
+    }
+
     // Detect if it is "plain-text" or "hashed" representation and update model according to it
     private static void updateCredential(UserModel user, CredentialRepresentation cred) {
         if (cred.getValue() != null) {
@@ -1142,6 +1129,28 @@ public class RepresentationToModel {
 
     // Role mappings
 
+    public static void createRoleMappings(UserRepresentation userRep, UserModel user, RealmModel realm) {
+        if (userRep.getRealmRoles() != null) {
+            for (String roleString : userRep.getRealmRoles()) {
+                RoleModel role = realm.getRole(roleString.trim());
+                if (role == null) {
+                    role = realm.addRole(roleString.trim());
+                }
+                user.grantRole(role);
+            }
+        }
+        if (userRep.getClientRoles() != null) {
+            Map<String, ClientModel> clientMap = realm.getClientNameMap();
+            for (Map.Entry<String, List<String>> entry : userRep.getClientRoles().entrySet()) {
+                ClientModel client = clientMap.get(entry.getKey());
+                if (client == null) {
+                    throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey());
+                }
+                createClientRoleMappings(client, user, entry.getValue());
+            }
+        }
+    }
+
     public static void createClientRoleMappings(ClientModel clientModel, UserModel user, List<String> roleNames) {
         if (user == null) {
             throw new RuntimeException("User not found");
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 c26e60c..88569b6 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -9,10 +9,7 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
 import org.keycloak.Config;
 import org.keycloak.exportimport.ExportImportManager;
 import org.keycloak.migration.MigrationModelManager;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
+import org.keycloak.models.*;
 import org.keycloak.models.utils.PostMigrationEvent;
 import org.keycloak.models.utils.RepresentationToModel;
 import org.keycloak.representations.idm.RealmRepresentation;
@@ -263,32 +260,46 @@ public class KeycloakApplication extends Application {
             if (addUserFile.isFile()) {
                 log.info("Importing users from '" + addUserFile + "'");
 
-                KeycloakSession session = sessionFactory.create();
+                List<RealmRepresentation> realms;
                 try {
-                    session.getTransaction().begin();
-
-                    List<RealmRepresentation> realms = JsonSerialization.readValue(new FileInputStream(addUserFile), new TypeReference<List<RealmRepresentation>>() {});
-                    for (RealmRepresentation r : realms) {
-                        RealmModel realm = session.realms().getRealmByName(r.getRealm());
-                        if (realm == null) {
-                            throw new Exception("Realm '" + r.getRealm() + "' not found");
-                        }
+                    realms = JsonSerialization.readValue(new FileInputStream(addUserFile), new TypeReference<List<RealmRepresentation>>() {
+                    });
+                } catch (IOException e) {
+                    log.errorv("Failed to load 'keycloak-add-user.json': {0}", e.getMessage());
+                    return;
+                }
 
-                        for (UserRepresentation u : r.getUsers()) {
-                            RepresentationToModel.createUser(session, realm, u, realm.getClientNameMap());
+                for (RealmRepresentation realmRep : realms) {
+                    for (UserRepresentation userRep : realmRep.getUsers()) {
+                        KeycloakSession session = sessionFactory.create();
+                        try {
+                            session.getTransaction().begin();
+
+                            RealmModel realm = session.realms().getRealmByName(realmRep.getRealm());
+                            if (realm == null) {
+                                log.errorv("Failed to add user ''{0}'' to realm ''{1}'': realm not found", userRep.getUsername(), realmRep.getRealm());
+                            } else {
+                                UserModel user = session.users().addUser(realm, userRep.getUsername());
+                                user.setEnabled(userRep.isEnabled());
+                                RepresentationToModel.createCredentials(userRep, user);
+                                RepresentationToModel.createRoleMappings(userRep, user, realm);
+                            }
+
+                            session.getTransaction().commit();
+                            log.infov("Added user ''{0}'' to realm ''{1}''", userRep.getUsername(), realmRep.getRealm());
+                        } catch (ModelDuplicateException e) {
+                            log.errorv("Failed to add user ''{0}'' to realm ''{1}'': user with username exists", userRep.getUsername(), realmRep.getRealm());
+                        } catch (Throwable t) {
+                            session.getTransaction().rollback();
+                            log.errorv("Failed to add user ''{0}'' to realm ''{1}'': {2}", userRep.getUsername(), realmRep.getRealm(), t.getMessage());
+                        } finally {
+                            session.close();
                         }
                     }
+                }
 
-                    session.getTransaction().commit();
-
-                    if (!addUserFile.delete()) {
-                        log.error("Failed to delete '" + addUserFile + "'");
-                    }
-                } catch (Throwable t) {
-                    session.getTransaction().rollback();
-                    log.error("Failed to import users from '" + addUserFile + "'", t);
-                } finally {
-                    session.close();
+                if (!addUserFile.delete()) {
+                    log.errorv("Failed to delete '{0}'", addUserFile.getAbsolutePath());
                 }
             }
         }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java
index 17fa174..dea6ebc 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adduser/AddUserTest.java
@@ -1,15 +1,28 @@
 package org.keycloak.testsuite.adduser;
 
+import org.codehaus.jackson.type.TypeReference;
 import org.junit.*;
 import org.junit.rules.TemporaryFolder;
 import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.admin.client.resource.RoleMappingResource;
+import org.keycloak.admin.client.resource.RoleScopeResource;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.common.util.Base64Url;
 import org.keycloak.models.Constants;
-import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
+import org.keycloak.representations.idm.*;
 import org.keycloak.testsuite.KeycloakServer;
+import org.keycloak.util.JsonSerialization;
 import org.keycloak.wildfly.adduser.AddUser;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -37,7 +50,16 @@ public class AddUserTest {
     @Test
     public void addUserTest() throws Throwable {
         AddUser.main(new String[]{"-u", "addusertest-admin", "-p", "password"});
-        Assert.assertEquals(1, dir.listFiles().length);
+        assertEquals(1, dir.listFiles().length);
+
+        List<RealmRepresentation> realms = JsonSerialization.readValue(new FileInputStream(new File(dir, "keycloak-add-user.json")), new TypeReference<List<RealmRepresentation>>() {});
+        assertEquals(1, realms.size());
+        assertEquals(1, realms.get(0).getUsers().size());
+
+        UserRepresentation user = realms.get(0).getUsers().get(0);
+        assertEquals(new Integer(100000), user.getCredentials().get(0).getHashIterations());
+        assertNull(user.getCredentials().get(0).getValue());
+        assertEquals(new Pbkdf2PasswordEncoder(Base64Url.decode(user.getCredentials().get(0).getSalt()), 100000).encode("password"), user.getCredentials().get(0).getHashedSaltedValue());
 
         KeycloakServer server = new KeycloakServer();
         try {
@@ -53,12 +75,54 @@ public class AddUserTest {
 
             keycloak.realms().create(testRealm);
 
+            RealmResource realm = keycloak.realm("master");
+
+            List<UserRepresentation> users = realm.users().search("addusertest-admin", null, null, null, null, null);
+            assertEquals(1, users.size());
+
+            UserRepresentation created = users.get(0);
+            assertNotNull(created.getCreatedTimestamp());
+
+            UserResource userResource = realm.users().get(created.getId());
+
+            List<RoleRepresentation> realmRoles = userResource.roles().realmLevel().listAll();
+
+            assertRoles(realmRoles, "admin", "offline_access");
+
+            List<ClientRepresentation> clients = realm.clients().findAll();
+            String accountId = null;
+            for (ClientRepresentation c : clients) {
+                if (c.getClientId().equals("account")) {
+                    accountId = c.getId();
+                }
+            }
+
+            List<RoleRepresentation> accountRoles = userResource.roles().clientLevel(accountId).listAll();
+
+            assertRoles(accountRoles, "view-profile", "manage-account");
+
             keycloak.close();
 
-            Assert.assertEquals(0, dir.listFiles().length);
+            assertEquals(0, dir.listFiles().length);
         } finally {
             server.stop();
         }
     }
 
+    public static void assertRoles(List<RoleRepresentation> actual, String... expected) {
+        assertEquals(expected.length, actual.size());
+
+        for (String e : expected) {
+            boolean found = false;
+            for (RoleRepresentation r : actual) {
+                if (r.getName().equals(e)) {
+                    found = true;
+                }
+            }
+            if (!found) {
+                fail("Role " + e + " not found");
+            }
+        }
+    }
+
 }
diff --git a/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java b/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
index ff4cf35..7be53c6 100644
--- a/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
+++ b/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
@@ -154,9 +154,9 @@ public class AddUser {
             roles = rolesString.split(",");
         } else {
             if (realmName.equals("master")) {
-                roles = new String[] { "admin", "account/manage-account" };
+                roles = new String[] { "admin" };
             } else {
-                roles = new String[] { "realm-management/realm-admin", "account/manage-account" };
+                roles = new String[] { "realm-management/realm-admin" };
             }
         }