keycloak-uncached

Details

diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 88525db..06eefe0 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -165,7 +165,8 @@ public class OIDCLoginProtocol implements LoginProtocol {
     @Override
     public void backchannelLogout(UserSessionModel userSession, ClientSessionModel clientSession) {
         if (!(clientSession.getClient() instanceof ClientModel)) return;
-        ClientModel app = (ClientModel)clientSession.getClient();
+        ClientModel app = clientSession.getClient();
+        // TODO: Probably non-effective to build executor every time from scratch. Should be likely shared for whole OIDCLoginProtocolFactory
         ApacheHttpClient4Executor executor = ResourceAdminManager.createExecutor();
 
         try {
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 8e363bb..6a96037 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -113,22 +113,26 @@ public class AuthenticationManager {
         expireUserSessionCookie(session, userSession, realm, uriInfo, headers, connection);
 
         for (ClientSessionModel clientSession : userSession.getClientSessions()) {
-            ClientModel client = clientSession.getClient();
-            if (client instanceof ClientModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) {
-                String authMethod = clientSession.getAuthMethod();
-                if (authMethod == null) continue; // must be a keycloak service like account
-                LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
-                protocol.setRealm(realm)
-                        .setHttpHeaders(headers)
-                        .setUriInfo(uriInfo);
-                protocol.backchannelLogout(userSession, clientSession);
-                clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT);
-            }
+            backchannelLogoutClientSession(session, realm, clientSession, userSession, uriInfo, headers);
         }
         userSession.setState(UserSessionModel.State.LOGGED_OUT);
         session.sessions().removeUserSession(realm, userSession);
     }
 
+    public static void backchannelLogoutClientSession(KeycloakSession session, RealmModel realm, ClientSessionModel clientSession, UserSessionModel userSession, UriInfo uriInfo, HttpHeaders headers) {
+        ClientModel client = clientSession.getClient();
+        if (client instanceof ClientModel && !client.isFrontchannelLogout() && clientSession.getAction() != ClientSessionModel.Action.LOGGED_OUT) {
+            String authMethod = clientSession.getAuthMethod();
+            if (authMethod == null) return; // must be a keycloak service like account
+            LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
+            protocol.setRealm(realm)
+                    .setHttpHeaders(headers)
+                    .setUriInfo(uriInfo);
+            protocol.backchannelLogout(userSession, clientSession);
+            clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT);
+        }
+    }
+
 
     public static Response browserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
         if (userSession == null) return null;
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 9b1edae..b9e8d89 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -478,7 +478,10 @@ public class AccountService {
         csrfCheck(stateChecker);
 
         UserModel user = auth.getUser();
-        session.sessions().removeUserSessions(realm, user);
+        List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
+        for (UserSessionModel userSession : userSessions) {
+            AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers);
+        }
 
         UriBuilder builder = Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "sessionsPage");
         String referrer = uriInfo.getQueryParameters().getFirst("referrer");
@@ -519,6 +522,7 @@ public class AccountService {
             List<ClientSessionModel> clientSessions = userSession.getClientSessions();
             for (ClientSessionModel clientSession : clientSessions) {
                 if (clientSession.getClient().getId().equals(clientId)) {
+                    AuthenticationManager.backchannelLogoutClientSession(session, realm, clientSession, userSession, uriInfo, headers);
                     TokenManager.dettachClientSession(session.sessions(), realm, clientSession);
                 }
             }
diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml
index d763ca1..527d91f 100755
--- a/testsuite/integration/pom.xml
+++ b/testsuite/integration/pom.xml
@@ -379,7 +379,7 @@
                             <systemPropertyVariables>
                                 <keycloak.realm.provider>jpa</keycloak.realm.provider>
                                 <keycloak.user.provider>jpa</keycloak.user.provider>
-                                <keycloak.eventStore.provider>jpa</keycloak.eventStore.provider>
+                                <keycloak.eventsStore.provider>jpa</keycloak.eventsStore.provider>
                                 <keycloak.userSessions.provider>jpa</keycloak.userSessions.provider>
                             </systemPropertyVariables>
                         </configuration>
@@ -443,7 +443,7 @@
                                     <systemPropertyVariables>
                                         <keycloak.realm.provider>mongo</keycloak.realm.provider>
                                         <keycloak.user.provider>mongo</keycloak.user.provider>
-                                        <keycloak.audit.provider>mongo</keycloak.audit.provider>
+                                        <keycloak.eventsStore.provider>mongo</keycloak.eventsStore.provider>
                                         <keycloak.userSessions.provider>mongo</keycloak.userSessions.provider>
                                         <keycloak.connectionsMongo.host>${keycloak.connectionsMongo.host}</keycloak.connectionsMongo.host>
                                         <keycloak.connectionsMongo.port>${keycloak.connectionsMongo.port}</keycloak.connectionsMongo.port>
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
index 15dfca3..2ea5ecc 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTest.java
@@ -155,4 +155,12 @@ public class AdapterTest {
         testStrategy.testAdminApplicationLogout();
     }
 
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
+
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
index f9f82dc..5c21db1 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/adapter/AdapterTestStrategy.java
@@ -44,6 +44,7 @@ import org.keycloak.services.managers.RealmManager;
 import org.keycloak.services.managers.ResourceAdminManager;
 import org.keycloak.services.resources.admin.AdminRoot;
 import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.pages.AccountSessionsPage;
 import org.keycloak.testsuite.pages.LoginPage;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 import org.keycloak.testsuite.rule.KeycloakRule;
@@ -94,6 +95,9 @@ public class AdapterTestStrategy extends ExternalResource {
     @WebResource
     protected InputPage inputPage;
 
+    @WebResource
+    protected AccountSessionsPage accountSessionsPage;
+
     protected String LOGIN_URL = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(AUTH_SERVER_URL)).build("demo").toString();
 
     public AdapterTestStrategy(String AUTH_SERVER_URL, String APP_SERVER_BASE_URL, AbstractKeycloakRule keycloakRule) {
@@ -592,6 +596,22 @@ public class AdapterTestStrategy extends ExternalResource {
         Assert.assertTrue(pageSource.contains("Counter=3"));
     }
 
+    /**
+     * KEYCLOAK-1216
+     */
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        // login as bburke
+        loginAndCheckSession(driver, loginPage);
+
+        // logout sessions in account management
+        accountSessionsPage.realm("demo");
+        accountSessionsPage.open();
+        accountSessionsPage.logoutAll();
+
+        // Assert I need to login again (logout was propagated to the app)
+        loginAndCheckSession(driver, loginPage);
+    }
+
     protected void loginAndCheckSession(WebDriver driver, LoginPage loginPage) {
         driver.navigate().to(APP_SERVER_BASE_URL + "/session-portal");
         String currentUrl = driver.getCurrentUrl();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java
index bfadc6d..1b52a56 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/AccountSessionsPage.java
@@ -36,7 +36,9 @@ import java.util.List;
  */
 public class AccountSessionsPage extends AbstractAccountPage {
 
-    private static String PATH = Urls.accountSessionsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), "test").toString();
+    private String realmName = "test";
+
+    private String path = Urls.accountSessionsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), "test").toString();
 
     @FindBy(id = "logout-all-sessions")
     private WebElement logoutAllLink;
@@ -45,8 +47,16 @@ public class AccountSessionsPage extends AbstractAccountPage {
         return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().endsWith("/account/sessions");
     }
 
+    public void realm(String realmName) {
+        this.realmName = realmName;
+    }
+
+    public String getPath() {
+        return Urls.accountSessionsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), realmName).toString();
+    }
+
     public void open() {
-        driver.navigate().to(PATH);
+        driver.navigate().to(getPath());
     }
 
     public void logoutAll() {
diff --git a/testsuite/integration/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration/src/test/resources/META-INF/keycloak-server.json
index 2c56c58..e2ebf54 100755
--- a/testsuite/integration/src/test/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/test/resources/META-INF/keycloak-server.json
@@ -4,7 +4,7 @@
     },
 
     "eventsStore": {
-        "provider": "${keycloak.eventStore.provider:jpa}"
+        "provider": "${keycloak.eventsStore.provider:jpa}"
     },
 
     "eventsListener": {
diff --git a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java
index 7c40fc2..6232ae5 100755
--- a/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java
+++ b/testsuite/jetty/jetty81/src/test/java/org/keycloak/testsuite/Jetty8Test.java
@@ -172,4 +172,12 @@ public class Jetty8Test {
     public void testAdminApplicationLogout() throws Throwable {
         testStrategy.testAdminApplicationLogout();
     }
+
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
 }
diff --git a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java
index 4b87597..09bffc7 100755
--- a/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java
+++ b/testsuite/jetty/jetty91/src/test/java/org/keycloak/testsuite/Jetty9Test.java
@@ -172,4 +172,12 @@ public class Jetty9Test {
     public void testAdminApplicationLogout() throws Throwable {
         testStrategy.testAdminApplicationLogout();
     }
+
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
 }
diff --git a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java
index ceab804..26db13a 100755
--- a/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java
+++ b/testsuite/jetty/jetty92/src/test/java/org/keycloak/testsuite/Jetty9Test.java
@@ -172,4 +172,12 @@ public class Jetty9Test {
     public void testAdminApplicationLogout() throws Throwable {
         testStrategy.testAdminApplicationLogout();
     }
+
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
 }
diff --git a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
index 9809e09..5393b65 100755
--- a/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
+++ b/testsuite/tomcat6/src/test/java/org/keycloak/testsuite/TomcatTest.java
@@ -161,6 +161,14 @@ public class TomcatTest {
         testStrategy.testAdminApplicationLogout();
     }
 
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
+
     static String getBaseDirectory() {
         String dirPath = null;
         String relativeDirPath = "testsuite" + File.separator + "tomcat6" + File.separator + "target";
diff --git a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
index ef06a17..7a38655 100755
--- a/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
+++ b/testsuite/tomcat7/src/test/java/org/keycloak/testsuite/Tomcat7Test.java
@@ -165,6 +165,14 @@ public class Tomcat7Test {
         testStrategy.testAdminApplicationLogout();
     }
 
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
+
 
     private static String getBaseDirectory() {
         String dirPath = null;
diff --git a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java
index 86fcac0..8c1372a 100755
--- a/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java
+++ b/testsuite/tomcat8/src/test/java/org/keycloak/testsuite/TomcatTest.java
@@ -166,6 +166,14 @@ public class TomcatTest {
         testStrategy.testAdminApplicationLogout();
     }
 
+    /**
+     * KEYCLOAK-1216
+     */
+    @Test
+    public void testAccountManagementSessionsLogout() throws Throwable {
+        testStrategy.testAccountManagementSessionsLogout();
+    }
+
     private static String getBaseDirectory() {
         String dirPath = null;
         String relativeDirPath = "testsuite" + File.separator + "tomcat8" + File.separator + "target";