/* * Copyright 2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.keycloak.testsuite.model; import com.google.common.collect.ImmutableMap; import org.junit.Assert; import org.junit.Test; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserModel.RequiredAction; import org.keycloak.services.managers.ClientManager; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.Assert.assertNotNull; /** * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> */ public class UserModelTest extends AbstractModelTest { @Test public void persistUser() { RealmModel realm = realmManager.createRealm("original"); KeycloakSession session = realmManager.getSession(); UserModel user = session.users().addUser(realm, "user"); user.setFirstName("first-name"); user.setLastName("last-name"); user.setEmail("email"); assertNotNull(user.getCreatedTimestamp()); // test that timestamp is current with 10s tollerance Assert.assertTrue((System.currentTimeMillis() - user.getCreatedTimestamp()) < 10000); user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); user.addRequiredAction(RequiredAction.UPDATE_PASSWORD); RealmModel searchRealm = realmManager.getRealm(realm.getId()); UserModel persisted = session.users().getUserByUsername("user", searchRealm); assertEquals(user, persisted); searchRealm = realmManager.getRealm(realm.getId()); UserModel persisted2 = session.users().getUserById(user.getId(), searchRealm); assertEquals(user, persisted2); Map<String, String> attributes = new HashMap<String, String>(); attributes.put(UserModel.LAST_NAME, "last-name"); List<UserModel> search = session.users().searchForUser(attributes, realm); Assert.assertEquals(search.size(), 1); Assert.assertEquals(search.get(0).getUsername(), "user"); attributes.clear(); attributes.put(UserModel.EMAIL, "email"); search = session.users().searchForUser(attributes, realm); Assert.assertEquals(search.size(), 1); Assert.assertEquals(search.get(0).getUsername(), "user"); attributes.clear(); attributes.put(UserModel.LAST_NAME, "last-name"); attributes.put(UserModel.EMAIL, "email"); search = session.users().searchForUser(attributes, realm); Assert.assertEquals(search.size(), 1); Assert.assertEquals(search.get(0).getUsername(), "user"); } @Test public void webOriginSetTest() { RealmModel realm = realmManager.createRealm("original"); ClientModel client = realm.addClient("user"); Assert.assertTrue(client.getWebOrigins().isEmpty()); client.addWebOrigin("origin-1"); Assert.assertEquals(1, client.getWebOrigins().size()); client.addWebOrigin("origin-2"); Assert.assertEquals(2, client.getWebOrigins().size()); client.removeWebOrigin("origin-2"); Assert.assertEquals(1, client.getWebOrigins().size()); client.removeWebOrigin("origin-1"); Assert.assertTrue(client.getWebOrigins().isEmpty()); client = realm.addClient("oauthclient2"); Assert.assertTrue(client.getWebOrigins().isEmpty()); client.addWebOrigin("origin-1"); Assert.assertEquals(1, client.getWebOrigins().size()); client.addWebOrigin("origin-2"); Assert.assertEquals(2, client.getWebOrigins().size()); client.removeWebOrigin("origin-2"); Assert.assertEquals(1, client.getWebOrigins().size()); client.removeWebOrigin("origin-1"); Assert.assertTrue(client.getWebOrigins().isEmpty()); } @Test public void testUserRequiredActions() throws Exception { RealmModel realm = realmManager.createRealm("original"); UserModel user = session.users().addUser(realm, "user"); Assert.assertTrue(user.getRequiredActions().isEmpty()); user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); String id = realm.getId(); commit(); realm = realmManager.getRealm(id); user = session.users().getUserByUsername("user", realm); Assert.assertEquals(1, user.getRequiredActions().size()); Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP.name())); user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); user = session.users().getUserByUsername("user", realm); Assert.assertEquals(1, user.getRequiredActions().size()); Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP.name())); user.addRequiredAction(RequiredAction.VERIFY_EMAIL.name()); user = session.users().getUserByUsername("user", realm); Assert.assertEquals(2, user.getRequiredActions().size()); Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.CONFIGURE_TOTP.name())); Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL.name())); user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP.name()); user = session.users().getUserByUsername("user", realm); Assert.assertEquals(1, user.getRequiredActions().size()); Assert.assertTrue(user.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL.name())); user.removeRequiredAction(RequiredAction.VERIFY_EMAIL.name()); user = session.users().getUserByUsername("user", realm); Assert.assertTrue(user.getRequiredActions().isEmpty()); } @Test public void testUserMultipleAttributes() throws Exception { RealmModel realm = realmManager.createRealm("original"); UserModel user = session.users().addUser(realm, "user"); UserModel userNoAttrs = session.users().addUser(realm, "user-noattrs"); user.setSingleAttribute("key1", "value1"); List<String> attrVals = new ArrayList<>(Arrays.asList( "val21", "val22" )); user.setAttribute("key2", attrVals); commit(); // Test read attributes realm = realmManager.getRealmByName("original"); user = session.users().getUserByUsername("user", realm); attrVals = user.getAttribute("key1"); Assert.assertEquals(1, attrVals.size()); Assert.assertEquals("value1", attrVals.get(0)); Assert.assertEquals("value1", user.getFirstAttribute("key1")); attrVals = user.getAttribute("key2"); Assert.assertEquals(2, attrVals.size()); Assert.assertTrue(attrVals.contains("val21")); Assert.assertTrue(attrVals.contains("val22")); attrVals = user.getAttribute("key3"); Assert.assertTrue(attrVals.isEmpty()); Assert.assertNull(user.getFirstAttribute("key3")); Map<String, List<String>> allAttrVals = user.getAttributes(); Assert.assertEquals(2, allAttrVals.size()); Assert.assertEquals(allAttrVals.get("key1"), user.getAttribute("key1")); Assert.assertEquals(allAttrVals.get("key2"), user.getAttribute("key2")); // Test remove and rewrite attribute user.removeAttribute("key1"); user.setSingleAttribute("key2", "val23"); commit(); realm = realmManager.getRealmByName("original"); user = session.users().getUserByUsername("user", realm); Assert.assertNull(user.getFirstAttribute("key1")); attrVals = user.getAttribute("key2"); Assert.assertEquals(1, attrVals.size()); Assert.assertEquals("val23", attrVals.get(0)); } // KEYCLOAK-3494 @Test public void testUpdateUserAttribute() throws Exception { RealmModel realm = realmManager.createRealm("original"); UserModel user = session.users().addUser(realm, "user"); user.setSingleAttribute("key1", "value1"); commit(); realm = realmManager.getRealmByName("original"); user = session.users().getUserByUsername("user", realm); // Update attribute List<String> attrVals = new ArrayList<>(Arrays.asList( "val2" )); user.setAttribute("key1", attrVals); Map<String, List<String>> allAttrVals = user.getAttributes(); // Ensure same transaction is able to see updated value Assert.assertEquals(1, allAttrVals.size()); Assert.assertEquals(allAttrVals.get("key1"), Arrays.asList("val2")); commit(); } // KEYCLOAK-3608 @Test public void testUpdateUserSingleAttribute() { Map<String, List<String>> expected = ImmutableMap.of( "key1", Arrays.asList("value3"), "key2", Arrays.asList("value2")); RealmModel realm = realmManager.createRealm("original"); UserModel user = session.users().addUser(realm, "user"); user.setSingleAttribute("key1", "value1"); user.setSingleAttribute("key2", "value2"); // Overwrite the first attribute user.setSingleAttribute("key1", "value3"); Assert.assertEquals(expected, user.getAttributes()); commit(); realm = session.realms().getRealmByName("original"); Assert.assertEquals(expected, session.users().getUserByUsername("user", realm).getAttributes()); } @Test public void testSearchByString() { RealmModel realm = realmManager.createRealm("original"); UserModel user1 = session.users().addUser(realm, "user1"); commit(); realm = session.realms().getRealmByName("original"); List<UserModel> users = session.users().searchForUser("user", realm, 0, 7); Assert.assertTrue(users.contains(user1)); } @Test public void testSearchByUserAttribute() throws Exception { RealmModel realm = realmManager.createRealm("original"); UserModel user1 = session.users().addUser(realm, "user1"); UserModel user2 = session.users().addUser(realm, "user2"); UserModel user3 = session.users().addUser(realm, "user3"); RealmModel otherRealm = realmManager.createRealm("other"); UserModel otherRealmUser = session.users().addUser(otherRealm, "user1"); user1.setSingleAttribute("key1", "value1"); user1.setSingleAttribute("key2", "value21"); user2.setSingleAttribute("key1", "value1"); user2.setSingleAttribute("key2", "value22"); user3.setSingleAttribute("key2", "value21"); otherRealmUser.setSingleAttribute("key2", "value21"); commit(); realm = session.realms().getRealmByName("original"); List<UserModel> users = session.users().searchForUserByUserAttribute("key1", "value1", realm); Assert.assertEquals(2, users.size()); Assert.assertTrue(users.contains(user1)); Assert.assertTrue(users.contains(user2)); users = session.users().searchForUserByUserAttribute("key2", "value21", realm); Assert.assertEquals(2, users.size()); Assert.assertTrue(users.contains(user1)); Assert.assertTrue(users.contains(user3)); users = session.users().searchForUserByUserAttribute("key2", "value22", realm); Assert.assertEquals(1, users.size()); Assert.assertTrue(users.contains(user2)); users = session.users().searchForUserByUserAttribute("key3", "value3", realm); Assert.assertEquals(0, users.size()); } @Test public void testServiceAccountLink() throws Exception { RealmModel realm = realmManager.createRealm("original"); ClientModel client = realm.addClient("foo"); UserModel user1 = session.users().addUser(realm, "user1"); user1.setFirstName("John"); user1.setLastName("Doe"); UserModel user2 = session.users().addUser(realm, "user2"); user2.setFirstName("John"); user2.setLastName("Doe"); // Search Assert.assertNull(session.users().getServiceAccount(client)); List<UserModel> users = session.users().searchForUser("John Doe", realm); Assert.assertEquals(2, users.size()); Assert.assertTrue(users.contains(user1)); Assert.assertTrue(users.contains(user2)); // Link service account user1.setServiceAccountClientLink(client.getId()); commit(); // Search and assert service account user not found realm = realmManager.getRealmByName("original"); client = realm.getClientByClientId("foo"); UserModel searched = session.users().getServiceAccount(client); Assert.assertEquals(searched, user1); users = session.users().searchForUser("John Doe", realm); Assert.assertEquals(1, users.size()); Assert.assertFalse(users.contains(user1)); Assert.assertTrue(users.contains(user2)); users = session.users().getUsers(realm, false); Assert.assertEquals(1, users.size()); Assert.assertFalse(users.contains(user1)); Assert.assertTrue(users.contains(user2)); users = session.users().getUsers(realm, true); Assert.assertEquals(2, users.size()); Assert.assertTrue(users.contains(user1)); Assert.assertTrue(users.contains(user2)); Assert.assertEquals(2, session.users().getUsersCount(realm)); // Remove client new ClientManager(realmManager).removeClient(realm, client); commit(); // Assert service account removed as well realm = realmManager.getRealmByName("original"); Assert.assertNull(session.users().getUserByUsername("user1", realm)); } @Test public void testGrantToAll() { RealmModel realm1 = realmManager.createRealm("realm1"); RoleModel role1 = realm1.addRole("role1"); UserModel user1 = realmManager.getSession().users().addUser(realm1, "user1"); UserModel user2 = realmManager.getSession().users().addUser(realm1, "user2"); RealmModel realm2 = realmManager.createRealm("realm2"); UserModel realm2User1 = realmManager.getSession().users().addUser(realm2, "user1"); commit(); realm1 = realmManager.getRealmByName("realm1"); role1 = realm1.getRole("role1"); realmManager.getSession().users().grantToAllUsers(realm1, role1); commit(); realm1 = realmManager.getRealmByName("realm1"); role1 = realm1.getRole("role1"); user1 = realmManager.getSession().users().getUserByUsername("user1", realm1); user2 = realmManager.getSession().users().getUserByUsername("user2", realm1); Assert.assertTrue(user1.hasRole(role1)); Assert.assertTrue(user2.hasRole(role1)); realm2 = realmManager.getRealmByName("realm2"); realm2User1 = realmManager.getSession().users().getUserByUsername("user1", realm2); Assert.assertFalse(realm2User1.hasRole(role1)); } public static void assertEquals(UserModel expected, UserModel actual) { Assert.assertEquals(expected.getUsername(), actual.getUsername()); Assert.assertEquals(expected.getCreatedTimestamp(), actual.getCreatedTimestamp()); Assert.assertEquals(expected.getFirstName(), actual.getFirstName()); Assert.assertEquals(expected.getLastName(), actual.getLastName()); String[] expectedRequiredActions = expected.getRequiredActions().toArray(new String[expected.getRequiredActions().size()]); Arrays.sort(expectedRequiredActions); String[] actualRequiredActions = actual.getRequiredActions().toArray(new String[actual.getRequiredActions().size()]); Arrays.sort(actualRequiredActions); Assert.assertArrayEquals(expectedRequiredActions, actualRequiredActions); } }