From 6b1c64a1a944b2b134af9858e7c18e5cec39d488 Mon Sep 17 00:00:00 2001 From: Lex Cao Date: Tue, 23 Aug 2022 21:28:52 +0800 Subject: [PATCH] Add rememberMe to a user session representation(#13408) (#13765) Closes #13408 --- .../idm/UserSessionRepresentation.java | 11 +++++++- .../models/utils/ModelToRepresentation.java | 7 +++--- .../testsuite/admin/client/SessionTest.java | 25 ++++++++++++++++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java index 9d244f5fb5..2e9294fa52 100755 --- a/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/UserSessionRepresentation.java @@ -31,6 +31,7 @@ public class UserSessionRepresentation { private String ipAddress; private long start; private long lastAccess; + private boolean rememberMe; private Map clients = new HashMap<>(); public String getId() { @@ -48,7 +49,7 @@ public class UserSessionRepresentation { public void setUsername(String username) { this.username = username; } - + public String getUserId() { return userId; } @@ -81,6 +82,14 @@ public class UserSessionRepresentation { this.lastAccess = lastAccess; } + public boolean isRememberMe() { + return rememberMe; + } + + public void setRememberMe(boolean rememberMe) { + this.rememberMe = rememberMe; + } + public Map getClients() { return clients; } diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index 3c83a78159..2e5a1369fc 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -641,6 +641,7 @@ public class ModelToRepresentation { rep.setUsername(session.getUser().getUsername()); rep.setUserId(session.getUser().getId()); rep.setIpAddress(session.getIpAddress()); + rep.setRememberMe(session.isRememberMe()); for (AuthenticatedClientSessionModel clientSession : session.getAuthenticatedClientSessions().values()) { ClientModel client = clientSession.getClient(); rep.getClients().put(client.getId(), client.getClientId()); @@ -694,7 +695,7 @@ public class ModelToRepresentation { rep.setNotBefore(clientModel.getNotBefore()); rep.setNodeReRegistrationTimeout(clientModel.getNodeReRegistrationTimeout()); rep.setClientAuthenticatorType(clientModel.getClientAuthenticatorType()); - + // adding the secret if non public or bearer only if (clientModel.isBearerOnly() || clientModel.isPublicClient()) { rep.setSecret(null); @@ -937,7 +938,7 @@ public class ModelToRepresentation { public static R toRepresentation(Policy policy, AuthorizationProvider authorization, boolean genericRepresentation, boolean export) { return toRepresentation(policy, authorization, genericRepresentation, export, false); } - + public static R toRepresentation(Policy policy, AuthorizationProvider authorization, boolean genericRepresentation, boolean export, boolean allFields) { PolicyProviderFactory providerFactory = authorization.getProviderFactory(policy.getType()); R representation; @@ -962,7 +963,7 @@ public class ModelToRepresentation { representation.setType(policy.getType()); representation.setDecisionStrategy(policy.getDecisionStrategy()); representation.setLogic(policy.getLogic()); - + if (allFields) { representation.setResourcesData(policy.getResources().stream() .map(resource -> toRepresentation(resource, policy.getResourceServer(), authorization, true)) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java index 4a545a3be5..7700c84c6b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/SessionTest.java @@ -24,17 +24,19 @@ import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.common.Profile; import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; +import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.testsuite.arquillian.annotation.DisableFeature; -import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.auth.page.account.AccountManagement; import org.keycloak.testsuite.util.AdminEventPaths; import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; /** @@ -105,6 +107,27 @@ public class SessionTest extends AbstractClientTest { assertNotNull(rep.getIpAddress()); assertNotNull(rep.getLastAccess()); assertNotNull(rep.getStart()); + assertFalse(rep.isRememberMe()); + + testRealmAccountManagementPage.signOut(); + } + + @Test + public void testGetUserSessionsWithRememberMe() { + RealmRepresentation realm = adminClient.realm(TEST).toRepresentation(); + realm.setRememberMe(true); + adminClient.realm(TEST).update(realm); + + testRealmAccountManagementPage.navigateTo(); + loginPage.form().rememberMe(true); + loginPage.form().login(testUser); + + ClientResource account = findClientResourceById("account"); + List sessions = account.getUserSessions(0, 5); + assertEquals(1, sessions.size()); + + UserSessionRepresentation rep = sessions.get(0); + assertTrue(rep.isRememberMe()); testRealmAccountManagementPage.signOut(); }