[KEYCLOAK-7907] Migrate model package from old testsuite
This commit is contained in:
parent
845275ef0f
commit
bec5d676e7
17 changed files with 3224 additions and 2520 deletions
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* 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 org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ConcurrentTransactionsTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, UserSessionProviderOfflineTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ConcurrentTransactionsTest.class);
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void persistClient(KeycloakSession session) {
|
||||
|
||||
final ClientModel[] client = {null};
|
||||
AtomicReference<String> clientDBIdAtomic = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSetup) -> {
|
||||
|
||||
RealmModel realm = sessionSetup.realms().getRealm("test");
|
||||
sessionSetup.users().addUser(realm, "user1").setEmail("user1@localhost");
|
||||
sessionSetup.users().addUser(realm, "user2").setEmail("user2@localhost");
|
||||
|
||||
realm = sessionSetup.realms().createRealm("original");
|
||||
|
||||
client[0] = sessionSetup.realms().addClient(realm, "client");
|
||||
client[0].setSecret("old");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> {
|
||||
String clientDBId = client[0].getId();
|
||||
clientDBIdAtomic.set(clientDBId);
|
||||
|
||||
final KeycloakSessionFactory sessionFactory = session1.getKeycloakSessionFactory();
|
||||
|
||||
final CountDownLatch transactionsCounter = new CountDownLatch(2);
|
||||
final CountDownLatch readLatch = new CountDownLatch(1);
|
||||
final CountDownLatch updateLatch = new CountDownLatch(1);
|
||||
|
||||
Thread thread1 = new Thread(() -> {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, session11 -> {
|
||||
try {
|
||||
KeycloakSession currentSession = session11;
|
||||
// Wait until transaction in both threads started
|
||||
transactionsCounter.countDown();
|
||||
logger.info("transaction1 started");
|
||||
transactionsCounter.await();
|
||||
|
||||
// Read client
|
||||
RealmModel realm1 = currentSession.realms().getRealmByName("original");
|
||||
ClientModel client1 = currentSession.realms().getClientByClientId("client", realm1);
|
||||
logger.info("transaction1: Read client finished");
|
||||
readLatch.countDown();
|
||||
|
||||
// Wait until thread2 updates client and commits
|
||||
updateLatch.await();
|
||||
logger.info("transaction1: Going to read client again");
|
||||
|
||||
client1 = currentSession.realms().getClientByClientId("client", realm1);
|
||||
logger.info("transaction1: secret: " + client1.getSecret());
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Thread thread2 = new Thread(() -> {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, session22 -> {
|
||||
try {
|
||||
KeycloakSession currentSession = session22;
|
||||
// Wait until transaction in both threads started
|
||||
transactionsCounter.countDown();
|
||||
logger.info("transaction2 started");
|
||||
transactionsCounter.await();
|
||||
|
||||
readLatch.await();
|
||||
logger.info("transaction2: Going to update client secret");
|
||||
|
||||
RealmModel realm12 = currentSession.realms().getRealmByName("original");
|
||||
ClientModel client12 = currentSession.realms().getClientByClientId("client", realm12);
|
||||
client12.setSecret("new");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
logger.info("transaction2: commited");
|
||||
updateLatch.countDown();
|
||||
});
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
try {
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
logger.info("after thread join");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session2) -> {
|
||||
RealmModel realm = session2.realms().getRealmByName("original");
|
||||
String clientDBId = clientDBIdAtomic.get();
|
||||
|
||||
ClientModel clientFromCache = session2.realms().getClientById(clientDBId, realm);
|
||||
ClientModel clientFromDB = session2.getProvider(RealmProvider.class).getClientById(clientDBId, realm);
|
||||
|
||||
logger.info("SECRET FROM DB : " + clientFromDB.getSecret());
|
||||
logger.info("SECRET FROM CACHE : " + clientFromCache.getSecret());
|
||||
|
||||
Assert.assertEquals("new", clientFromDB.getSecret());
|
||||
Assert.assertEquals("new", clientFromCache.getSecret());
|
||||
|
||||
session2.sessions().removeUserSessions(realm);
|
||||
|
||||
tearDownRealm(session2, "user1", "user2");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// KEYCLOAK-3296 , KEYCLOAK-3494
|
||||
@Test
|
||||
@ModelTest
|
||||
public void removeUserAttribute(KeycloakSession session) throws Exception {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSet) -> {
|
||||
|
||||
RealmModel realm = sessionSet.realms().createRealm("original");
|
||||
|
||||
UserModel john = sessionSet.users().addUser(realm, "john");
|
||||
john.setSingleAttribute("foo", "val1");
|
||||
|
||||
UserModel john2 = sessionSet.users().addUser(realm, "john2");
|
||||
john2.setAttribute("foo", Arrays.asList("val1", "val2"));
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session2) -> {
|
||||
|
||||
final KeycloakSessionFactory sessionFactory = session2.getKeycloakSessionFactory();
|
||||
|
||||
AtomicReference<Exception> reference = new AtomicReference<>();
|
||||
|
||||
final CountDownLatch readAttrLatch = new CountDownLatch(2);
|
||||
|
||||
Runnable runnable = () -> {
|
||||
try {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, session1 -> {
|
||||
try {
|
||||
// Read user attribute
|
||||
RealmModel realm = session1.realms().getRealmByName("original");
|
||||
UserModel john = session1.users().getUserByUsername("john", realm);
|
||||
String attrVal = john.getFirstAttribute("foo");
|
||||
|
||||
UserModel john2 = session1.users().getUserByUsername("john2", realm);
|
||||
String attrVal2 = john2.getFirstAttribute("foo");
|
||||
|
||||
// Wait until it's read in both threads
|
||||
readAttrLatch.countDown();
|
||||
readAttrLatch.await();
|
||||
|
||||
// KEYCLOAK-3296 : Remove user attribute in both threads
|
||||
john.removeAttribute("foo");
|
||||
|
||||
// KEYCLOAK-3494 : Set single attribute in both threads
|
||||
john2.setSingleAttribute("foo", "bar");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
reference.set(e);
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
readAttrLatch.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
Thread thread1 = new Thread(runnable);
|
||||
Thread thread2 = new Thread(runnable);
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
try {
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
logger.info("removeUserAttribute: after thread join");
|
||||
if (reference.get() != null) {
|
||||
Assert.fail("Exception happened in some of threads. Details: " + reference.get().getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTearDown) -> {
|
||||
tearDownRealm(sessionTearDown, "john", "john2");
|
||||
});
|
||||
}
|
||||
|
||||
private void tearDownRealm(KeycloakSession session, String user1, String user2) {
|
||||
KeycloakSession currentSession = session;
|
||||
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel realmUser1 = currentSession.users().getUserByUsername(user1, realm);
|
||||
UserModel realmUser2 = currentSession.users().getUserByUsername(user2, realm);
|
||||
|
||||
UserManager um = new UserManager(currentSession);
|
||||
if (realmUser1 != null) {
|
||||
um.removeUser(realm, realmUser1);
|
||||
}
|
||||
if (realmUser2 != null) {
|
||||
um.removeUser(realm, realmUser2);
|
||||
}
|
||||
|
||||
assert (currentSession.realms().removeRealm(realm.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
}
|
|
@ -17,10 +17,14 @@
|
|||
|
||||
package org.keycloak.testsuite.model;
|
||||
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.KeycloakSessionTask;
|
||||
|
@ -28,15 +32,30 @@ import org.keycloak.models.dblock.DBLockManager;
|
|||
import org.keycloak.models.dblock.DBLockProvider;
|
||||
import org.keycloak.models.dblock.DBLockProviderFactory;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class DBLockTest extends AbstractModelTest {
|
||||
public class DBLockTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, DBLockTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
private static final Logger log = Logger.getLogger(DBLockTest.class);
|
||||
|
||||
|
@ -48,66 +67,65 @@ public class DBLockTest extends AbstractModelTest {
|
|||
private static final int LOCK_RECHECK_MILLIS = 10;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void before() throws Exception {
|
||||
super.before();
|
||||
|
||||
// Set timeouts for testing
|
||||
DBLockManager lockManager = new DBLockManager(session);
|
||||
DBLockProviderFactory lockFactory = lockManager.getDBLockFactory();
|
||||
lockFactory.setTimeouts(LOCK_RECHECK_MILLIS, LOCK_TIMEOUT_MILLIS);
|
||||
testingClient.server().run(session -> {
|
||||
// Set timeouts for testing
|
||||
DBLockManager lockManager = new DBLockManager(session);
|
||||
DBLockProviderFactory lockFactory = lockManager.getDBLockFactory();
|
||||
lockFactory.setTimeouts(LOCK_RECHECK_MILLIS, LOCK_TIMEOUT_MILLIS);
|
||||
|
||||
// Drop lock table, just to simulate racing threads for create lock table and insert lock record into it.
|
||||
lockManager.getDBLock().destroyLockInfo();
|
||||
// Drop lock table, just to simulate racing threads for create lock table and insert lock record into it.
|
||||
lockManager.getDBLock().destroyLockInfo();
|
||||
});
|
||||
|
||||
commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockConcurrently() throws Exception {
|
||||
long startupTime = System.currentTimeMillis();
|
||||
@ModelTest
|
||||
public void testLockConcurrently(KeycloakSession session) throws Exception {
|
||||
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
final KeycloakSessionFactory sessionFactory = realmManager.getSession().getKeycloakSessionFactory();
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionLC) -> {
|
||||
long startupTime = System.currentTimeMillis();
|
||||
|
||||
List<Thread> threads = new LinkedList<>();
|
||||
for (int i=0 ; i<THREADS_COUNT ; i++) {
|
||||
Thread thread = new Thread() {
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
final KeycloakSessionFactory sessionFactory = sessionLC.getKeycloakSessionFactory();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i=0 ; i<ITERATIONS_PER_THREAD ; i++) {
|
||||
List<Thread> threads = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < THREADS_COUNT; i++) {
|
||||
Thread thread = new Thread(() -> {
|
||||
for (int j = 0; j < ITERATIONS_PER_THREAD; j++) {
|
||||
try {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||
|
||||
@Override
|
||||
public void run(KeycloakSession session) {
|
||||
lock(session, semaphore);
|
||||
}
|
||||
|
||||
});
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, session1 ->
|
||||
lock(session1, semaphore));
|
||||
} catch (RuntimeException e) {
|
||||
semaphore.setException(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
threads.add(thread);
|
||||
}
|
||||
|
||||
for (Thread thread : threads) {
|
||||
thread.start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
threads.add(thread);
|
||||
}
|
||||
long took = (System.currentTimeMillis() - startupTime);
|
||||
log.infof("DBLockTest executed in %d ms with total counter %d. THREADS_COUNT=%d, ITERATIONS_PER_THREAD=%d", took, semaphore.getTotal(), THREADS_COUNT, ITERATIONS_PER_THREAD);
|
||||
|
||||
for (Thread thread : threads) {
|
||||
thread.start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
long took = (System.currentTimeMillis() - startupTime);
|
||||
log.infof("DBLockTest executed in %d ms with total counter %d. THREADS_COUNT=%d, ITERATIONS_PER_THREAD=%d", took, semaphore.getTotal(), THREADS_COUNT, ITERATIONS_PER_THREAD);
|
||||
Assert.assertEquals(semaphore.getTotal(), THREADS_COUNT * ITERATIONS_PER_THREAD);
|
||||
Assert.assertNull(semaphore.getException());
|
||||
Assert.assertEquals(semaphore.getTotal(), THREADS_COUNT * ITERATIONS_PER_THREAD);
|
||||
Assert.assertNull(semaphore.getException());
|
||||
});
|
||||
}
|
||||
|
||||
private void lock(KeycloakSession session, Semaphore semaphore) {
|
||||
|
@ -124,6 +142,9 @@ public class DBLockTest extends AbstractModelTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
|
||||
// Ensure just one thread is allowed to run at the same time
|
||||
private class Semaphore {
|
||||
|
@ -167,7 +188,7 @@ public class DBLockTest extends AbstractModelTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ public class ImportTest extends AbstractTestRealmKeycloakTest {
|
|||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, AbstractLDAPTest.class)
|
||||
return RunOnServerDeployment.create(UserResource.class, ImportTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* 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 org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class MultipleRealmsTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, MultipleRealmsTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
public static void createObjects(KeycloakSession session, RealmModel realm) {
|
||||
ClientModel app1 = realm.addClient("app1");
|
||||
realm.addClient("app2");
|
||||
|
||||
session.users().addUser(realm, "user1");
|
||||
session.users().addUser(realm, "user2");
|
||||
|
||||
realm.addRole("role1");
|
||||
realm.addRole("role2");
|
||||
|
||||
app1.addRole("app1Role1");
|
||||
app1.addScopeMapping(realm.getRole("role1"));
|
||||
|
||||
realm.addClient("cl1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testUsers(KeycloakSession session) {
|
||||
|
||||
AtomicReference<UserModel> r1user1Atomic = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTestUser1) -> {
|
||||
KeycloakSession currentSession = sessionTestUser1;
|
||||
|
||||
RealmModel realm1 = currentSession.realms().createRealm("id1", "realm1");
|
||||
RealmModel realm2 = currentSession.realms().createRealm("id2", "realm2");
|
||||
|
||||
createObjects(currentSession, realm1);
|
||||
createObjects(currentSession, realm2);
|
||||
|
||||
UserModel r1user1 = currentSession.users().getUserByUsername("user1", realm1);
|
||||
UserModel r2user1 = currentSession.users().getUserByUsername("user1", realm2);
|
||||
|
||||
r1user1Atomic.set(r1user1);
|
||||
|
||||
Assert.assertEquals(r1user1.getUsername(), r2user1.getUsername());
|
||||
Assert.assertNotEquals(r1user1.getId(), r2user1.getId());
|
||||
|
||||
// Test password
|
||||
currentSession.userCredentialManager().updateCredential(realm1, r1user1, UserCredentialModel.password("pass1"));
|
||||
currentSession.userCredentialManager().updateCredential(realm2, r2user1, UserCredentialModel.password("pass2"));
|
||||
|
||||
Assert.assertTrue(currentSession.userCredentialManager().isValid(realm1, r1user1, UserCredentialModel.password("pass1")));
|
||||
Assert.assertFalse(currentSession.userCredentialManager().isValid(realm1, r1user1, UserCredentialModel.password("pass2")));
|
||||
Assert.assertFalse(currentSession.userCredentialManager().isValid(realm2, r2user1, UserCredentialModel.password("pass1")));
|
||||
Assert.assertTrue(currentSession.userCredentialManager().isValid(realm2, r2user1, UserCredentialModel.password("pass2")));
|
||||
|
||||
// Test searching
|
||||
Assert.assertEquals(2, currentSession.users().searchForUser("user", realm1).size());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTestUser2) -> {
|
||||
KeycloakSession currentSession = sessionTestUser2;
|
||||
|
||||
RealmModel realm1 = currentSession.realms().getRealm("id1");
|
||||
RealmModel realm2 = currentSession.realms().getRealm("id2");
|
||||
|
||||
UserModel r1user1 = r1user1Atomic.get();
|
||||
|
||||
currentSession.users().removeUser(realm1, r1user1);
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm1);
|
||||
currentSession.users().removeUser(realm1, user2);
|
||||
Assert.assertEquals(0, currentSession.users().searchForUser("user", realm1).size());
|
||||
Assert.assertEquals(2, currentSession.users().searchForUser("user", realm2).size());
|
||||
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm1);
|
||||
UserModel user1a = currentSession.users().getUserByUsername("user1", realm2);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm1, user1);
|
||||
}
|
||||
if (user1a != null) {
|
||||
um.removeUser(realm2, user1a);
|
||||
}
|
||||
|
||||
currentSession.realms().removeRealm("id1");
|
||||
currentSession.realms().removeRealm("id2");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testGetById(KeycloakSession session) {
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionById) -> {
|
||||
KeycloakSession currentSession = sessionById;
|
||||
|
||||
RealmModel realm1 = currentSession.realms().createRealm("id1", "realm1");
|
||||
RealmModel realm2 = currentSession.realms().createRealm("id2", "realm2");
|
||||
|
||||
createObjects(currentSession, realm1);
|
||||
createObjects(currentSession, realm2);
|
||||
|
||||
Assert.assertEquals(realm1, currentSession.realms().getRealm("id1"));
|
||||
Assert.assertEquals(realm1, currentSession.realms().getRealmByName("realm1"));
|
||||
Assert.assertEquals(realm2, currentSession.realms().getRealm("id2"));
|
||||
Assert.assertEquals(realm2, currentSession.realms().getRealmByName("realm2"));
|
||||
|
||||
ClientModel r1app1 = realm1.getClientByClientId("app1");
|
||||
|
||||
Assert.assertNotNull(realm1.getClientByClientId("app2"));
|
||||
Assert.assertNotNull(realm2.getClientByClientId("app1"));
|
||||
Assert.assertNotNull(realm2.getClientByClientId("app2"));
|
||||
|
||||
Assert.assertEquals(r1app1, realm1.getClientById(r1app1.getId()));
|
||||
Assert.assertNull(realm2.getClientById(r1app1.getId()));
|
||||
|
||||
ClientModel r2cl1 = realm2.getClientByClientId("cl1");
|
||||
Assert.assertEquals(r2cl1.getId(), realm2.getClientById(r2cl1.getId()).getId());
|
||||
Assert.assertNull(realm1.getClientByClientId(r2cl1.getId()));
|
||||
|
||||
RoleModel r1App1Role = r1app1.getRole("app1Role1");
|
||||
Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId()));
|
||||
Assert.assertNull(realm2.getRoleById(r1App1Role.getId()));
|
||||
|
||||
RoleModel r2Role1 = realm2.getRole("role2");
|
||||
Assert.assertNull(realm1.getRoleById(r2Role1.getId()));
|
||||
Assert.assertEquals(r2Role1, realm2.getRoleById(r2Role1.getId()));
|
||||
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm1);
|
||||
UserModel user1a = currentSession.users().getUserByUsername("user1", realm2);
|
||||
|
||||
UserManager um = new UserManager(currentSession);
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm1, user1);
|
||||
}
|
||||
if (user1a != null) {
|
||||
um.removeUser(realm2, user1a);
|
||||
}
|
||||
|
||||
currentSession.realms().removeRealm("id1");
|
||||
currentSession.realms().removeRealm("id2");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* 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 org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
private static ComponentModel clientStorageComponent;
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, UserConsentModelTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
testingClient.server().run(session -> {
|
||||
setupEnv(session);
|
||||
});
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
testingClient.server().run(session -> {
|
||||
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel realm = realmManager.getRealmByName("original");
|
||||
|
||||
if (realm != null) {
|
||||
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user = session.users().getUserByUsername("user", realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
UserModel user3 = session.users().getUserByUsername("user3", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user != null) {
|
||||
um.removeUser(realm, user);
|
||||
}
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm, user1);
|
||||
}
|
||||
if (user2 != null) {
|
||||
um.removeUser(realm, user2);
|
||||
}
|
||||
if (user3 != null) {
|
||||
um.removeUser(realm, user3);
|
||||
}
|
||||
realmManager.removeRealm(realm);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setupEnv(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionEnv) -> {
|
||||
KeycloakSession currentSession = sessionEnv;
|
||||
|
||||
RealmManager realmManager = new RealmManager(currentSession);
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.addClient("foo-client");
|
||||
ClientModel barClient = realm.addClient("bar-client");
|
||||
|
||||
ClientScopeModel fooScope = realm.addClientScope("foo");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
ClientScopeModel barScope = realm.addClientScope("bar");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
UserModel john = currentSession.users().addUser(realm, "john");
|
||||
UserModel mary = currentSession.users().addUser(realm, "mary");
|
||||
|
||||
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
||||
johnFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
|
||||
|
||||
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
||||
johnBarGrant.addGrantedClientScope(barScope);
|
||||
|
||||
// Update should fail as grant doesn't yet exists
|
||||
try {
|
||||
realmManager.getSession().users().updateConsent(realm, john.getId(), johnBarGrant);
|
||||
Assert.fail("Not expected to end here");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
|
||||
|
||||
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
||||
maryFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
|
||||
|
||||
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
||||
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, "http://localhost:8081/*");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CONSENT, "true");
|
||||
clientStorage.setParentId(realm.getId());
|
||||
clientStorageComponent = realm.addComponentModel(clientStorage);
|
||||
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
Assert.assertNotNull(hardcodedClient);
|
||||
|
||||
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void basicConsentTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCT) -> {
|
||||
KeycloakSession currentSession = sessionCT;
|
||||
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel johnBarConsent = currentSession.users().getConsentByClient(realm, john.getId(), barClient.getId());
|
||||
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel maryConsent = currentSession.users().getConsentByClient(realm, mary.getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
UserConsentModel maryHardcodedConsent = currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
||||
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), barClient.getId()));
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void getAllConsentTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionACT) -> {
|
||||
KeycloakSession currentSession = sessionACT;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> johnConsents = currentSession.users().getConsents(realm, john.getId());
|
||||
Assert.assertEquals(2, johnConsents.size());
|
||||
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(2, maryConsents.size());
|
||||
UserConsentModel maryConsent = maryConsents.get(0);
|
||||
UserConsentModel maryHardcodedConsent = maryConsents.get(1);
|
||||
if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) {
|
||||
maryConsent = maryConsents.get(1);
|
||||
maryHardcodedConsent = maryConsents.get(0);
|
||||
|
||||
}
|
||||
Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
|
||||
Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void updateWithClientScopeRemovalTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession removalTestSession1) -> {
|
||||
KeycloakSession currentSession = removalTestSession1;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
||||
|
||||
// Remove foo protocol mapper from johnConsent
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
johnConsent.getGrantedClientScopes().remove(fooScope);
|
||||
|
||||
currentSession.users().updateConsent(realm, john.getId(), johnConsent);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession removalTestSession2) -> {
|
||||
KeycloakSession currentSession = removalTestSession2;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void revokeTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRT1) -> {
|
||||
KeycloakSession currentSession = sessionRT1;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
|
||||
currentSession.users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
currentSession.users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRT2) -> {
|
||||
KeycloakSession currentSession = sessionRT2;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId()));
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteUserTest(KeycloakSession session) {
|
||||
// Validate user deleted without any referential constraint errors
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUT) -> {
|
||||
KeycloakSession currentSession = sessionUT;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
currentSession.users().removeUser(realm, john);
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
currentSession.users().removeUser(realm, mary);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteClientScopeTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionST1) -> {
|
||||
KeycloakSession currentSession = sessionST1;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
realm.removeClientScope(fooScope.getId());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionST2) -> {
|
||||
KeycloakSession currentSession = sessionST2;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteClientTest(KeycloakSession session) {
|
||||
|
||||
AtomicReference<String> barClientID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionDCT1) -> {
|
||||
KeycloakSession currentSession = sessionDCT1;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
barClientID.set(barClient.getId());
|
||||
|
||||
realm.removeClient(barClient.getId());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionDCT2) -> {
|
||||
KeycloakSession currentSession = sessionDCT2;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
Assert.assertNull(realm.getClientByClientId("bar-client"));
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
|
||||
UserConsentModel johnFooConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), barClientID.get()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteClientStorageTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCST1) -> {
|
||||
KeycloakSession currentSession = sessionCST1;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
realm.removeComponent(clientStorageComponent);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCST2) -> {
|
||||
KeycloakSession currentSession = sessionCST2;
|
||||
RealmModel realm = currentSession.realms().getRealm("original");
|
||||
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
Assert.assertNull(hardcodedClient);
|
||||
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(1, maryConsents.size());
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isClientScopeGranted(RealmModel realm, String scopeName, UserConsentModel consentModel) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(realm, scopeName);
|
||||
return consentModel.isClientScopeGranted(clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* 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 org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
|
||||
import org.keycloak.testsuite.federation.UserMapStorageFactory;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, UserConsentWithUserStorageModelTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
private static ComponentModel clientStorageComponent;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
testingClient.server().run(currentSession -> {
|
||||
setupEnv(currentSession);
|
||||
});
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
testingClient.server().run(session -> {
|
||||
|
||||
RealmManager realmManager = new RealmManager(session);
|
||||
RealmModel realm = realmManager.getRealmByName("original");
|
||||
|
||||
if (realm != null) {
|
||||
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user = session.users().getUserByUsername("user", realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
UserModel user3 = session.users().getUserByUsername("user3", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user != null) {
|
||||
um.removeUser(realm, user);
|
||||
}
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm, user1);
|
||||
}
|
||||
if (user2 != null) {
|
||||
um.removeUser(realm, user2);
|
||||
}
|
||||
if (user3 != null) {
|
||||
um.removeUser(realm, user3);
|
||||
}
|
||||
realmManager.removeRealm(realm);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setupEnv(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionSetUpEnv) -> {
|
||||
KeycloakSession currentSession = sessionSetUpEnv;
|
||||
|
||||
RealmManager realmManager = new RealmManager(currentSession);
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
|
||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
||||
model.setName("memory");
|
||||
model.setPriority(0);
|
||||
model.setProviderId(UserMapStorageFactory.PROVIDER_ID);
|
||||
model.setParentId(realm.getId());
|
||||
realm.addComponentModel(model);
|
||||
|
||||
ClientModel fooClient = realm.addClient("foo-client");
|
||||
ClientModel barClient = realm.addClient("bar-client");
|
||||
|
||||
ClientScopeModel fooScope = realm.addClientScope("foo");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
ClientScopeModel barScope = realm.addClientScope("bar");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
UserModel john = currentSession.users().addUser(realm, "john");
|
||||
UserModel mary = currentSession.users().addUser(realm, "mary");
|
||||
|
||||
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
||||
johnFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
|
||||
|
||||
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
||||
johnBarGrant.addGrantedClientScope(barScope);
|
||||
|
||||
// Update should fail as grant doesn't yet exists
|
||||
try {
|
||||
currentSession.users().updateConsent(realm, john.getId(), johnBarGrant);
|
||||
Assert.fail("Not expected to end here");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
|
||||
|
||||
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
||||
maryFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
|
||||
|
||||
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
||||
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, "http://localhost:8081/*");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CONSENT, "true");
|
||||
clientStorage.setParentId(realm.getId());
|
||||
clientStorageComponent = realm.addComponentModel(clientStorage);
|
||||
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
Assert.assertNotNull(hardcodedClient);
|
||||
|
||||
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void basicConsentTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession currentSessionCT) -> {
|
||||
KeycloakSession currentSession = currentSessionCT;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
|
||||
UserModel john = currentSessionCT.users().getUserByUsername("john", realm);
|
||||
UserModel mary = currentSessionCT.users().getUserByUsername("mary", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel johnBarConsent = currentSession.users().getConsentByClient(realm, john.getId(), barClient.getId());
|
||||
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel maryConsent = currentSession.users().getConsentByClient(realm, mary.getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||
|
||||
ClientModel hardcodedClient = currentSessionCT.realms().getClientByClientId("hardcoded-client", realm);
|
||||
UserConsentModel maryHardcodedConsent = currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
||||
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), barClient.getId()));
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void getAllConsentTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession currentSessionACT) -> {
|
||||
KeycloakSession currentSession = currentSessionACT;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
|
||||
UserModel john = currentSessionACT.users().getUserByUsername("john", realm);
|
||||
UserModel mary = currentSessionACT.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> johnConsents = currentSession.users().getConsents(realm, john.getId());
|
||||
Assert.assertEquals(2, johnConsents.size());
|
||||
|
||||
ClientModel hardcodedClient = currentSessionACT.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(2, maryConsents.size());
|
||||
UserConsentModel maryConsent = maryConsents.get(0);
|
||||
UserConsentModel maryHardcodedConsent = maryConsents.get(1);
|
||||
if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) {
|
||||
maryConsent = maryConsents.get(1);
|
||||
maryHardcodedConsent = maryConsents.get(0);
|
||||
|
||||
}
|
||||
Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
|
||||
Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void updateWithClientScopeRemovalTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionScopeRemoval1) -> {
|
||||
KeycloakSession currentSession = sessionScopeRemoval1;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
||||
|
||||
// Remove foo protocol mapper from johnConsent
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
johnConsent.getGrantedClientScopes().remove(fooScope);
|
||||
|
||||
currentSession.users().updateConsent(realm, john.getId(), johnConsent);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionScopeRemoval2) -> {
|
||||
KeycloakSession currentSession = sessionScopeRemoval2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void revokeTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRevoke1) -> {
|
||||
KeycloakSession currentSession = sessionRevoke1;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
|
||||
currentSession.users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
currentSession.users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRevoke2) -> {
|
||||
KeycloakSession currentSession = sessionRevoke2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId()));
|
||||
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
Assert.assertNull(currentSession.users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteUserTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionDelete) -> {
|
||||
// Validate user deleted without any referential constraint errors
|
||||
KeycloakSession currentSession = sessionDelete;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
currentSession.users().removeUser(realm, john);
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
currentSession.users().removeUser(realm, mary);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteClientScopeTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClScope1) -> {
|
||||
KeycloakSession currentSession = sesDelClScope1;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
realm.removeClientScope(fooScope.getId());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClScope2) -> {
|
||||
KeycloakSession currentSession = sesDelClScope2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = currentSession.users().getUserByUsername("john", realm);
|
||||
UserConsentModel johnConsent = currentSession.users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteClientTest(KeycloakSession session) {
|
||||
AtomicReference<String> barClientID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClient1) -> {
|
||||
KeycloakSession currentSession = sesDelClient1;
|
||||
RealmManager realmManager = new RealmManager(currentSession);
|
||||
RealmModel realm = realmManager.getRealmByName("original");
|
||||
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
barClientID.set(barClient.getId());
|
||||
|
||||
realm.removeClient(barClient.getId());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClient2) -> {
|
||||
KeycloakSession currentSession = sesDelClient2;
|
||||
RealmManager realmManager = new RealmManager(currentSession);
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
Assert.assertNull(realm.getClientByClientId("bar-client"));
|
||||
|
||||
UserModel john = realmManager.getSession().users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClientID.get()));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void deleteClientStorageTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClientStore1) -> {
|
||||
KeycloakSession currentSession = sesDelClientStore1;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
realm.removeComponent(clientStorageComponent);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClientStore2) -> {
|
||||
KeycloakSession currentSession = sesDelClientStore2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
ClientModel hardcodedClient = currentSession.realms().getClientByClientId("hardcoded-client", realm);
|
||||
Assert.assertNull(hardcodedClient);
|
||||
|
||||
UserModel mary = currentSession.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(1, maryConsents.size());
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isClientScopeGranted(RealmModel realm, String scopeName, UserConsentModel consentModel) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(realm, scopeName);
|
||||
return consentModel.isClientScopeGranted(clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,615 @@
|
|||
/*
|
||||
* 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.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.UserModel.RequiredAction;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class UserModelTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, UserModelTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model",
|
||||
"com.google.common");
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
testingClient.server().run(session -> {
|
||||
|
||||
RealmModel realm = session.realms().getRealmByName("original");
|
||||
|
||||
if (realm != null) {
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user = session.users().getUserByUsername("user", realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
UserModel user3 = session.users().getUserByUsername("user3", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user != null) {
|
||||
um.removeUser(realm, user);
|
||||
}
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm, user1);
|
||||
}
|
||||
if (user2 != null) {
|
||||
um.removeUser(realm, user2);
|
||||
}
|
||||
if (user3 != null) {
|
||||
um.removeUser(realm, user3);
|
||||
}
|
||||
session.realms().removeRealm(realm.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void persistUser(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesPersistUser) -> {
|
||||
KeycloakSession currentSession = sesPersistUser;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
UserModel user = currentSession.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 = currentSession.realms().getRealm(realm.getId());
|
||||
UserModel persisted = currentSession.users().getUserByUsername("user", searchRealm);
|
||||
|
||||
assertEquals(user, persisted);
|
||||
|
||||
searchRealm = currentSession.realms().getRealm(realm.getId());
|
||||
UserModel persisted2 = currentSession.users().getUserById(user.getId(), searchRealm);
|
||||
assertEquals(user, persisted2);
|
||||
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put(UserModel.LAST_NAME, "last-name");
|
||||
List<UserModel> search = currentSession.users().searchForUser(attributes, realm);
|
||||
Assert.assertEquals(search.size(), 1);
|
||||
Assert.assertEquals(search.get(0).getUsername(), "user");
|
||||
|
||||
attributes.clear();
|
||||
attributes.put(UserModel.EMAIL, "email");
|
||||
search = currentSession.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 = currentSession.users().searchForUser(attributes, realm);
|
||||
Assert.assertEquals(search.size(), 1);
|
||||
Assert.assertEquals(search.get(0).getUsername(), "user");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void webOriginSetTest(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesWebOrigin) -> {
|
||||
KeycloakSession currentSession = sesWebOrigin;
|
||||
RealmModel realm = currentSession.realms().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
|
||||
@ModelTest
|
||||
public void testUserRequiredActions(KeycloakSession session) throws Exception {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUserReqActions) -> {
|
||||
KeycloakSession currentSession = sesUserReqActions;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
UserModel user = currentSession.users().addUser(realm, "user");
|
||||
|
||||
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
||||
|
||||
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
|
||||
String id = realm.getId();
|
||||
|
||||
realm = currentSession.realms().getRealm(id);
|
||||
user = currentSession.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 = currentSession.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 = currentSession.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 = currentSession.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 = currentSession.users().getUserByUsername("user", realm);
|
||||
|
||||
Assert.assertTrue(user.getRequiredActions().isEmpty());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testUserMultipleAttributes(KeycloakSession session) throws Exception {
|
||||
AtomicReference<List<String>> attrValsAtomic = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesMultipleAtr1) -> {
|
||||
KeycloakSession currentSession = sesMultipleAtr1;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
UserModel user = currentSession.users().addUser(realm, "user");
|
||||
currentSession.users().addUser(realm, "user-noattrs");
|
||||
|
||||
user.setSingleAttribute("key1", "value1");
|
||||
|
||||
List<String> attrVals = new ArrayList<>(Arrays.asList("val21", "val22"));
|
||||
attrValsAtomic.set(attrVals);
|
||||
|
||||
user.setAttribute("key2", attrVals);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesMultipleAtr2) -> {
|
||||
KeycloakSession currentSession = sesMultipleAtr2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
// Test read attributes
|
||||
UserModel user = currentSession.users().getUserByUsername("user", realm);
|
||||
|
||||
List<String> attrVals = attrValsAtomic.get();
|
||||
|
||||
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");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesMultipleAtr3) -> {
|
||||
KeycloakSession currentSession = sesMultipleAtr3;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user = currentSession.users().getUserByUsername("user", realm);
|
||||
Assert.assertNull(user.getFirstAttribute("key1"));
|
||||
|
||||
List<String> attrVals = attrValsAtomic.get();
|
||||
attrVals = user.getAttribute("key2");
|
||||
|
||||
Assert.assertEquals(1, attrVals.size());
|
||||
Assert.assertEquals("val23", attrVals.get(0));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// KEYCLOAK-3494
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testUpdateUserAttribute(KeycloakSession session) throws Exception {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateAtr1) -> {
|
||||
KeycloakSession currentSession = sesUpdateAtr1;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
UserModel user = currentSession.users().addUser(realm, "user");
|
||||
|
||||
user.setSingleAttribute("key1", "value1");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateAtr2) -> {
|
||||
KeycloakSession currentSession = sesUpdateAtr2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user = currentSession.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"));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// KEYCLOAK-3608
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testUpdateUserSingleAttribute(KeycloakSession session) {
|
||||
|
||||
AtomicReference<Map<String, List<String>>> expectedAtomic = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateUserSingleAtr) -> {
|
||||
KeycloakSession currentSession = sesUpdateUserSingleAtr;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
|
||||
Map<String, List<String>> expected = ImmutableMap.of(
|
||||
"key1", Arrays.asList("value3"),
|
||||
"key2", Arrays.asList("value2"));
|
||||
expectedAtomic.set(expected);
|
||||
|
||||
UserModel user = currentSession.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());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateUserSingleAtr2) -> {
|
||||
KeycloakSession currentSession = sesUpdateUserSingleAtr2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
Map<String, List<String>> expected = expectedAtomic.get();
|
||||
Assert.assertEquals(expected, currentSession.users().getUserByUsername("user", realm).getAttributes());
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testSearchByString(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesSearchString1) -> {
|
||||
KeycloakSession currentSession = sesSearchString1;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
currentSession.users().addUser(realm, "user1");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesSearchString1) -> {
|
||||
KeycloakSession currentSession = sesSearchString1;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
|
||||
List<UserModel> users = currentSession.users().searchForUser("user", realm, 0, 7);
|
||||
Assert.assertTrue(users.contains(user1));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testSearchByUserAttribute(KeycloakSession session) throws Exception {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesSearchAtr1) -> {
|
||||
KeycloakSession currentSession = sesSearchAtr1;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
UserModel user1 = currentSession.users().addUser(realm, "user1");
|
||||
UserModel user2 = currentSession.users().addUser(realm, "user2");
|
||||
UserModel user3 = currentSession.users().addUser(realm, "user3");
|
||||
RealmModel otherRealm = currentSession.realms().createRealm("other");
|
||||
UserModel otherRealmUser = currentSession.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");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesSearchAtr2) -> {
|
||||
KeycloakSession currentSession = sesSearchAtr2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm);
|
||||
UserModel user3 = currentSession.users().getUserByUsername("user3", realm);
|
||||
|
||||
List<UserModel> users = currentSession.users().searchForUserByUserAttribute("key1", "value1", realm);
|
||||
Assert.assertEquals(2, users.size());
|
||||
Assert.assertTrue(users.contains(user1));
|
||||
Assert.assertTrue(users.contains(user2));
|
||||
|
||||
users = currentSession.users().searchForUserByUserAttribute("key2", "value21", realm);
|
||||
Assert.assertEquals(2, users.size());
|
||||
Assert.assertTrue(users.contains(user1));
|
||||
Assert.assertTrue(users.contains(user3));
|
||||
|
||||
users = currentSession.users().searchForUserByUserAttribute("key2", "value22", realm);
|
||||
Assert.assertEquals(1, users.size());
|
||||
Assert.assertTrue(users.contains(user2));
|
||||
|
||||
users = currentSession.users().searchForUserByUserAttribute("key3", "value3", realm);
|
||||
Assert.assertEquals(0, users.size());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testServiceAccountLink(KeycloakSession session) throws Exception {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesServiceLink1) -> {
|
||||
KeycloakSession currentSession = sesServiceLink1;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
ClientModel client = realm.addClient("foo");
|
||||
|
||||
UserModel user1 = currentSession.users().addUser(realm, "user1");
|
||||
user1.setFirstName("John");
|
||||
user1.setLastName("Doe");
|
||||
|
||||
UserModel user2 = currentSession.users().addUser(realm, "user2");
|
||||
user2.setFirstName("John");
|
||||
user2.setLastName("Doe");
|
||||
|
||||
// Search
|
||||
Assert.assertNull(currentSession.users().getServiceAccount(client));
|
||||
List<UserModel> users = currentSession.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());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesServiceLink2) -> {
|
||||
KeycloakSession currentSession = sesServiceLink2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm);
|
||||
|
||||
// Search and assert service account user not found
|
||||
ClientModel client = realm.getClientByClientId("foo");
|
||||
UserModel searched = currentSession.users().getServiceAccount(client);
|
||||
Assert.assertEquals(searched, user1);
|
||||
List<UserModel> users = currentSession.users().searchForUser("John Doe", realm);
|
||||
Assert.assertEquals(1, users.size());
|
||||
Assert.assertFalse(users.contains(user1));
|
||||
Assert.assertTrue(users.contains(user2));
|
||||
|
||||
users = currentSession.users().getUsers(realm, false);
|
||||
Assert.assertEquals(1, users.size());
|
||||
Assert.assertFalse(users.contains(user1));
|
||||
Assert.assertTrue(users.contains(user2));
|
||||
|
||||
users = currentSession.users().getUsers(realm, true);
|
||||
Assert.assertEquals(2, users.size());
|
||||
Assert.assertTrue(users.contains(user1));
|
||||
Assert.assertTrue(users.contains(user2));
|
||||
|
||||
Assert.assertEquals(2, currentSession.users().getUsersCount(realm, true));
|
||||
Assert.assertEquals(1, currentSession.users().getUsersCount(realm, false));
|
||||
|
||||
// Remove client
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
|
||||
clientMgr.removeClient(realm, client);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesServiceLink3) -> {
|
||||
KeycloakSession currentSession = sesServiceLink3;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
// Assert service account removed as well
|
||||
Assert.assertNull(currentSession.users().getUserByUsername("user1", realm));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testGrantToAll(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll1) -> {
|
||||
KeycloakSession currentSession = sesGrantToAll1;
|
||||
|
||||
if (currentSession.realms().getRealm("realm1") != null)
|
||||
currentSession.realms().removeRealm("realm1");
|
||||
|
||||
RealmModel realm1 = currentSession.realms().createRealm("realm1");
|
||||
|
||||
realm1.addRole("role1");
|
||||
currentSession.users().addUser(realm1, "user1");
|
||||
currentSession.users().addUser(realm1, "user2");
|
||||
|
||||
if (currentSession.realms().getRealm("realm2") != null)
|
||||
currentSession.realms().removeRealm("realm2");
|
||||
|
||||
RealmModel realm2 = currentSession.realms().createRealm("realm2");
|
||||
currentSession.users().addUser(realm2, "user1");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll2) -> {
|
||||
KeycloakSession currentSession = sesGrantToAll2;
|
||||
RealmModel realm1 = currentSession.realms().getRealmByName("realm1");
|
||||
|
||||
RoleModel role1 = realm1.getRole("role1");
|
||||
currentSession.users().grantToAllUsers(realm1, role1);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll2) -> {
|
||||
KeycloakSession currentSession = sesGrantToAll2;
|
||||
RealmModel realm1 = currentSession.realms().getRealmByName("realm1");
|
||||
|
||||
RoleModel role1 = realm1.getRole("role1");
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm1);
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm1);
|
||||
Assert.assertTrue(user1.hasRole(role1));
|
||||
Assert.assertTrue(user2.hasRole(role1));
|
||||
|
||||
RealmModel realm2 = currentSession.realms().getRealmByName("realm2");
|
||||
UserModel realm2User1 = currentSession.users().getUserByUsername("user1", realm2);
|
||||
Assert.assertFalse(realm2User1.hasRole(role1));
|
||||
|
||||
currentSession.realms().removeRealm(realm1.getId());
|
||||
currentSession.realms().removeRealm(realm2.getId());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testUserNotBefore(KeycloakSession session) throws Exception {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUserNotBefore1) -> {
|
||||
KeycloakSession currentSession = sesUserNotBefore1;
|
||||
RealmModel realm = currentSession.realms().createRealm("original");
|
||||
|
||||
UserModel user1 = currentSession.users().addUser(realm, "user1");
|
||||
currentSession.users().setNotBeforeForUser(realm, user1, 10);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUserNotBefore2) -> {
|
||||
KeycloakSession currentSession = sesUserNotBefore2;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
int notBefore = currentSession.users().getNotBeforeOfUser(realm, user1);
|
||||
Assert.assertEquals(10, notBefore);
|
||||
|
||||
// Try to update
|
||||
currentSession.users().setNotBeforeForUser(realm, user1, 20);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUserNotBefore3) -> {
|
||||
KeycloakSession currentSession = sesUserNotBefore3;
|
||||
RealmModel realm = currentSession.realms().getRealmByName("original");
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
int notBefore = currentSession.users().getNotBeforeOfUser(realm, user1);
|
||||
Assert.assertEquals(20, notBefore);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,611 @@
|
|||
/*
|
||||
* 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 org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.*;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserSessionPersisterProviderTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, UserSessionPersisterProvider.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
testingClient.server().run(session -> {
|
||||
initStuff(session);
|
||||
});
|
||||
}
|
||||
|
||||
public static void initStuff(KeycloakSession session) {
|
||||
RealmModel realm = session.realms().getRealm("test");
|
||||
session.users().addUser(realm, "user1").setEmail("user1@localhost");
|
||||
session.users().addUser(realm, "user2").setEmail("user2@localhost");
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealm("test");
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm, user1);
|
||||
}
|
||||
if (user2 != null) {
|
||||
um.removeUser(realm, user2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testPersistenceWithLoad(KeycloakSession session) {
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[][] origSessions = new UserSessionModel[1][1];
|
||||
final UserSessionModel[] userSession = new UserSessionModel[1];
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionWL) -> {
|
||||
// Create some sessions in infinispan
|
||||
origSessions[0] = createSessions(sessionWL);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionWL22) -> {
|
||||
// Persist 3 created userSessions and clientSessions as offline
|
||||
RealmModel realm = sessionWL22.realms().getRealm("test");
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
List<UserSessionModel> userSessions = sessionWL22.sessions().getUserSessions(realm, testApp);
|
||||
for (UserSessionModel userSessionLooper : userSessions) {
|
||||
persistUserSession(sessionWL22, userSessionLooper, true);
|
||||
}
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionWL2) -> {
|
||||
// Persist 1 online session
|
||||
RealmModel realm = sessionWL2.realms().getRealm("test");
|
||||
userSession[0] = sessionWL2.sessions().getUserSession(realm, origSessions[0][0].getId());
|
||||
persistUserSession(sessionWL2, userSession[0], false);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionWL3) -> {// Assert online session
|
||||
RealmModel realm = sessionWL3.realms().getRealm("test");
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(sessionWL3, false, 1, 1, 1);
|
||||
UserSessionProviderTest.assertSession(loadedSessions.get(0), sessionWL3.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionWL4) -> {
|
||||
// Assert offline sessions
|
||||
RealmModel realm = sessionWL4.realms().getRealm("test");
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(sessionWL4, true, 2, 2, 3);
|
||||
UserSessionProviderTest.assertSessions(loadedSessions, origSessions[0]);
|
||||
|
||||
assertSessionLoaded(loadedSessions, origSessions[0][0].getId(), sessionWL4.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party");
|
||||
assertSessionLoaded(loadedSessions, origSessions[0][1].getId(), sessionWL4.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app");
|
||||
assertSessionLoaded(loadedSessions, origSessions[0][2].getId(), sessionWL4.users().getUserByUsername("user2", realm), "127.0.0.3", started, started, "test-app");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testUpdateAndRemove(KeycloakSession session) {
|
||||
int started = Time.currentTime();
|
||||
|
||||
AtomicReference<UserSessionModel[]> origSessionsAt = new AtomicReference<>();
|
||||
AtomicReference<List<UserSessionModel>> loadedSessionsAt = new AtomicReference<>();
|
||||
|
||||
AtomicReference<UserSessionModel> userSessionAt = new AtomicReference<>();
|
||||
AtomicReference<UserSessionModel> persistedSessionAt = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateRemove1) -> {
|
||||
KeycloakSession currentSession = sesUpdateRemove1;
|
||||
|
||||
// Create some sessions in infinispan
|
||||
UserSessionModel[] origSessions = createSessions(currentSession);
|
||||
origSessionsAt.set(origSessions);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateRemove2) -> {
|
||||
KeycloakSession currentSession = sesUpdateRemove2;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
UserSessionModel[] origSessions = origSessionsAt.get();
|
||||
|
||||
// Persist 1 offline session
|
||||
UserSessionModel userSession = currentSession.sessions().getUserSession(realm, origSessions[1].getId());
|
||||
userSessionAt.set(userSession);
|
||||
|
||||
persistUserSession(currentSession, userSession, true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateRemove3) -> {
|
||||
KeycloakSession currentSession = sesUpdateRemove3;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
UserSessionPersisterProvider persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
// Load offline session
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1);
|
||||
loadedSessionsAt.set(loadedSessions);
|
||||
|
||||
UserSessionModel persistedSession = loadedSessions.get(0);
|
||||
persistedSessionAt.set(persistedSession);
|
||||
|
||||
UserSessionProviderTest.assertSession(persistedSession, currentSession.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app");
|
||||
|
||||
// create new clientSession
|
||||
AuthenticatedClientSessionModel clientSession = createClientSession(currentSession, realm.getClientByClientId("third-party"), currentSession.sessions().getUserSession(realm, persistedSession.getId()),
|
||||
"http://redirect", "state");
|
||||
persister.createClientSession(clientSession, true);
|
||||
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateRemove4) -> {
|
||||
KeycloakSession currentSession = sesUpdateRemove4;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
UserSessionPersisterProvider persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
UserSessionModel userSession = userSessionAt.get();
|
||||
|
||||
// Remove clientSession
|
||||
persister.removeClientSession(userSession.getId(), realm.getClientByClientId("third-party").getId(), true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateRemove5) -> {
|
||||
KeycloakSession currentSession = sesUpdateRemove5;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
UserSessionPersisterProvider persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
List<UserSessionModel> loadedSessions = loadedSessionsAt.get();
|
||||
UserSessionModel persistedSession = persistedSessionAt.get();
|
||||
|
||||
// Assert clientSession removed
|
||||
loadedSessions = loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1);
|
||||
persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, currentSession.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app");
|
||||
|
||||
// Remove userSession
|
||||
persister.removeUserSession(persistedSession.getId(), true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesUpdateRemove6) -> {
|
||||
KeycloakSession currentSession = sesUpdateRemove6;
|
||||
// Assert nothing found
|
||||
loadPersistedSessionsPaginated(currentSession, true, 10, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOnRealmRemoved(KeycloakSession session) {
|
||||
AtomicReference<String> userSessionID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR1) -> {
|
||||
KeycloakSession currentSession = sessionRR1;
|
||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||
|
||||
fooRealm.addClient("foo-app");
|
||||
currentSession.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = currentSession.sessions().createUserSession(fooRealm, currentSession.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
userSessionID.set(userSession.getId());
|
||||
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR2) -> {
|
||||
KeycloakSession currentSession = sessionRR2;
|
||||
|
||||
// Persist offline session
|
||||
RealmModel fooRealm = currentSession.realms().getRealm("foo");
|
||||
UserSessionModel userSession = currentSession.sessions().getUserSession(fooRealm, userSessionID.get());
|
||||
persistUserSession(currentSession, userSession, true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR3) -> {
|
||||
KeycloakSession currentSession = sessionRR3;
|
||||
|
||||
// Assert session was persisted
|
||||
loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1);
|
||||
|
||||
// Remove realm
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR4) -> {
|
||||
KeycloakSession currentSession = sessionRR4;
|
||||
|
||||
// Assert nothing loaded
|
||||
loadPersistedSessionsPaginated(currentSession, true, 10, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOnClientRemoved(KeycloakSession session) {
|
||||
int started = Time.currentTime();
|
||||
AtomicReference<String> userSessionID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR1) -> {
|
||||
KeycloakSession currentSession = sessionCR1;
|
||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||
|
||||
fooRealm.addClient("foo-app");
|
||||
fooRealm.addClient("bar-app");
|
||||
currentSession.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = currentSession.sessions().createUserSession(fooRealm, currentSession.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
userSessionID.set(userSession.getId());
|
||||
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("bar-app"), userSession, "http://redirect", "state");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR2) -> {
|
||||
KeycloakSession currentSession = sessionCR2;
|
||||
RealmModel fooRealm = currentSession.realms().getRealm("foo");
|
||||
|
||||
// Persist offline session
|
||||
UserSessionModel userSession = currentSession.sessions().getUserSession(fooRealm, userSessionID.get());
|
||||
persistUserSession(currentSession, userSession, true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR3) -> {
|
||||
KeycloakSession currentSession = sessionCR3;
|
||||
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert session was persisted with both clientSessions
|
||||
UserSessionModel persistedSession = loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1).get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, currentSession.users().getUserByUsername("user3", fooRealm), "127.0.0.1", started, started, "foo-app", "bar-app");
|
||||
|
||||
// Remove foo-app client
|
||||
ClientModel client = fooRealm.getClientByClientId("foo-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR4) -> {
|
||||
KeycloakSession currentSession = sessionCR4;
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert just one bar-app clientSession persisted now
|
||||
UserSessionModel persistedSession = loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1).get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, currentSession.users().getUserByUsername("user3", fooRealm), "127.0.0.1", started, started, "bar-app");
|
||||
|
||||
// Remove bar-app client
|
||||
ClientModel client = fooRealm.getClientByClientId("bar-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR5) -> {
|
||||
KeycloakSession currentSession = sessionCR5;
|
||||
|
||||
// Assert loading still works - last userSession is still there, but no clientSession on it
|
||||
loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1);
|
||||
|
||||
// Cleanup
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOnUserRemoved(KeycloakSession session) {
|
||||
int started = Time.currentTime();
|
||||
AtomicReference<UserSessionModel[]> origSessionsAt = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionOR1) -> {
|
||||
KeycloakSession currentSession = sessionOR1;
|
||||
|
||||
// Create some sessions in infinispan
|
||||
UserSessionModel[] origSessions = createSessions(currentSession);
|
||||
origSessionsAt.set(origSessions);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionOR2) -> {
|
||||
KeycloakSession currentSession = sessionOR2;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
UserSessionModel[] origSessions = origSessionsAt.get();
|
||||
|
||||
// Persist 2 offline sessions of 2 users
|
||||
UserSessionModel userSession1 = currentSession.sessions().getUserSession(realm, origSessions[1].getId());
|
||||
UserSessionModel userSession2 = currentSession.sessions().getUserSession(realm, origSessions[2].getId());
|
||||
persistUserSession(currentSession, userSession1, true);
|
||||
persistUserSession(currentSession, userSession2, true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionOR3) -> {
|
||||
KeycloakSession currentSession = sessionOR3;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
// Load offline sessions
|
||||
loadPersistedSessionsPaginated(currentSession, true, 10, 1, 2);
|
||||
|
||||
// Properly delete user and assert his offlineSession removed
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
new UserManager(currentSession).removeUser(realm, user1);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionOR4) -> {
|
||||
KeycloakSession currentSession = sessionOR4;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
UserSessionPersisterProvider persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
Assert.assertEquals(1, persister.getUserSessionsCount(true));
|
||||
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1);
|
||||
UserSessionModel persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, currentSession.users().getUserByUsername("user2", realm), "127.0.0.3", started, started, "test-app");
|
||||
|
||||
// KEYCLOAK-2431 Assert that userSessionPersister is resistent even to situation, when users are deleted "directly".
|
||||
// No exception will happen. However session will be still there
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm);
|
||||
currentSession.users().removeUser(realm, user2);
|
||||
|
||||
loadedSessions = loadPersistedSessionsPaginated(currentSession, true, 10, 1, 1);
|
||||
|
||||
// Cleanup
|
||||
UserSessionModel userSession = loadedSessions.get(0);
|
||||
currentSession.sessions().removeUserSession(realm, userSession);
|
||||
persister.removeUserSession(userSession.getId(), userSession.isOffline());
|
||||
});
|
||||
}
|
||||
|
||||
// KEYCLOAK-1999
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testNoSessions(KeycloakSession session) {
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionNS) -> {
|
||||
UserSessionPersisterProvider persister = sessionNS.getProvider(UserSessionPersisterProvider.class);
|
||||
List<UserSessionModel> sessions = persister.loadUserSessions(0, 1, true, 0, "abc");
|
||||
Assert.assertEquals(0, sessions.size());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testMoreSessions(KeycloakSession session) {
|
||||
AtomicReference<List<UserSessionModel>> userSessionsAt = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionMS1) -> {
|
||||
KeycloakSession currentSession = sessionMS1;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
// Create 10 userSessions - each having 1 clientSession
|
||||
List<UserSessionModel> userSessions = new ArrayList<>();
|
||||
UserModel user = currentSession.users().getUserByUsername("user1", realm);
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
// Having different offsets for each session (to ensure that lastSessionRefresh is also different)
|
||||
Time.setOffset(i);
|
||||
|
||||
UserSessionModel userSession = currentSession.sessions().createUserSession(realm, user, "user1", "127.0.0.1", "form", true, null, null);
|
||||
createClientSession(currentSession, realm.getClientByClientId("test-app"), userSession, "http://redirect", "state");
|
||||
userSessions.add(userSession);
|
||||
}
|
||||
|
||||
userSessionsAt.set(userSessions);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionMS2) -> {
|
||||
KeycloakSession currentSession = sessionMS2;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
List<UserSessionModel> userSessions = userSessionsAt.get();
|
||||
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
UserSessionModel userSession2 = currentSession.sessions().getUserSession(realm, userSession.getId());
|
||||
persistUserSession(currentSession, userSession2, true);
|
||||
}
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionMS3) -> {
|
||||
KeycloakSession currentSession = sessionMS3;
|
||||
RealmModel realm = currentSession.realms().getRealm("test");
|
||||
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(currentSession, true, 2, 10, 20);
|
||||
UserModel user = currentSession.users().getUserByUsername("user1", realm);
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
|
||||
for (UserSessionModel loadedSession : loadedSessions) {
|
||||
assertEquals(user.getId(), loadedSession.getUser().getId());
|
||||
assertEquals("127.0.0.1", loadedSession.getIpAddress());
|
||||
assertEquals(user.getUsername(), loadedSession.getLoginUsername());
|
||||
|
||||
assertEquals(1, loadedSession.getAuthenticatedClientSessions().size());
|
||||
assertTrue(loadedSession.getAuthenticatedClientSessions().containsKey(testApp.getId()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testExpiredSessions(KeycloakSession session) {
|
||||
UserSessionModel[][] origSessions = {new UserSessionModel[1]};
|
||||
int started = Time.currentTime();
|
||||
final UserSessionModel[] userSession1 = {null};
|
||||
final UserSessionModel[] userSession2 = {null};
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionES) -> {
|
||||
// Create some sessions in infinispan
|
||||
UserSessionPersisterProvider persister = sessionES.getProvider(UserSessionPersisterProvider.class);
|
||||
origSessions[0] = createSessions(sessionES);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionES2) -> {
|
||||
// Persist 2 offline sessions of 2 users
|
||||
RealmModel realm = sessionES2.realms().getRealm("test");
|
||||
UserSessionPersisterProvider persister = sessionES2.getProvider(UserSessionPersisterProvider.class);
|
||||
userSession1[0] = sessionES2.sessions().getUserSession(realm, origSessions[0][1].getId());
|
||||
userSession2[0] = sessionES2.sessions().getUserSession(realm, origSessions[0][2].getId());
|
||||
persistUserSession(sessionES2, userSession1[0], true);
|
||||
persistUserSession(sessionES2, userSession2[0], true);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionES3) -> {
|
||||
// Update one of the sessions with lastSessionRefresh of 20 days ahead
|
||||
int lastSessionRefresh = Time.currentTime() + 1728000;
|
||||
RealmModel realm = sessionES3.realms().getRealm("test");
|
||||
UserSessionPersisterProvider persister = sessionES3.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
persister.updateLastSessionRefreshes(realm, lastSessionRefresh, Collections.singleton(userSession1[0].getId()), true);
|
||||
|
||||
// Increase time offset - 40 days
|
||||
Time.setOffset(3456000);
|
||||
try {
|
||||
// Run expiration thread
|
||||
persister.removeExpired(realm);
|
||||
|
||||
// Test the updated session is still in persister. Not updated session is not there anymore
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(sessionES3, true, 10, 1, 1);
|
||||
UserSessionModel persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, sessionES3.users().getUserByUsername("user1", realm), "127.0.0.2", started, lastSessionRefresh, "test-app");
|
||||
|
||||
} finally {
|
||||
// Cleanup
|
||||
Time.setOffset(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private AuthenticatedClientSessionModel createClientSession(KeycloakSession session, ClientModel client, UserSessionModel userSession, String redirect, String state) {
|
||||
RealmModel realm = session.realms().getRealm("test");
|
||||
AuthenticatedClientSessionModel clientSession = session.sessions().createClientSession(realm, client, userSession);
|
||||
clientSession.setRedirectUri(redirect);
|
||||
if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
private UserSessionModel[] createSessions(KeycloakSession session) {
|
||||
RealmModel realm = session.realms().getRealm("test");
|
||||
UserSessionModel[] sessions = new UserSessionModel[3];
|
||||
sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true, null, null);
|
||||
|
||||
createClientSession(session, realm.getClientByClientId("test-app"), sessions[0], "http://redirect", "state");
|
||||
createClientSession(session, realm.getClientByClientId("third-party"), sessions[0], "http://redirect", "state");
|
||||
|
||||
sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true, null, null);
|
||||
createClientSession(session, realm.getClientByClientId("test-app"), sessions[1], "http://redirect", "state");
|
||||
|
||||
sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true, null, null);
|
||||
createClientSession(session, realm.getClientByClientId("test-app"), sessions[2], "http://redirect", "state");
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private void persistUserSession(KeycloakSession session, UserSessionModel userSession, boolean offline) {
|
||||
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
persister.createUserSession(userSession, offline);
|
||||
for (AuthenticatedClientSessionModel clientSession : userSession.getAuthenticatedClientSessions().values()) {
|
||||
persister.createClientSession(clientSession, offline);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertSessionLoaded(List<UserSessionModel> sessions, String id, UserModel user, String ipAddress, int started, int lastRefresh, String... clients) {
|
||||
for (UserSessionModel session : sessions) {
|
||||
if (session.getId().equals(id)) {
|
||||
UserSessionProviderTest.assertSession(session, user, ipAddress, started, lastRefresh, clients);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Assert.fail("Session with ID " + id + " not found in the list");
|
||||
}
|
||||
|
||||
private List<UserSessionModel> loadPersistedSessionsPaginated(KeycloakSession session, boolean offline, int sessionsPerPage, int expectedPageCount, int expectedSessionsCount) {
|
||||
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
int count = persister.getUserSessionsCount(offline);
|
||||
|
||||
int pageCount = 0;
|
||||
boolean next = true;
|
||||
List<UserSessionModel> result = new ArrayList<>();
|
||||
int lastCreatedOn = 0;
|
||||
String lastSessionId = "abc";
|
||||
|
||||
while (next) {
|
||||
List<UserSessionModel> sess = persister.loadUserSessions(0, sessionsPerPage, offline, lastCreatedOn, lastSessionId);
|
||||
|
||||
if (sess.size() < sessionsPerPage) {
|
||||
next = false;
|
||||
|
||||
// We had at least some session
|
||||
if (sess.size() > 0) {
|
||||
pageCount++;
|
||||
}
|
||||
} else {
|
||||
pageCount++;
|
||||
|
||||
UserSessionModel lastSession = sess.get(sess.size() - 1);
|
||||
lastCreatedOn = lastSession.getStarted();
|
||||
lastSessionId = lastSession.getId();
|
||||
}
|
||||
|
||||
result.addAll(sess);
|
||||
}
|
||||
|
||||
Assert.assertEquals(expectedPageCount, pageCount);
|
||||
Assert.assertEquals(expectedSessionsCount, result.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,636 @@
|
|||
/*
|
||||
* 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 org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.managers.UserSessionManager;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserSessionProviderOfflineTest extends AbstractTestRealmKeycloakTest {
|
||||
private static KeycloakSession currentSession;
|
||||
private static RealmModel realm;
|
||||
private static UserSessionManager sessionManager;
|
||||
private static UserSessionPersisterProvider persister;
|
||||
|
||||
@Deployment
|
||||
@TargetsContainer(AUTH_SERVER_CURRENT)
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class, UserSessionProviderOfflineTest.class)
|
||||
.addPackages(true,
|
||||
"org.keycloak.testsuite",
|
||||
"org.keycloak.testsuite.model");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
testingClient.server().run(session -> {
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionBefore) -> {
|
||||
reloadState(sessionBefore, true);
|
||||
persister = sessionBefore.getProvider(UserSessionPersisterProvider.class);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm, user1);
|
||||
}
|
||||
if (user2 != null) {
|
||||
um.removeUser(realm, user2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOfflineSessionsCrud(KeycloakSession session) {
|
||||
Map<String, Set<String>> offlineSessions = new HashMap<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCrud) -> {
|
||||
// Create some online sessions in infinispan
|
||||
reloadState(sessionCrud);
|
||||
createSessions(sessionCrud);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCrud2) -> {
|
||||
currentSession = sessionCrud2;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
// Key is userSession ID, values are client UUIDS
|
||||
// Persist 3 created userSessions and clientSessions as offline
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
List<UserSessionModel> userSessions = currentSession.sessions().getUserSessions(realm, testApp);
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
offlineSessions.put(userSession.getId(), createOfflineSessionIncludeClientSessions(currentSession, userSession));
|
||||
}
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCrud3) -> {
|
||||
currentSession = sessionCrud3;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
// Assert all previously saved offline sessions found
|
||||
for (Map.Entry<String, Set<String>> entry : offlineSessions.entrySet()) {
|
||||
UserSessionModel offlineSession = sessionManager.findOfflineUserSession(realm, entry.getKey());
|
||||
Assert.assertNotNull(offlineSession);
|
||||
Assert.assertEquals(offlineSession.getAuthenticatedClientSessions().keySet(), entry.getValue());
|
||||
}
|
||||
|
||||
// Find clients with offline token
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
|
||||
Set<ClientModel> clients = sessionManager.findClientsWithOfflineToken(realm, user1);
|
||||
Assert.assertEquals(clients.size(), 2);
|
||||
for (ClientModel client : clients) {
|
||||
Assert.assertTrue(client.getClientId().equals("test-app") || client.getClientId().equals("third-party"));
|
||||
}
|
||||
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm);
|
||||
|
||||
clients = sessionManager.findClientsWithOfflineToken(realm, user2);
|
||||
Assert.assertEquals(clients.size(), 1);
|
||||
Assert.assertEquals("test-app", clients.iterator().next().getClientId());
|
||||
|
||||
// Test count
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
ClientModel thirdparty = realm.getClientByClientId("third-party");
|
||||
Assert.assertEquals(3, currentSession.sessions().getOfflineSessionsCount(realm, testApp));
|
||||
Assert.assertEquals(1, currentSession.sessions().getOfflineSessionsCount(realm, thirdparty));
|
||||
// Revoke "test-app" for user1
|
||||
sessionManager.revokeOfflineToken(user1, testApp);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCrud4) -> {
|
||||
currentSession = sessionCrud4;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
// Assert userSession revoked
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
ClientModel thirdparty = realm.getClientByClientId("third-party");
|
||||
|
||||
// Still 2 sessions. The count of sessions by client may not be accurate after revoke due the
|
||||
// performance optimizations (the "127.0.0.1" currentSession still has another client "thirdparty" in it)
|
||||
Assert.assertEquals(2, currentSession.sessions().getOfflineSessionsCount(realm, testApp));
|
||||
Assert.assertEquals(1, currentSession.sessions().getOfflineSessionsCount(realm, thirdparty));
|
||||
|
||||
List<UserSessionModel> thirdpartySessions = currentSession.sessions().getOfflineUserSessions(realm, thirdparty, 0, 10);
|
||||
Assert.assertEquals(1, thirdpartySessions.size());
|
||||
Assert.assertEquals("127.0.0.1", thirdpartySessions.get(0).getIpAddress());
|
||||
Assert.assertEquals("user1", thirdpartySessions.get(0).getUser().getUsername());
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = currentSession.users().getUserByUsername("user2", realm);
|
||||
|
||||
Set<ClientModel> clients = sessionManager.findClientsWithOfflineToken(realm, user1);
|
||||
Assert.assertEquals(1, clients.size());
|
||||
Assert.assertEquals("third-party", clients.iterator().next().getClientId());
|
||||
clients = sessionManager.findClientsWithOfflineToken(realm, user2);
|
||||
Assert.assertEquals(1, clients.size());
|
||||
Assert.assertEquals("test-app", clients.iterator().next().getClientId());
|
||||
|
||||
// Revoke the second currentSession for user1 too.
|
||||
sessionManager.revokeOfflineToken(user1, thirdparty);
|
||||
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCrud5) -> {
|
||||
currentSession = sessionCrud5;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
ClientModel thirdparty = realm.getClientByClientId("third-party");
|
||||
|
||||
// Accurate count now. All sessions of user1 cleared
|
||||
Assert.assertEquals(1, currentSession.sessions().getOfflineSessionsCount(realm, testApp));
|
||||
Assert.assertEquals(0, currentSession.sessions().getOfflineSessionsCount(realm, thirdparty));
|
||||
|
||||
List<UserSessionModel> testAppSessions = currentSession.sessions().getOfflineUserSessions(realm, testApp, 0, 10);
|
||||
|
||||
Assert.assertEquals(1, testAppSessions.size());
|
||||
Assert.assertEquals("127.0.0.3", testAppSessions.get(0).getIpAddress());
|
||||
Assert.assertEquals("user2", testAppSessions.get(0).getUser().getUsername());
|
||||
|
||||
UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
|
||||
|
||||
Set<ClientModel> clients = sessionManager.findClientsWithOfflineToken(realm, user1);
|
||||
Assert.assertEquals(0, clients.size());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOnRealmRemoved(KeycloakSession session) {
|
||||
AtomicReference<String> userSessionID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR1) -> {
|
||||
currentSession = sessionRR1;
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
currentSession.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = currentSession.sessions().createUserSession(fooRealm, currentSession.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
userSessionID.set(userSession.getId());
|
||||
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR2) -> {
|
||||
currentSession = sessionRR2;
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
|
||||
// Persist offline session
|
||||
RealmModel fooRealm = currentSession.realms().getRealm("foo");
|
||||
UserSessionModel userSession = currentSession.sessions().getUserSession(fooRealm, userSessionID.get());
|
||||
createOfflineSessionIncludeClientSessions(currentSession, userSession);
|
||||
|
||||
UserSessionModel offlineUserSession = sessionManager.findOfflineUserSession(fooRealm, userSession.getId());
|
||||
Assert.assertEquals(offlineUserSession.getAuthenticatedClientSessions().size(), 1);
|
||||
AuthenticatedClientSessionModel offlineClientSession = offlineUserSession.getAuthenticatedClientSessions().values().iterator().next();
|
||||
Assert.assertEquals("foo-app", offlineClientSession.getClient().getClientId());
|
||||
Assert.assertEquals("user3", offlineClientSession.getUserSession().getUser().getUsername());
|
||||
|
||||
// Remove realm
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR3) -> {
|
||||
currentSession = sessionRR3;
|
||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||
|
||||
fooRealm.addClient("foo-app");
|
||||
currentSession.users().addUser(fooRealm, "user3");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRR4) -> {
|
||||
currentSession = sessionRR4;
|
||||
RealmModel fooRealm = currentSession.realms().getRealm("foo");
|
||||
|
||||
Assert.assertEquals(0, currentSession.sessions().getOfflineSessionsCount(fooRealm, fooRealm.getClientByClientId("foo-app")));
|
||||
|
||||
// Cleanup
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOnClientRemoved(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR) -> {
|
||||
try {
|
||||
int started = Time.currentTime();
|
||||
AtomicReference<String> userSessionID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR1) -> {
|
||||
currentSession = sessionCR1;
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||
|
||||
fooRealm.addClient("foo-app");
|
||||
fooRealm.addClient("bar-app");
|
||||
currentSession.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = currentSession.sessions().createUserSession(fooRealm, currentSession.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
userSessionID.set(userSession.getId());
|
||||
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("bar-app"), userSession, "http://redirect", "state");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR2) -> {
|
||||
currentSession = sessionCR2;
|
||||
// Create offline currentSession
|
||||
RealmModel fooRealm = currentSession.realms().getRealm("foo");
|
||||
UserSessionModel userSession = currentSession.sessions().getUserSession(fooRealm, userSessionID.get());
|
||||
createOfflineSessionIncludeClientSessions(currentSession, userSession);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR3) -> {
|
||||
currentSession = sessionCR3;
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert currentSession was persisted with both clientSessions
|
||||
UserSessionModel offlineSession = currentSession.sessions().getOfflineUserSession(fooRealm, userSessionID.get());
|
||||
assertSession(offlineSession, currentSession.users().getUserByUsername("user3", fooRealm), "127.0.0.1", started, started, "foo-app", "bar-app");
|
||||
|
||||
// Remove foo-app client
|
||||
ClientModel client = fooRealm.getClientByClientId("foo-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR4) -> {
|
||||
currentSession = sessionCR4;
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert just one bar-app clientSession persisted now
|
||||
UserSessionModel offlineSession = currentSession.sessions().getOfflineUserSession(fooRealm, userSessionID.get());
|
||||
Assert.assertEquals(1, offlineSession.getAuthenticatedClientSessions().size());
|
||||
Assert.assertEquals("bar-app", offlineSession.getAuthenticatedClientSessions().values().iterator().next().getClient().getClientId());
|
||||
|
||||
// Remove bar-app client
|
||||
ClientModel client = fooRealm.getClientByClientId("bar-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCR5) -> {
|
||||
currentSession = sessionCR5;
|
||||
// Assert nothing loaded - userSession was removed as well because it was last userSession
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
UserSessionModel offlineSession = currentSession.sessions().getOfflineUserSession(fooRealm, userSessionID.get());
|
||||
Assert.assertEquals(0, offlineSession.getAuthenticatedClientSessions().size());
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTearDown) -> {
|
||||
currentSession = sessionTearDown;
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
UserModel user3 = currentSession.users().getUserByUsername("user3", fooRealm);
|
||||
|
||||
// Remove user3
|
||||
new UserManager(currentSession).removeUser(fooRealm, user3);
|
||||
|
||||
// Cleanup
|
||||
realmMgr = new RealmManager(currentSession);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testOnUserRemoved(KeycloakSession session) {
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUR) -> {
|
||||
try {
|
||||
int started = Time.currentTime();
|
||||
AtomicReference<String> userSessionID = new AtomicReference<>();
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUR1) -> {
|
||||
currentSession = sessionUR1;
|
||||
RealmModel fooRealm = currentSession.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
currentSession.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = currentSession.sessions().createUserSession(fooRealm, currentSession.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
userSessionID.set(userSession.getId());
|
||||
|
||||
createClientSession(currentSession, fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUR2) -> {
|
||||
currentSession = sessionUR2;
|
||||
|
||||
// Create offline session
|
||||
RealmModel fooRealm = currentSession.realms().getRealm("foo");
|
||||
UserSessionModel userSession = currentSession.sessions().getUserSession(fooRealm, userSessionID.get());
|
||||
createOfflineSessionIncludeClientSessions(currentSession, userSession);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUR3) -> {
|
||||
currentSession = sessionUR3;
|
||||
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
UserModel user3 = currentSession.users().getUserByUsername("user3", fooRealm);
|
||||
|
||||
// Assert session was persisted with both clientSessions
|
||||
UserSessionModel offlineSession = currentSession.sessions().getOfflineUserSession(fooRealm, userSessionID.get());
|
||||
assertSession(offlineSession, user3, "127.0.0.1", started, started, "foo-app");
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTearDown) -> {
|
||||
currentSession = sessionTearDown;
|
||||
|
||||
RealmManager realmMgr = new RealmManager(currentSession);
|
||||
RealmModel fooRealm = realmMgr.getRealm("foo");
|
||||
UserModel user3 = currentSession.users().getUserByUsername("user3", fooRealm);
|
||||
|
||||
// Remove user3
|
||||
new UserManager(currentSession).removeUser(fooRealm, user3);
|
||||
|
||||
// Cleanup
|
||||
realmMgr = new RealmManager(currentSession);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ModelTest
|
||||
public void testExpired(KeycloakSession session) {
|
||||
AtomicReference<UserSessionModel[]> origSessionsAt = new AtomicReference<>();
|
||||
|
||||
// Key is userSessionId, value is set of client UUIDS
|
||||
Map<String, Set<String>> offlineSessions = new HashMap<>();
|
||||
ClientModel[] testApp = new ClientModel[1];
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired1) -> {
|
||||
// Create some online sessions in infinispan
|
||||
currentSession = sessionExpired1;
|
||||
reloadState(currentSession);
|
||||
UserSessionModel[] origSessions = createSessions(currentSession);
|
||||
origSessionsAt.set(origSessions);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired2) -> {
|
||||
currentSession = sessionExpired2;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
// Persist 3 created userSessions and clientSessions as offline
|
||||
testApp[0] = realm.getClientByClientId("test-app");
|
||||
List<UserSessionModel> userSessions = currentSession.sessions().getUserSessions(realm, testApp[0]);
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
offlineSessions.put(userSession.getId(), createOfflineSessionIncludeClientSessions(currentSession, userSession));
|
||||
}
|
||||
|
||||
// Assert all previously saved offline sessions found
|
||||
for (Map.Entry<String, Set<String>> entry : offlineSessions.entrySet()) {
|
||||
UserSessionModel foundSession = sessionManager.findOfflineUserSession(realm, entry.getKey());
|
||||
Assert.assertEquals(foundSession.getAuthenticatedClientSessions().keySet(), entry.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired3) -> {
|
||||
currentSession = sessionExpired3;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
UserSessionModel[] origSessions = origSessionsAt.get();
|
||||
|
||||
UserSessionModel session0 = currentSession.sessions().getOfflineUserSession(realm, origSessions[0].getId());
|
||||
Assert.assertNotNull(session0);
|
||||
|
||||
// sessions are in persister too
|
||||
Assert.assertEquals(3, persister.getUserSessionsCount(true));
|
||||
|
||||
Time.setOffset(300);
|
||||
|
||||
// Set lastSessionRefresh to currentSession[0] to 0
|
||||
session0.setLastSessionRefresh(Time.currentTime());
|
||||
});
|
||||
|
||||
try {
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired4) -> {
|
||||
currentSession = sessionExpired4;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
UserSessionModel[] origSessions = origSessionsAt.get();
|
||||
// Increase timeOffset - 20 days
|
||||
Time.setOffset(1728000);
|
||||
|
||||
UserSessionModel session0 = currentSession.sessions().getOfflineUserSession(realm, origSessions[0].getId());
|
||||
session0.setLastSessionRefresh(Time.currentTime());
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired5) -> {
|
||||
currentSession = sessionExpired5;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
// Increase timeOffset - 40 days
|
||||
Time.setOffset(3456000);
|
||||
|
||||
// Expire and ensure that all sessions despite session0 were removed
|
||||
currentSession.sessions().removeExpired(realm);
|
||||
persister.removeExpired(realm);
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired6) -> {
|
||||
currentSession = sessionExpired6;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
UserSessionModel[] origSessions = origSessionsAt.get();
|
||||
|
||||
// assert session0 is the only session found
|
||||
Assert.assertNotNull(currentSession.sessions().getOfflineUserSession(realm, origSessions[0].getId()));
|
||||
Assert.assertNull(currentSession.sessions().getOfflineUserSession(realm, origSessions[1].getId()));
|
||||
Assert.assertNull(currentSession.sessions().getOfflineUserSession(realm, origSessions[2].getId()));
|
||||
|
||||
Assert.assertEquals(1, persister.getUserSessionsCount(true));
|
||||
|
||||
// Expire everything and assert nothing found
|
||||
Time.setOffset(6000000);
|
||||
|
||||
currentSession.sessions().removeExpired(realm);
|
||||
persister.removeExpired(realm);
|
||||
|
||||
});
|
||||
|
||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpired7) -> {
|
||||
currentSession = sessionExpired7;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
|
||||
for (String userSessionId : offlineSessions.keySet()) {
|
||||
Assert.assertNull(sessionManager.findOfflineUserSession(realm, userSessionId));
|
||||
}
|
||||
Assert.assertEquals(0, persister.getUserSessionsCount(true));
|
||||
});
|
||||
|
||||
} finally {
|
||||
Time.setOffset(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Set<String> createOfflineSessionIncludeClientSessions(KeycloakSession session, UserSessionModel
|
||||
userSession) {
|
||||
Set<String> offlineSessions = new HashSet<>();
|
||||
UserSessionManager localManager = new UserSessionManager(session);
|
||||
for (AuthenticatedClientSessionModel clientSession : userSession.getAuthenticatedClientSessions().values()) {
|
||||
localManager.createOrUpdateOfflineSession(clientSession, userSession);
|
||||
offlineSessions.add(clientSession.getClient().getId());
|
||||
}
|
||||
|
||||
return offlineSessions;
|
||||
}
|
||||
|
||||
public static void assertSession(UserSessionModel session, UserModel user, String ipAddress, int started,
|
||||
int lastRefresh, String... clients) {
|
||||
assertEquals(user.getId(), session.getUser().getId());
|
||||
assertEquals(ipAddress, session.getIpAddress());
|
||||
assertEquals(user.getUsername(), session.getLoginUsername());
|
||||
assertEquals("form", session.getAuthMethod());
|
||||
assertTrue(session.isRememberMe());
|
||||
assertTrue((session.getStarted() >= started - 1) && (session.getStarted() <= started + 1));
|
||||
assertTrue((session.getLastSessionRefresh() >= lastRefresh - 1) && (session.getLastSessionRefresh() <= lastRefresh + 1));
|
||||
|
||||
String[] actualClients = new String[session.getAuthenticatedClientSessions().size()];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, AuthenticatedClientSessionModel> entry : session.getAuthenticatedClientSessions().entrySet()) {
|
||||
String clientUUID = entry.getKey();
|
||||
AuthenticatedClientSessionModel clientSession = entry.getValue();
|
||||
Assert.assertEquals(clientUUID, clientSession.getClient().getId());
|
||||
actualClients[i] = clientSession.getClient().getClientId();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static AuthenticatedClientSessionModel createClientSession(KeycloakSession sessionParam, ClientModel
|
||||
client, UserSessionModel userSession, String redirect, String state) {
|
||||
AuthenticatedClientSessionModel clientSession = sessionParam.sessions().createClientSession(client.getRealm(), client, userSession);
|
||||
clientSession.setRedirectUri(redirect);
|
||||
if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
private static UserSessionModel[] createSessions(KeycloakSession session) {
|
||||
UserSessionModel[] sessions = new UserSessionModel[3];
|
||||
sessions[0] = session.sessions().createUserSession(realm, currentSession.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true, null, null);
|
||||
|
||||
Set<String> roles = new HashSet<String>();
|
||||
roles.add("one");
|
||||
roles.add("two");
|
||||
|
||||
Set<String> protocolMappers = new HashSet<String>();
|
||||
protocolMappers.add("mapper-one");
|
||||
protocolMappers.add("mapper-two");
|
||||
|
||||
createClientSession(session, realm.getClientByClientId("test-app"), sessions[0], "http://redirect", "state");
|
||||
createClientSession(session, realm.getClientByClientId("third-party"), sessions[0], "http://redirect", "state");
|
||||
|
||||
sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true, null, null);
|
||||
createClientSession(session, realm.getClientByClientId("test-app"), sessions[1], "http://redirect", "state");
|
||||
|
||||
sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true, null, null);
|
||||
createClientSession(session, realm.getClientByClientId("test-app"), sessions[2], "http://redirect", "state");
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public static void reloadState(KeycloakSession session) {
|
||||
reloadState(session, false);
|
||||
}
|
||||
|
||||
public static void reloadState(KeycloakSession session, Boolean initialConfig) {
|
||||
currentSession = session;
|
||||
realm = currentSession.realms().getRealm("test");
|
||||
if (initialConfig) {
|
||||
currentSession.users().addUser(realm, "user1").setEmail("user1@localhost");
|
||||
currentSession.users().addUser(realm, "user2").setEmail("user2@localhost");
|
||||
}
|
||||
sessionManager = new UserSessionManager(currentSession);
|
||||
persister = currentSession.getProvider(UserSessionPersisterProvider.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class CompositeRolesModelTest extends AbstractModelTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void before() throws Exception {
|
||||
super.before();
|
||||
RealmManager manager = realmManager;
|
||||
RealmRepresentation rep = AbstractModelTest.loadJson("model/testcomposites.json");
|
||||
rep.setId("TestComposites");
|
||||
manager.importRealm(rep);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoClientID() throws IOException {
|
||||
|
||||
RealmManager manager = realmManager;
|
||||
RealmRepresentation rep = AbstractModelTest.loadJson("model/testrealm-noclient-id.json");
|
||||
rep.setId("TestNoClientID");
|
||||
expectedException.expect(RuntimeException.class);
|
||||
expectedException.expectMessage("Unknown client specification in scope mappings: some-client");
|
||||
manager.importRealm(rep);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComposites() {
|
||||
Set<RoleModel> requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_USER");
|
||||
Assert.assertEquals(5, requestedRoles.size());
|
||||
assertContains("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_ROLE", requestedRoles);
|
||||
assertContains("APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_CHILD", requestedRoles);
|
||||
assertContains("APP_COMPOSITE_APPLICATION", "APP_ROLE_2", requestedRoles);
|
||||
assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
|
||||
assertContains("realm", "REALM_ROLE_1", requestedRoles);
|
||||
|
||||
requestedRoles = getRequestedRoles("APP_COMPOSITE_APPLICATION", "REALM_APP_COMPOSITE_USER");
|
||||
Assert.assertEquals(4, requestedRoles.size());
|
||||
assertContains("APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles);
|
||||
|
||||
requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
|
||||
Assert.assertEquals(1, requestedRoles.size());
|
||||
assertContains("realm", "REALM_COMPOSITE_1", requestedRoles);
|
||||
|
||||
requestedRoles = getRequestedRoles("REALM_COMPOSITE_2_APPLICATION", "REALM_COMPOSITE_1_USER");
|
||||
Assert.assertEquals(3, requestedRoles.size());
|
||||
assertContains("realm", "REALM_COMPOSITE_1", requestedRoles);
|
||||
assertContains("realm", "REALM_COMPOSITE_CHILD", requestedRoles);
|
||||
assertContains("realm", "REALM_ROLE_4", requestedRoles);
|
||||
|
||||
requestedRoles = getRequestedRoles("REALM_ROLE_1_APPLICATION", "REALM_COMPOSITE_1_USER");
|
||||
Assert.assertEquals(1, requestedRoles.size());
|
||||
assertContains("realm", "REALM_ROLE_1", requestedRoles);
|
||||
|
||||
requestedRoles = getRequestedRoles("REALM_COMPOSITE_1_APPLICATION", "REALM_ROLE_1_USER");
|
||||
Assert.assertEquals(1, requestedRoles.size());
|
||||
assertContains("realm", "REALM_ROLE_1", requestedRoles);
|
||||
}
|
||||
|
||||
// Same algorithm as in TokenManager.createAccessCode
|
||||
private Set<RoleModel> getRequestedRoles(String applicationName, String username) {
|
||||
Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
|
||||
|
||||
RealmModel realm = realmManager.getRealm("TestComposites");
|
||||
UserModel user = realmManager.getSession().users().getUserByUsername(username, realm);
|
||||
ClientModel application = realm.getClientByClientId(applicationName);
|
||||
|
||||
Set<RoleModel> roleMappings = user.getRoleMappings();
|
||||
Set<RoleModel> scopeMappings = application.getScopeMappings();
|
||||
Set<RoleModel> appRoles = application.getRoles();
|
||||
if (appRoles != null) scopeMappings.addAll(appRoles);
|
||||
|
||||
for (RoleModel role : roleMappings) {
|
||||
if (role.getContainer().equals(application)) requestedRoles.add(role);
|
||||
for (RoleModel desiredRole : scopeMappings) {
|
||||
Set<RoleModel> visited = new HashSet<RoleModel>();
|
||||
applyScope(role, desiredRole, visited, requestedRoles);
|
||||
}
|
||||
}
|
||||
|
||||
return requestedRoles;
|
||||
}
|
||||
|
||||
private static void applyScope(RoleModel role, RoleModel scope, Set<RoleModel> visited, Set<RoleModel> requested) {
|
||||
if (visited.contains(scope)) return;
|
||||
visited.add(scope);
|
||||
if (role.hasRole(scope)) {
|
||||
requested.add(scope);
|
||||
return;
|
||||
}
|
||||
if (!scope.isComposite()) return;
|
||||
|
||||
for (RoleModel contained : scope.getComposites()) {
|
||||
applyScope(role, contained, visited, requested);
|
||||
}
|
||||
}
|
||||
|
||||
private RoleModel getRole(String appName, String roleName) {
|
||||
RealmModel realm = realmManager.getRealm("TestComposites");
|
||||
if ("realm".equals(appName)) {
|
||||
return realm.getRole(roleName);
|
||||
} else {
|
||||
return realm.getClientByClientId(appName).getRole(roleName);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertContains(String appName, String roleName, Set<RoleModel> requestedRoles) {
|
||||
RoleModel expectedRole = getRole(appName, roleName);
|
||||
|
||||
Assert.assertTrue(requestedRoles.contains(expectedRole));
|
||||
|
||||
// Check if requestedRole has correct role container
|
||||
for (RoleModel role : requestedRoles) {
|
||||
if (role.equals(expectedRole)) {
|
||||
Assert.assertEquals(role.getContainer(), expectedRole.getContainer());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,234 +0,0 @@
|
|||
/*
|
||||
* 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 org.jboss.logging.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.KeycloakSessionTask;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RealmProvider;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ConcurrentTransactionsTest extends AbstractModelTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ConcurrentTransactionsTest.class);
|
||||
|
||||
@Test
|
||||
public void persistClient() throws Exception {
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
KeycloakSession session = realmManager.getSession();
|
||||
|
||||
ClientModel client = session.realms().addClient(realm, "client");
|
||||
client.setSecret("old");
|
||||
|
||||
String clientDBId = client.getId();
|
||||
|
||||
final KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
commit();
|
||||
|
||||
final CountDownLatch transactionsCounter = new CountDownLatch(2);
|
||||
final CountDownLatch readLatch = new CountDownLatch(1);
|
||||
final CountDownLatch updateLatch = new CountDownLatch(1);
|
||||
|
||||
Thread thread1 = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||
|
||||
@Override
|
||||
public void run(KeycloakSession session) {
|
||||
try {
|
||||
// Wait until transaction in both threads started
|
||||
transactionsCounter.countDown();
|
||||
logger.info("transaction1 started");
|
||||
transactionsCounter.await();
|
||||
|
||||
// Read client
|
||||
RealmModel realm = session.realms().getRealmByName("original");
|
||||
ClientModel client = session.realms().getClientByClientId("client", realm);
|
||||
logger.info("transaction1: Read client finished");
|
||||
readLatch.countDown();
|
||||
|
||||
// Wait until thread2 updates client and commits
|
||||
updateLatch.await();
|
||||
logger.info("transaction1: Going to read client again");
|
||||
|
||||
client = session.realms().getClientByClientId("client", realm);
|
||||
logger.info("transaction1: secret: " + client.getSecret());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Thread thread2 = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||
|
||||
@Override
|
||||
public void run(KeycloakSession session) {
|
||||
try {
|
||||
// Wait until transaction in both threads started
|
||||
transactionsCounter.countDown();
|
||||
logger.info("transaction2 started");
|
||||
transactionsCounter.await();
|
||||
|
||||
|
||||
readLatch.await();
|
||||
logger.info("transaction2: Going to update client secret");
|
||||
|
||||
RealmModel realm = session.realms().getRealmByName("original");
|
||||
ClientModel client = session.realms().getClientByClientId("client", realm);
|
||||
client.setSecret("new");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
logger.info("transaction2: commited");
|
||||
updateLatch.countDown();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
|
||||
logger.info("after thread join");
|
||||
|
||||
commit();
|
||||
|
||||
session = realmManager.getSession();
|
||||
|
||||
realm = session.realms().getRealmByName("original");
|
||||
ClientModel clientFromCache = session.realms().getClientById(clientDBId, realm);
|
||||
ClientModel clientFromDB = session.getProvider(RealmProvider.class).getClientById(clientDBId, realm);
|
||||
|
||||
logger.info("SECRET FROM DB : " + clientFromDB.getSecret());
|
||||
logger.info("SECRET FROM CACHE : " + clientFromCache.getSecret());
|
||||
|
||||
Assert.assertEquals("new", clientFromDB.getSecret());
|
||||
Assert.assertEquals("new", clientFromCache.getSecret());
|
||||
}
|
||||
|
||||
|
||||
// KEYCLOAK-3296 , KEYCLOAK-3494
|
||||
@Test
|
||||
public void removeUserAttribute() throws Exception {
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
KeycloakSession session = realmManager.getSession();
|
||||
|
||||
UserModel john = session.users().addUser(realm, "john");
|
||||
john.setSingleAttribute("foo", "val1");
|
||||
|
||||
UserModel john2 = session.users().addUser(realm, "john2");
|
||||
john2.setAttribute("foo", Arrays.asList("val1", "val2"));
|
||||
|
||||
final KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
commit();
|
||||
|
||||
AtomicReference<Exception> reference = new AtomicReference<>();
|
||||
|
||||
final CountDownLatch readAttrLatch = new CountDownLatch(2);
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||
|
||||
@Override
|
||||
public void run(KeycloakSession session) {
|
||||
try {
|
||||
// Read user attribute
|
||||
RealmModel realm = session.realms().getRealmByName("original");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
String attrVal = john.getFirstAttribute("foo");
|
||||
|
||||
UserModel john2 = session.users().getUserByUsername("john2", realm);
|
||||
String attrVal2 = john2.getFirstAttribute("foo");
|
||||
|
||||
// Wait until it's read in both threads
|
||||
readAttrLatch.countDown();
|
||||
readAttrLatch.await();
|
||||
|
||||
// KEYCLOAK-3296 : Remove user attribute in both threads
|
||||
john.removeAttribute("foo");
|
||||
|
||||
// KEYCLOAK-3494 : Set single attribute in both threads
|
||||
john2.setSingleAttribute("foo", "bar");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} catch (Exception e) {
|
||||
reference.set(e);
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
readAttrLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Thread thread1 = new Thread(runnable);
|
||||
Thread thread2 = new Thread(runnable);
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
|
||||
logger.info("removeUserAttribute: after thread join");
|
||||
|
||||
commit();
|
||||
|
||||
if (reference.get() != null) {
|
||||
Assert.fail("Exception happened in some of threads. Details: " + reference.get().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class MultipleRealmsTest extends AbstractModelTest {
|
||||
|
||||
private RealmModel realm1;
|
||||
private RealmModel realm2;
|
||||
|
||||
@Before
|
||||
@Override
|
||||
public void before() throws Exception {
|
||||
super.before();
|
||||
realm1 = realmManager.createRealm("id1", "realm1");
|
||||
realm2 = realmManager.createRealm("id2", "realm2");
|
||||
|
||||
createObjects(realm1);
|
||||
createObjects(realm2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsers() {
|
||||
UserModel r1user1 = session.users().getUserByUsername("user1", realm1);
|
||||
UserModel r2user1 = session.users().getUserByUsername("user1", realm2);
|
||||
Assert.assertEquals(r1user1.getUsername(), r2user1.getUsername());
|
||||
Assert.assertNotEquals(r1user1.getId(), r2user1.getId());
|
||||
|
||||
// Test password
|
||||
session.userCredentialManager().updateCredential(realm1, r1user1, UserCredentialModel.password("pass1"));
|
||||
session.userCredentialManager().updateCredential(realm2, r2user1, UserCredentialModel.password("pass2"));
|
||||
|
||||
Assert.assertTrue(session.userCredentialManager().isValid(realm1, r1user1, UserCredentialModel.password("pass1")));
|
||||
Assert.assertFalse(session.userCredentialManager().isValid(realm1, r1user1, UserCredentialModel.password("pass2")));
|
||||
Assert.assertFalse(session.userCredentialManager().isValid(realm2, r2user1, UserCredentialModel.password("pass1")));
|
||||
Assert.assertTrue(session.userCredentialManager().isValid(realm2, r2user1, UserCredentialModel.password("pass2")));
|
||||
|
||||
// Test searching
|
||||
Assert.assertEquals(2, session.users().searchForUser("user", realm1).size());
|
||||
|
||||
commit();
|
||||
realm1 = model.getRealm("id1");
|
||||
realm2 = model.getRealm("id2");
|
||||
|
||||
session.users().removeUser(realm1, r1user1);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm1);
|
||||
session.users().removeUser(realm1, user2);
|
||||
Assert.assertEquals(0, session.users().searchForUser("user", realm1).size());
|
||||
Assert.assertEquals(2, session.users().searchForUser("user", realm2).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetById() {
|
||||
Assert.assertEquals(realm1, model.getRealm("id1"));
|
||||
Assert.assertEquals(realm1, model.getRealmByName("realm1"));
|
||||
Assert.assertEquals(realm2, model.getRealm("id2"));
|
||||
Assert.assertEquals(realm2, model.getRealmByName("realm2"));
|
||||
|
||||
ClientModel r1app1 = realm1.getClientByClientId("app1");
|
||||
ClientModel r1app2 = realm1.getClientByClientId("app2");
|
||||
ClientModel r2app1 = realm2.getClientByClientId("app1");
|
||||
ClientModel r2app2 = realm2.getClientByClientId("app2");
|
||||
|
||||
Assert.assertEquals(r1app1, realm1.getClientById(r1app1.getId()));
|
||||
Assert.assertNull(realm2.getClientById(r1app1.getId()));
|
||||
|
||||
ClientModel r2cl1 = realm2.getClientByClientId("cl1");
|
||||
Assert.assertEquals(r2cl1.getId(), realm2.getClientById(r2cl1.getId()).getId());
|
||||
Assert.assertNull(realm1.getClientByClientId(r2cl1.getId()));
|
||||
|
||||
RoleModel r1App1Role = r1app1.getRole("app1Role1");
|
||||
Assert.assertEquals(r1App1Role, realm1.getRoleById(r1App1Role.getId()));
|
||||
Assert.assertNull(realm2.getRoleById(r1App1Role.getId()));
|
||||
|
||||
RoleModel r2Role1 = realm2.getRole("role2");
|
||||
Assert.assertNull(realm1.getRoleById(r2Role1.getId()));
|
||||
Assert.assertEquals(r2Role1, realm2.getRoleById(r2Role1.getId()));
|
||||
}
|
||||
|
||||
private void createObjects(RealmModel realm) {
|
||||
ClientModel app1 = realm.addClient("app1");
|
||||
realm.addClient("app2");
|
||||
|
||||
realmManager.getSession().users().addUser(realm, "user1");
|
||||
realmManager.getSession().users().addUser(realm, "user2");
|
||||
|
||||
realm.addRole("role1");
|
||||
realm.addRole("role2");
|
||||
|
||||
app1.addRole("app1Role1");
|
||||
app1.addScopeMapping(realm.getRole("role1"));
|
||||
|
||||
realm.addClient("cl1");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.protocol.oidc.mappers.UserPropertyMapper;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserConsentModelTest extends AbstractModelTest {
|
||||
|
||||
private ComponentModel clientStorageComponent;
|
||||
|
||||
@Before
|
||||
public void setupEnv() {
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
|
||||
ClientModel fooClient = realm.addClient("foo-client");
|
||||
ClientModel barClient = realm.addClient("bar-client");
|
||||
|
||||
ClientScopeModel fooScope = realm.addClientScope("foo");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
ClientScopeModel barScope = realm.addClientScope("bar");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
UserModel john = session.users().addUser(realm, "john");
|
||||
UserModel mary = session.users().addUser(realm, "mary");
|
||||
|
||||
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
||||
johnFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
|
||||
|
||||
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
||||
johnBarGrant.addGrantedClientScope(barScope);
|
||||
|
||||
// Update should fail as grant doesn't yet exists
|
||||
try {
|
||||
realmManager.getSession().users().updateConsent(realm, john.getId(), johnBarGrant);
|
||||
Assert.fail("Not expected to end here");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
|
||||
|
||||
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
||||
maryFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
|
||||
|
||||
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
||||
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, "http://localhost:8081/*");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CONSENT, "true");
|
||||
clientStorage.setParentId(realm.getId());
|
||||
clientStorageComponent = realm.addComponentModel(clientStorage);
|
||||
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
Assert.assertNotNull(hardcodedClient);
|
||||
|
||||
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
|
||||
|
||||
|
||||
commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicConsentTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel johnBarConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId());
|
||||
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel maryConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
UserConsentModel maryHardcodedConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
||||
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllConsentTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john.getId());
|
||||
Assert.assertEquals(2, johnConsents.size());
|
||||
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(2, maryConsents.size());
|
||||
UserConsentModel maryConsent = maryConsents.get(0);
|
||||
UserConsentModel maryHardcodedConsent = maryConsents.get(1);
|
||||
if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) {
|
||||
maryConsent = maryConsents.get(1);
|
||||
maryHardcodedConsent = maryConsents.get(0);
|
||||
|
||||
}
|
||||
Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
|
||||
Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateWithClientScopeRemovalTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
||||
|
||||
// Remove foo protocol mapper from johnConsent
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
johnConsent.getGrantedClientScopes().remove(fooScope);
|
||||
|
||||
realmManager.getSession().users().updateConsent(realm, john.getId(), johnConsent);
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
fooClient = realm.getClientByClientId("foo-client");
|
||||
john = session.users().getUserByUsername("john", realm);
|
||||
johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void revokeTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
realmManager.getSession().users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
realmManager.getSession().users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
john = session.users().getUserByUsername("john", realm);
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId()));
|
||||
mary = session.users().getUserByUsername("mary", realm);
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteUserTest() {
|
||||
// Validate user deleted without any referential constraint errors
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
session.users().removeUser(realm, john);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
session.users().removeUser(realm, mary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteClientScopeTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
realm.removeClientScope(fooScope.getId());
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteClientTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
realm.removeClient(barClient.getId());
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
Assert.assertNull(realm.getClientByClientId("bar-client"));
|
||||
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteClientStorageTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
realm.removeComponent(clientStorageComponent);
|
||||
commit();
|
||||
|
||||
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
Assert.assertNull(hardcodedClient);
|
||||
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(1, maryConsents.size());
|
||||
}
|
||||
|
||||
private boolean isClientScopeGranted(RealmModel realm, String scopeName, UserConsentModel consentModel) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(realm, scopeName);
|
||||
return consentModel.isClientScopeGranted(clientScope);
|
||||
}
|
||||
}
|
|
@ -1,296 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.protocol.oidc.mappers.UserPropertyMapper;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
|
||||
import org.keycloak.testsuite.federation.storage.UserMapStorageFactory;
|
||||
import org.keycloak.testsuite.federation.storage.UserPropertyFileStorageFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserConsentWithUserStorageModelTest extends AbstractModelTest {
|
||||
|
||||
private ComponentModel clientStorageComponent;
|
||||
|
||||
@Before
|
||||
public void setupEnv() {
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
|
||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
||||
model.setName("memory");
|
||||
model.setPriority(0);
|
||||
model.setProviderId(UserMapStorageFactory.PROVIDER_ID);
|
||||
model.setParentId(realm.getId());
|
||||
realm.addComponentModel(model);
|
||||
|
||||
ClientModel fooClient = realm.addClient("foo-client");
|
||||
ClientModel barClient = realm.addClient("bar-client");
|
||||
|
||||
ClientScopeModel fooScope = realm.addClientScope("foo");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
ClientScopeModel barScope = realm.addClientScope("bar");
|
||||
fooScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
|
||||
UserModel john = session.users().addUser(realm, "john");
|
||||
UserModel mary = session.users().addUser(realm, "mary");
|
||||
|
||||
UserConsentModel johnFooGrant = new UserConsentModel(fooClient);
|
||||
johnFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnFooGrant);
|
||||
|
||||
UserConsentModel johnBarGrant = new UserConsentModel(barClient);
|
||||
johnBarGrant.addGrantedClientScope(barScope);
|
||||
|
||||
// Update should fail as grant doesn't yet exists
|
||||
try {
|
||||
realmManager.getSession().users().updateConsent(realm, john.getId(), johnBarGrant);
|
||||
Assert.fail("Not expected to end here");
|
||||
} catch (ModelException expected) {
|
||||
}
|
||||
|
||||
realmManager.getSession().users().addConsent(realm, john.getId(), johnBarGrant);
|
||||
|
||||
UserConsentModel maryFooGrant = new UserConsentModel(fooClient);
|
||||
maryFooGrant.addGrantedClientScope(fooScope);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryFooGrant);
|
||||
|
||||
ClientStorageProviderModel clientStorage = new ClientStorageProviderModel();
|
||||
clientStorage.setProviderId(HardcodedClientStorageProviderFactory.PROVIDER_ID);
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, "http://localhost:8081/*");
|
||||
clientStorage.getConfig().putSingle(HardcodedClientStorageProviderFactory.CONSENT, "true");
|
||||
clientStorage.setParentId(realm.getId());
|
||||
clientStorageComponent = realm.addComponentModel(clientStorage);
|
||||
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
Assert.assertNotNull(hardcodedClient);
|
||||
|
||||
UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient);
|
||||
realmManager.getSession().users().addConsent(realm, mary.getId(), maryHardcodedGrant);
|
||||
|
||||
|
||||
commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicConsentTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel johnBarConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId());
|
||||
Assert.assertEquals(johnBarConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent));
|
||||
Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate());
|
||||
|
||||
UserConsentModel maryConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate());
|
||||
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
UserConsentModel maryHardcodedConsent = realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate());
|
||||
Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate());
|
||||
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), barClient.getId()));
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), hardcodedClient.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllConsentTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> johnConsents = realmManager.getSession().users().getConsents(realm, john.getId());
|
||||
Assert.assertEquals(2, johnConsents.size());
|
||||
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(2, maryConsents.size());
|
||||
UserConsentModel maryConsent = maryConsents.get(0);
|
||||
UserConsentModel maryHardcodedConsent = maryConsents.get(1);
|
||||
if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) {
|
||||
maryConsent = maryConsents.get(1);
|
||||
maryHardcodedConsent = maryConsents.get(0);
|
||||
|
||||
}
|
||||
Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId());
|
||||
Assert.assertEquals(maryConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent));
|
||||
|
||||
Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId());
|
||||
Assert.assertEquals(maryHardcodedConsent.getGrantedClientScopes().size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateWithClientScopeRemovalTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size());
|
||||
|
||||
// Remove foo protocol mapper from johnConsent
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
johnConsent.getGrantedClientScopes().remove(fooScope);
|
||||
|
||||
realmManager.getSession().users().updateConsent(realm, john.getId(), johnConsent);
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
fooClient = realm.getClientByClientId("foo-client");
|
||||
john = session.users().getUserByUsername("john", realm);
|
||||
johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void revokeTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
realmManager.getSession().users().revokeConsentForClient(realm, john.getId(), fooClient.getId());
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
realmManager.getSession().users().revokeConsentForClient(realm, mary.getId(), hardcodedClient.getId());
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
john = session.users().getUserByUsername("john", realm);
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId()));
|
||||
mary = session.users().getUserByUsername("mary", realm);
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, mary.getId(), hardcodedClient.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteUserTest() {
|
||||
// Validate user deleted without any referential constraint errors
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
session.users().removeUser(realm, john);
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
session.users().removeUser(realm, mary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteClientScopeTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo");
|
||||
realm.removeClientScope(fooScope.getId());
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
fooClient = realm.getClientByClientId("foo-client");
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
UserConsentModel johnConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
|
||||
Assert.assertEquals(johnConsent.getGrantedClientScopes().size(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteClientTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
ClientModel barClient = realm.getClientByClientId("bar-client");
|
||||
realm.removeClient(barClient.getId());
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
ClientModel fooClient = realm.getClientByClientId("foo-client");
|
||||
Assert.assertNull(realm.getClientByClientId("bar-client"));
|
||||
|
||||
UserModel john = session.users().getUserByUsername("john", realm);
|
||||
|
||||
UserConsentModel johnFooConsent = realmManager.getSession().users().getConsentByClient(realm, john.getId(), fooClient.getId());
|
||||
Assert.assertEquals(johnFooConsent.getGrantedClientScopes().size(), 1);
|
||||
Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent));
|
||||
|
||||
Assert.assertNull(realmManager.getSession().users().getConsentByClient(realm, john.getId(), barClient.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteClientStorageTest() {
|
||||
RealmModel realm = realmManager.getRealm("original");
|
||||
realm.removeComponent(clientStorageComponent);
|
||||
commit();
|
||||
|
||||
|
||||
|
||||
realm = realmManager.getRealm("original");
|
||||
ClientModel hardcodedClient = session.realms().getClientByClientId("hardcoded-client", realm);
|
||||
Assert.assertNull(hardcodedClient);
|
||||
|
||||
UserModel mary = session.users().getUserByUsername("mary", realm);
|
||||
|
||||
List<UserConsentModel> maryConsents = realmManager.getSession().users().getConsents(realm, mary.getId());
|
||||
Assert.assertEquals(1, maryConsents.size());
|
||||
}
|
||||
|
||||
private boolean isClientScopeGranted(RealmModel realm, String scopeName, UserConsentModel consentModel) {
|
||||
ClientScopeModel clientScope = KeycloakModelUtils.getClientScopeByName(realm, scopeName);
|
||||
return consentModel.isClientScopeGranted(clientScope);
|
||||
}
|
||||
}
|
|
@ -1,442 +0,0 @@
|
|||
/*
|
||||
* 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, true));
|
||||
Assert.assertEquals(1, session.users().getUsersCount(realm, false));
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserNotBefore() throws Exception {
|
||||
RealmModel realm = realmManager.createRealm("original");
|
||||
|
||||
UserModel user1 = session.users().addUser(realm, "user1");
|
||||
session.users().setNotBeforeForUser(realm, user1, 10);
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealmByName("original");
|
||||
user1 = session.users().getUserByUsername("user1", realm);
|
||||
int notBefore = session.users().getNotBeforeOfUser(realm, user1);
|
||||
Assert.assertEquals(10, notBefore);
|
||||
|
||||
// Try to update
|
||||
session.users().setNotBeforeForUser(realm, user1, 20);
|
||||
|
||||
commit();
|
||||
|
||||
realm = realmManager.getRealmByName("original");
|
||||
user1 = session.users().getUserByUsername("user1", realm);
|
||||
notBefore = session.users().getNotBeforeOfUser(realm, user1);
|
||||
Assert.assertEquals(20, notBefore);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,469 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.cluster.ClusterProvider;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.models.UserManager;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserSessionPersisterProviderTest {
|
||||
|
||||
|
||||
@ClassRule
|
||||
public static KeycloakRule kc = new KeycloakRule();
|
||||
|
||||
private KeycloakSession session;
|
||||
private RealmModel realm;
|
||||
private UserSessionPersisterProvider persister;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
session = kc.startSession();
|
||||
realm = session.realms().getRealm("test");
|
||||
session.users().addUser(realm, "user1").setEmail("user1@localhost");
|
||||
session.users().addUser(realm, "user2").setEmail("user2@localhost");
|
||||
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
resetSession();
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
if (user1 != null) {
|
||||
um.removeUser(realm, user1);
|
||||
}
|
||||
if (user2 != null) {
|
||||
um.removeUser(realm, user2);
|
||||
}
|
||||
kc.stopSession(session, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistenceWithLoad() {
|
||||
// Create some sessions in infinispan
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[] origSessions = createSessions();
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist 3 created userSessions and clientSessions as offline
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, testApp);
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
persistUserSession(userSession, true);
|
||||
}
|
||||
|
||||
// Persist 1 online session
|
||||
UserSessionModel userSession = session.sessions().getUserSession(realm, origSessions[0].getId());
|
||||
persistUserSession(userSession, false);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert online session
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(false, 1, 1, 1);
|
||||
UserSessionProviderTest.assertSession(loadedSessions.get(0), session.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party");
|
||||
|
||||
// Assert offline sessions
|
||||
loadedSessions = loadPersistedSessionsPaginated(true, 2, 2, 3);
|
||||
UserSessionProviderTest.assertSessions(loadedSessions, origSessions);
|
||||
|
||||
assertSessionLoaded(loadedSessions, origSessions[0].getId(), session.users().getUserByUsername("user1", realm), "127.0.0.1", started, started, "test-app", "third-party");
|
||||
assertSessionLoaded(loadedSessions, origSessions[1].getId(), session.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app");
|
||||
assertSessionLoaded(loadedSessions, origSessions[2].getId(), session.users().getUserByUsername("user2", realm), "127.0.0.3", started, started, "test-app");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdateAndRemove() {
|
||||
// Create some sessions in infinispan
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[] origSessions = createSessions();
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist 1 offline session
|
||||
UserSessionModel userSession = session.sessions().getUserSession(realm, origSessions[1].getId());
|
||||
persistUserSession(userSession, true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Load offline session
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
UserSessionModel persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user1", realm), "127.0.0.2", started, started, "test-app");
|
||||
|
||||
// create new clientSession
|
||||
AuthenticatedClientSessionModel clientSession = createClientSession(realm.getClientByClientId("third-party"), session.sessions().getUserSession(realm, persistedSession.getId()),
|
||||
"http://redirect", "state");
|
||||
persister.createClientSession(clientSession, true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Remove clientSession
|
||||
persister.removeClientSession(userSession.getId(), realm.getClientByClientId("third-party").getId(), true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert clientSession removed
|
||||
loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user1", realm), "127.0.0.2", started, started , "test-app");
|
||||
|
||||
// Remove userSession
|
||||
persister.removeUserSession(persistedSession.getId(), true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert nothing found
|
||||
loadPersistedSessionsPaginated(true, 10, 0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRealmRemoved() {
|
||||
RealmModel fooRealm = session.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
session.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(fooRealm, session.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
createClientSession(fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist offline session
|
||||
fooRealm = session.realms().getRealm("foo");
|
||||
userSession = session.sessions().getUserSession(fooRealm, userSession.getId());
|
||||
persistUserSession(userSession, true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert session was persisted
|
||||
loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
|
||||
// Remove realm
|
||||
RealmManager realmMgr = new RealmManager(session);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert nothing loaded
|
||||
loadPersistedSessionsPaginated(true, 10, 0, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClientRemoved() {
|
||||
int started = Time.currentTime();
|
||||
|
||||
RealmModel fooRealm = session.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
fooRealm.addClient("bar-app");
|
||||
session.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(fooRealm, session.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
createClientSession(fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
createClientSession(fooRealm.getClientByClientId("bar-app"), userSession, "http://redirect", "state");
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist offline session
|
||||
fooRealm = session.realms().getRealm("foo");
|
||||
userSession = session.sessions().getUserSession(fooRealm, userSession.getId());
|
||||
persistUserSession(userSession, true);
|
||||
|
||||
resetSession();
|
||||
|
||||
RealmManager realmMgr = new RealmManager(session);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert session was persisted with both clientSessions
|
||||
UserSessionModel persistedSession = loadPersistedSessionsPaginated(true, 10, 1, 1).get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user3", fooRealm), "127.0.0.1", started, started, "foo-app", "bar-app");
|
||||
|
||||
// Remove foo-app client
|
||||
ClientModel client = fooRealm.getClientByClientId("foo-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
|
||||
resetSession();
|
||||
|
||||
realmMgr = new RealmManager(session);
|
||||
clientMgr = new ClientManager(realmMgr);
|
||||
fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert just one bar-app clientSession persisted now
|
||||
persistedSession = loadPersistedSessionsPaginated(true, 10, 1, 1).get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user3", fooRealm), "127.0.0.1", started, started, "bar-app");
|
||||
|
||||
// Remove bar-app client
|
||||
client = fooRealm.getClientByClientId("bar-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert loading still works - last userSession is still there, but no clientSession on it
|
||||
loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
|
||||
// Cleanup
|
||||
realmMgr = new RealmManager(session);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnUserRemoved() {
|
||||
// Create some sessions in infinispan
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[] origSessions = createSessions();
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist 2 offline sessions of 2 users
|
||||
UserSessionModel userSession1 = session.sessions().getUserSession(realm, origSessions[1].getId());
|
||||
UserSessionModel userSession2 = session.sessions().getUserSession(realm, origSessions[2].getId());
|
||||
persistUserSession(userSession1, true);
|
||||
persistUserSession(userSession2, true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Load offline sessions
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 2);
|
||||
|
||||
// Properly delete user and assert his offlineSession removed
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
new UserManager(session).removeUser(realm, user1);
|
||||
|
||||
resetSession();
|
||||
|
||||
Assert.assertEquals(1, persister.getUserSessionsCount(true));
|
||||
loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
UserSessionModel persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user2", realm), "127.0.0.3", started, started, "test-app");
|
||||
|
||||
// KEYCLOAK-2431 Assert that userSessionPersister is resistent even to situation, when users are deleted "directly".
|
||||
// No exception will happen. However session will be still there
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
session.users().removeUser(realm, user2);
|
||||
|
||||
loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
|
||||
// Cleanup
|
||||
UserSessionModel userSession = loadedSessions.get(0);
|
||||
session.sessions().removeUserSession(realm, userSession);
|
||||
persister.removeUserSession(userSession.getId(), userSession.isOffline());
|
||||
}
|
||||
|
||||
// KEYCLOAK-1999
|
||||
@Test
|
||||
public void testNoSessions() {
|
||||
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
List<UserSessionModel> sessions = persister.loadUserSessions(0, 1, true, 0, "abc");
|
||||
Assert.assertEquals(0, sessions.size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMoreSessions() {
|
||||
// Create 10 userSessions - each having 1 clientSession
|
||||
List<UserSessionModel> userSessions = new ArrayList<>();
|
||||
UserModel user = session.users().getUserByUsername("user1", realm);
|
||||
|
||||
for (int i=0 ; i<20 ; i++) {
|
||||
// Having different offsets for each session (to ensure that lastSessionRefresh is also different)
|
||||
Time.setOffset(i);
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(realm, user, "user1", "127.0.0.1", "form", true, null, null);
|
||||
createClientSession(realm.getClientByClientId("test-app"), userSession, "http://redirect", "state");
|
||||
userSessions.add(userSession);
|
||||
}
|
||||
|
||||
resetSession();
|
||||
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
UserSessionModel userSession2 = session.sessions().getUserSession(realm, userSession.getId());
|
||||
persistUserSession(userSession2, true);
|
||||
}
|
||||
|
||||
resetSession();
|
||||
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(true, 2, 10, 20);
|
||||
user = session.users().getUserByUsername("user1", realm);
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
|
||||
for (UserSessionModel loadedSession : loadedSessions) {
|
||||
assertEquals(user.getId(), loadedSession.getUser().getId());
|
||||
assertEquals("127.0.0.1", loadedSession.getIpAddress());
|
||||
assertEquals(user.getUsername(), loadedSession.getLoginUsername());
|
||||
|
||||
assertEquals(1, loadedSession.getAuthenticatedClientSessions().size());
|
||||
assertTrue(loadedSession.getAuthenticatedClientSessions().containsKey(testApp.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExpiredSessions() {
|
||||
// Create some sessions in infinispan
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[] origSessions = createSessions();
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist 2 offline sessions of 2 users
|
||||
UserSessionModel userSession1 = session.sessions().getUserSession(realm, origSessions[1].getId());
|
||||
UserSessionModel userSession2 = session.sessions().getUserSession(realm, origSessions[2].getId());
|
||||
persistUserSession(userSession1, true);
|
||||
persistUserSession(userSession2, true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Update one of the sessions with lastSessionRefresh of 20 days ahead
|
||||
int lastSessionRefresh = Time.currentTime() + 1728000;
|
||||
persister.updateLastSessionRefreshes(realm, lastSessionRefresh, Collections.singleton(userSession1.getId()), true);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Increase time offset - 40 days
|
||||
Time.setOffset(3456000);
|
||||
try {
|
||||
// Run expiration thread
|
||||
persister.removeExpired(realm);
|
||||
|
||||
// Test the updated session is still in persister. Not updated session is not there anymore
|
||||
List<UserSessionModel> loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 1);
|
||||
UserSessionModel persistedSession = loadedSessions.get(0);
|
||||
UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user1", realm), "127.0.0.2", started, lastSessionRefresh, "test-app");
|
||||
|
||||
} finally {
|
||||
// Cleanup
|
||||
Time.setOffset(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private AuthenticatedClientSessionModel createClientSession(ClientModel client, UserSessionModel userSession, String redirect, String state) {
|
||||
AuthenticatedClientSessionModel clientSession = session.sessions().createClientSession(realm, client, userSession);
|
||||
clientSession.setRedirectUri(redirect);
|
||||
if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
private UserSessionModel[] createSessions() {
|
||||
UserSessionModel[] sessions = new UserSessionModel[3];
|
||||
sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true, null, null);
|
||||
|
||||
createClientSession(realm.getClientByClientId("test-app"), sessions[0], "http://redirect", "state");
|
||||
createClientSession(realm.getClientByClientId("third-party"), sessions[0], "http://redirect", "state");
|
||||
|
||||
sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true, null, null);
|
||||
createClientSession(realm.getClientByClientId("test-app"), sessions[1], "http://redirect", "state");
|
||||
|
||||
sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true, null, null);
|
||||
createClientSession(realm.getClientByClientId("test-app"), sessions[2], "http://redirect", "state");
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
private void persistUserSession(UserSessionModel userSession, boolean offline) {
|
||||
persister.createUserSession(userSession, offline);
|
||||
for (AuthenticatedClientSessionModel clientSession : userSession.getAuthenticatedClientSessions().values()) {
|
||||
persister.createClientSession(clientSession, offline);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetSession() {
|
||||
kc.stopSession(session, true);
|
||||
session = kc.startSession();
|
||||
realm = session.realms().getRealm("test");
|
||||
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
}
|
||||
|
||||
public static void assertSessionLoaded(List<UserSessionModel> sessions, String id, UserModel user, String ipAddress, int started, int lastRefresh, String... clients) {
|
||||
for (UserSessionModel session : sessions) {
|
||||
if (session.getId().equals(id)) {
|
||||
UserSessionProviderTest.assertSession(session, user, ipAddress, started, lastRefresh, clients);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Assert.fail("Session with ID " + id + " not found in the list");
|
||||
}
|
||||
|
||||
private List<UserSessionModel> loadPersistedSessionsPaginated(boolean offline, int sessionsPerPage, int expectedPageCount, int expectedSessionsCount) {
|
||||
int count = persister.getUserSessionsCount(offline);
|
||||
|
||||
|
||||
int pageCount = 0;
|
||||
boolean next = true;
|
||||
List<UserSessionModel> result = new ArrayList<>();
|
||||
int lastCreatedOn = 0;
|
||||
String lastSessionId = "abc";
|
||||
|
||||
while (next) {
|
||||
List<UserSessionModel> sess = persister.loadUserSessions(0, sessionsPerPage, offline, lastCreatedOn, lastSessionId);
|
||||
|
||||
if (sess.size() < sessionsPerPage) {
|
||||
next = false;
|
||||
|
||||
// We had at least some session
|
||||
if (sess.size() > 0) {
|
||||
pageCount++;
|
||||
}
|
||||
} else {
|
||||
pageCount++;
|
||||
|
||||
UserSessionModel lastSession = sess.get(sess.size() - 1);
|
||||
lastCreatedOn = lastSession.getStarted();
|
||||
lastSessionId = lastSession.getId();
|
||||
}
|
||||
|
||||
result.addAll(sess);
|
||||
}
|
||||
|
||||
Assert.assertEquals(pageCount, expectedPageCount);
|
||||
Assert.assertEquals(result.size(), expectedSessionsCount);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,467 +0,0 @@
|
|||
/*
|
||||
* 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 org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.models.UserManager;
|
||||
import org.keycloak.services.managers.UserSessionManager;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.LoggingRule;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class UserSessionProviderOfflineTest {
|
||||
|
||||
@ClassRule
|
||||
public static KeycloakRule kc = new KeycloakRule();
|
||||
|
||||
@Rule
|
||||
public LoggingRule loggingRule = new LoggingRule(this);
|
||||
|
||||
private KeycloakSession session;
|
||||
private RealmModel realm;
|
||||
private UserSessionManager sessionManager;
|
||||
private UserSessionPersisterProvider persister;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
session = kc.startSession();
|
||||
realm = session.realms().getRealm("test");
|
||||
session.users().addUser(realm, "user1").setEmail("user1@localhost");
|
||||
session.users().addUser(realm, "user2").setEmail("user2@localhost");
|
||||
sessionManager = new UserSessionManager(session);
|
||||
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
resetSession();
|
||||
session.sessions().removeUserSessions(realm);
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
|
||||
UserManager um = new UserManager(session);
|
||||
um.removeUser(realm, user1);
|
||||
um.removeUser(realm, user2);
|
||||
kc.stopSession(session, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOfflineSessionsCrud() {
|
||||
// Create some online sessions in infinispan
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[] origSessions = createSessions();
|
||||
|
||||
resetSession();
|
||||
|
||||
// Key is userSession ID, values are client UUIDS
|
||||
Map<String, Set<String>> offlineSessions = new HashMap<>();
|
||||
|
||||
// Persist 3 created userSessions and clientSessions as offline
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, testApp);
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
offlineSessions.put(userSession.getId(), createOfflineSessionIncludeClientSessions(userSession));
|
||||
}
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert all previously saved offline sessions found
|
||||
for (Map.Entry<String, Set<String>> entry : offlineSessions.entrySet()) {
|
||||
UserSessionModel offlineSession = sessionManager.findOfflineUserSession(realm, entry.getKey());
|
||||
Assert.assertNotNull(offlineSession);
|
||||
Assert.assertEquals(offlineSession.getAuthenticatedClientSessions().keySet(), entry.getValue());
|
||||
}
|
||||
|
||||
// Find clients with offline token
|
||||
UserModel user1 = session.users().getUserByUsername("user1", realm);
|
||||
Set<ClientModel> clients = sessionManager.findClientsWithOfflineToken(realm, user1);
|
||||
Assert.assertEquals(clients.size(), 2);
|
||||
for (ClientModel client : clients) {
|
||||
Assert.assertTrue(client.getClientId().equals("test-app") || client.getClientId().equals("third-party"));
|
||||
}
|
||||
|
||||
UserModel user2 = session.users().getUserByUsername("user2", realm);
|
||||
clients = sessionManager.findClientsWithOfflineToken(realm, user2);
|
||||
Assert.assertEquals(clients.size(), 1);
|
||||
Assert.assertTrue(clients.iterator().next().getClientId().equals("test-app"));
|
||||
|
||||
// Test count
|
||||
testApp = realm.getClientByClientId("test-app");
|
||||
ClientModel thirdparty = realm.getClientByClientId("third-party");
|
||||
Assert.assertEquals(3, session.sessions().getOfflineSessionsCount(realm, testApp));
|
||||
Assert.assertEquals(1, session.sessions().getOfflineSessionsCount(realm, thirdparty));
|
||||
|
||||
// Revoke "test-app" for user1
|
||||
sessionManager.revokeOfflineToken(user1, testApp);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert userSession revoked
|
||||
testApp = realm.getClientByClientId("test-app");
|
||||
thirdparty = realm.getClientByClientId("third-party");
|
||||
|
||||
// Still 2 sessions. The count of sessions by client may not be accurate after revoke due the
|
||||
// performance optimizations (the "127.0.0.1" session still has another client "thirdparty" in it)
|
||||
Assert.assertEquals(2, session.sessions().getOfflineSessionsCount(realm, testApp));
|
||||
Assert.assertEquals(1, session.sessions().getOfflineSessionsCount(realm, thirdparty));
|
||||
|
||||
List<UserSessionModel> thirdpartySessions = session.sessions().getOfflineUserSessions(realm, thirdparty, 0, 10);
|
||||
Assert.assertEquals(1, thirdpartySessions.size());
|
||||
Assert.assertEquals("127.0.0.1", thirdpartySessions.get(0).getIpAddress());
|
||||
Assert.assertEquals("user1", thirdpartySessions.get(0).getUser().getUsername());
|
||||
|
||||
user1 = session.users().getUserByUsername("user1", realm);
|
||||
user2 = session.users().getUserByUsername("user2", realm);
|
||||
clients = sessionManager.findClientsWithOfflineToken(realm, user1);
|
||||
Assert.assertEquals(1, clients.size());
|
||||
Assert.assertEquals("third-party", clients.iterator().next().getClientId());
|
||||
clients = sessionManager.findClientsWithOfflineToken(realm, user2);
|
||||
Assert.assertEquals(1, clients.size());
|
||||
Assert.assertEquals("test-app", clients.iterator().next().getClientId());
|
||||
|
||||
// Revoke the second session for user1 too.
|
||||
sessionManager.revokeOfflineToken(user1, thirdparty);
|
||||
|
||||
resetSession();
|
||||
|
||||
testApp = realm.getClientByClientId("test-app");
|
||||
thirdparty = realm.getClientByClientId("third-party");
|
||||
|
||||
// Accurate count now. All sessions of user1 cleared
|
||||
Assert.assertEquals(1, session.sessions().getOfflineSessionsCount(realm, testApp));
|
||||
Assert.assertEquals(0, session.sessions().getOfflineSessionsCount(realm, thirdparty));
|
||||
|
||||
List<UserSessionModel> testAppSessions = session.sessions().getOfflineUserSessions(realm, testApp, 0, 10);
|
||||
|
||||
Assert.assertEquals(1, testAppSessions.size());
|
||||
Assert.assertEquals("127.0.0.3", testAppSessions.get(0).getIpAddress());
|
||||
Assert.assertEquals("user2", testAppSessions.get(0).getUser().getUsername());
|
||||
|
||||
clients = sessionManager.findClientsWithOfflineToken(realm, user1);
|
||||
Assert.assertEquals(0, clients.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnRealmRemoved() {
|
||||
RealmModel fooRealm = session.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
session.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(fooRealm, session.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
AuthenticatedClientSessionModel clientSession = createClientSession(fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
|
||||
resetSession();
|
||||
|
||||
// Persist offline session
|
||||
fooRealm = session.realms().getRealm("foo");
|
||||
userSession = session.sessions().getUserSession(fooRealm, userSession.getId());
|
||||
createOfflineSessionIncludeClientSessions(userSession);
|
||||
|
||||
resetSession();
|
||||
|
||||
UserSessionModel offlineUserSession = sessionManager.findOfflineUserSession(fooRealm, userSession.getId());
|
||||
Assert.assertEquals(offlineUserSession.getAuthenticatedClientSessions().size(), 1);
|
||||
AuthenticatedClientSessionModel offlineClientSession = offlineUserSession.getAuthenticatedClientSessions().values().iterator().next();
|
||||
Assert.assertEquals("foo-app", offlineClientSession.getClient().getClientId());
|
||||
Assert.assertEquals("user3", offlineClientSession.getUserSession().getUser().getUsername());
|
||||
|
||||
// Remove realm
|
||||
RealmManager realmMgr = new RealmManager(session);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
|
||||
resetSession();
|
||||
|
||||
fooRealm = session.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
session.users().addUser(fooRealm, "user3");
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert nothing loaded
|
||||
fooRealm = session.realms().getRealm("foo");
|
||||
Assert.assertNull(sessionManager.findOfflineUserSession(fooRealm, userSession.getId()));
|
||||
Assert.assertEquals(0, session.sessions().getOfflineSessionsCount(fooRealm, fooRealm.getClientByClientId("foo-app")));
|
||||
|
||||
// Cleanup
|
||||
realmMgr = new RealmManager(session);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClientRemoved() {
|
||||
int started = Time.currentTime();
|
||||
|
||||
RealmModel fooRealm = session.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
fooRealm.addClient("bar-app");
|
||||
session.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(fooRealm, session.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
createClientSession(fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
createClientSession(fooRealm.getClientByClientId("bar-app"), userSession, "http://redirect", "state");
|
||||
|
||||
resetSession();
|
||||
|
||||
// Create offline session
|
||||
fooRealm = session.realms().getRealm("foo");
|
||||
userSession = session.sessions().getUserSession(fooRealm, userSession.getId());
|
||||
createOfflineSessionIncludeClientSessions(userSession);
|
||||
|
||||
resetSession();
|
||||
|
||||
RealmManager realmMgr = new RealmManager(session);
|
||||
ClientManager clientMgr = new ClientManager(realmMgr);
|
||||
fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert session was persisted with both clientSessions
|
||||
UserSessionModel offlineSession = session.sessions().getOfflineUserSession(fooRealm, userSession.getId());
|
||||
UserSessionProviderTest.assertSession(offlineSession, session.users().getUserByUsername("user3", fooRealm), "127.0.0.1", started, started, "foo-app", "bar-app");
|
||||
|
||||
// Remove foo-app client
|
||||
ClientModel client = fooRealm.getClientByClientId("foo-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
|
||||
resetSession();
|
||||
|
||||
realmMgr = new RealmManager(session);
|
||||
clientMgr = new ClientManager(realmMgr);
|
||||
fooRealm = realmMgr.getRealm("foo");
|
||||
|
||||
// Assert just one bar-app clientSession persisted now
|
||||
offlineSession = session.sessions().getOfflineUserSession(fooRealm, userSession.getId());
|
||||
Assert.assertEquals(1, offlineSession.getAuthenticatedClientSessions().size());
|
||||
Assert.assertEquals("bar-app", offlineSession.getAuthenticatedClientSessions().values().iterator().next().getClient().getClientId());
|
||||
|
||||
// Remove bar-app client
|
||||
client = fooRealm.getClientByClientId("bar-app");
|
||||
clientMgr.removeClient(fooRealm, client);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert nothing loaded - userSession was removed as well because it was last userSession
|
||||
realmMgr = new RealmManager(session);
|
||||
fooRealm = realmMgr.getRealm("foo");
|
||||
offlineSession = session.sessions().getOfflineUserSession(fooRealm, userSession.getId());
|
||||
Assert.assertEquals(0, offlineSession.getAuthenticatedClientSessions().size());
|
||||
|
||||
// Cleanup
|
||||
realmMgr = new RealmManager(session);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnUserRemoved() {
|
||||
int started = Time.currentTime();
|
||||
|
||||
RealmModel fooRealm = session.realms().createRealm("foo", "foo");
|
||||
fooRealm.addClient("foo-app");
|
||||
session.users().addUser(fooRealm, "user3");
|
||||
|
||||
UserSessionModel userSession = session.sessions().createUserSession(fooRealm, session.users().getUserByUsername("user3", fooRealm), "user3", "127.0.0.1", "form", true, null, null);
|
||||
AuthenticatedClientSessionModel clientSession = createClientSession(fooRealm.getClientByClientId("foo-app"), userSession, "http://redirect", "state");
|
||||
|
||||
resetSession();
|
||||
|
||||
// Create offline session
|
||||
fooRealm = session.realms().getRealm("foo");
|
||||
userSession = session.sessions().getUserSession(fooRealm, userSession.getId());
|
||||
createOfflineSessionIncludeClientSessions(userSession);
|
||||
|
||||
resetSession();
|
||||
|
||||
RealmManager realmMgr = new RealmManager(session);
|
||||
fooRealm = realmMgr.getRealm("foo");
|
||||
UserModel user3 = session.users().getUserByUsername("user3", fooRealm);
|
||||
|
||||
// Assert session was persisted with both clientSessions
|
||||
UserSessionModel offlineSession = session.sessions().getOfflineUserSession(fooRealm, userSession.getId());
|
||||
UserSessionProviderTest.assertSession(offlineSession, user3, "127.0.0.1", started, started, "foo-app");
|
||||
|
||||
// Remove user3
|
||||
new UserManager(session).removeUser(fooRealm, user3);
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert userSession removed as well
|
||||
Assert.assertNull(session.sessions().getOfflineUserSession(fooRealm, userSession.getId()));
|
||||
|
||||
// Cleanup
|
||||
realmMgr = new RealmManager(session);
|
||||
realmMgr.removeRealm(realmMgr.getRealm("foo"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpired() {
|
||||
// Create some online sessions in infinispan
|
||||
int started = Time.currentTime();
|
||||
UserSessionModel[] origSessions = createSessions();
|
||||
|
||||
resetSession();
|
||||
|
||||
// Key is userSessionId, value is set of client UUIDS
|
||||
Map<String, Set<String>> offlineSessions = new HashMap<>();
|
||||
|
||||
// Persist 3 created userSessions and clientSessions as offline
|
||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||
List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, testApp);
|
||||
for (UserSessionModel userSession : userSessions) {
|
||||
offlineSessions.put(userSession.getId(), createOfflineSessionIncludeClientSessions(userSession));
|
||||
}
|
||||
|
||||
resetSession();
|
||||
|
||||
// Assert all previously saved offline sessions found
|
||||
for (Map.Entry<String, Set<String>> entry : offlineSessions.entrySet()) {
|
||||
UserSessionModel foundSession = sessionManager.findOfflineUserSession(realm, entry.getKey());
|
||||
Assert.assertEquals(foundSession.getAuthenticatedClientSessions().keySet(), entry.getValue());
|
||||
}
|
||||
|
||||
UserSessionModel session0 = session.sessions().getOfflineUserSession(realm, origSessions[0].getId());
|
||||
Assert.assertNotNull(session0);
|
||||
|
||||
// sessions are in persister too
|
||||
Assert.assertEquals(3, persister.getUserSessionsCount(true));
|
||||
|
||||
// Increase timeOffset - 5 minutes
|
||||
Time.setOffset(300);
|
||||
try {
|
||||
|
||||
// Update lastSessionRefresh of session0. This will update lastSessionRefresh of all the sessions to DB as they were not yet updated to DB
|
||||
session0.setLastSessionRefresh(Time.currentTime());
|
||||
|
||||
resetSession();
|
||||
|
||||
// Increase timeOffset - 20 days
|
||||
Time.setOffset(1728000);
|
||||
|
||||
session0 = session.sessions().getOfflineUserSession(realm, origSessions[0].getId());
|
||||
session0.setLastSessionRefresh(Time.currentTime());
|
||||
|
||||
resetSession();
|
||||
|
||||
// Increase timeOffset - 40 days
|
||||
Time.setOffset(3456000);
|
||||
|
||||
// Expire and ensure that all sessions despite session0 were removed
|
||||
|
||||
session.sessions().removeExpired(realm);
|
||||
persister.removeExpired(realm);
|
||||
|
||||
resetSession();
|
||||
|
||||
// assert session0 is the only session found
|
||||
Assert.assertNotNull(session.sessions().getOfflineUserSession(realm, origSessions[0].getId()));
|
||||
Assert.assertNull(session.sessions().getOfflineUserSession(realm, origSessions[1].getId()));
|
||||
Assert.assertNull(session.sessions().getOfflineUserSession(realm, origSessions[2].getId()));
|
||||
|
||||
Assert.assertEquals(1, persister.getUserSessionsCount(true));
|
||||
|
||||
// Expire everything and assert nothing found
|
||||
Time.setOffset(6000000);
|
||||
|
||||
session.sessions().removeExpired(realm);
|
||||
persister.removeExpired(realm);
|
||||
|
||||
resetSession();
|
||||
|
||||
for (String userSessionId : offlineSessions.keySet()) {
|
||||
Assert.assertNull(sessionManager.findOfflineUserSession(realm, userSessionId));
|
||||
}
|
||||
Assert.assertEquals(0, persister.getUserSessionsCount(true));
|
||||
|
||||
} finally {
|
||||
Time.setOffset(0);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> createOfflineSessionIncludeClientSessions(UserSessionModel userSession) {
|
||||
Set<String> offlineSessions = new HashSet<>();
|
||||
|
||||
for (AuthenticatedClientSessionModel clientSession : userSession.getAuthenticatedClientSessions().values()) {
|
||||
sessionManager.createOrUpdateOfflineSession(clientSession, userSession);
|
||||
offlineSessions.add(clientSession.getClient().getId());
|
||||
}
|
||||
return offlineSessions;
|
||||
}
|
||||
|
||||
|
||||
private void resetSession() {
|
||||
kc.stopSession(session, true);
|
||||
session = kc.startSession();
|
||||
realm = session.realms().getRealm("test");
|
||||
sessionManager = new UserSessionManager(session);
|
||||
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||
}
|
||||
|
||||
private AuthenticatedClientSessionModel createClientSession(ClientModel client, UserSessionModel userSession, String redirect, String state) {
|
||||
AuthenticatedClientSessionModel clientSession = session.sessions().createClientSession(client.getRealm(), client, userSession);
|
||||
clientSession.setRedirectUri(redirect);
|
||||
if (state != null) clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, state);
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
private UserSessionModel[] createSessions() {
|
||||
UserSessionModel[] sessions = new UserSessionModel[3];
|
||||
sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true, null, null);
|
||||
|
||||
Set<String> roles = new HashSet<String>();
|
||||
roles.add("one");
|
||||
roles.add("two");
|
||||
|
||||
Set<String> protocolMappers = new HashSet<String>();
|
||||
protocolMappers.add("mapper-one");
|
||||
protocolMappers.add("mapper-two");
|
||||
|
||||
createClientSession(realm.getClientByClientId("test-app"), sessions[0], "http://redirect", "state");
|
||||
createClientSession(realm.getClientByClientId("third-party"), sessions[0], "http://redirect", "state");
|
||||
|
||||
sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true, null, null);
|
||||
createClientSession(realm.getClientByClientId("test-app"), sessions[1], "http://redirect", "state");
|
||||
|
||||
sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true, null, null);
|
||||
createClientSession(realm.getClientByClientId("test-app"), sessions[2], "http://redirect", "state");
|
||||
|
||||
return sessions;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue