mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Return user session started time when client note is missing for offline
Closes #39021 Signed-off-by: rmartinc <rmartinc@redhat.com> (cherry picked from commit 11b032f9cd5b336c1002ccb19e4977b1699f8ffa)
This commit is contained in:
parent
1aa80ab6d1
commit
a343af90dd
@ -39,8 +39,12 @@ public interface AuthenticatedClientSessionModel extends CommonClientSessionMode
|
||||
|
||||
default int getStarted() {
|
||||
String started = getNote(STARTED_AT_NOTE);
|
||||
// Fallback to 0 if "started" note is not available. This can happen for the offline sessions migrated from old version where "startedAt" note was not yet available
|
||||
return started == null ? 0 : Integer.parseInt(started);
|
||||
if (started == null) {
|
||||
// Note can be null for offline sessions migrated from old version where "startedAt" note was not yet available
|
||||
// Fallback to user session started for offline or 0
|
||||
return getUserSession().isOffline() ? getUserSessionStarted() : 0;
|
||||
}
|
||||
return Integer.parseInt(started);
|
||||
}
|
||||
|
||||
default int getUserSessionStarted() {
|
||||
|
||||
@ -870,6 +870,22 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||
}, Integer.class);
|
||||
}
|
||||
|
||||
private void removeClientSessionStartedAtNote(final String userSessionId, final String clientId, final String clientSessionId) {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realmModel = session.realms().getRealmByName("test");
|
||||
session.getContext().setRealm(realmModel);
|
||||
ClientModel clientModel = realmModel.getClientByClientId(clientId);
|
||||
UserSessionModel userSession = session.sessions().getOfflineUserSession(realmModel, userSessionId);
|
||||
if (userSession != null) {
|
||||
AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientModel.getId());
|
||||
if (clientSession != null) {
|
||||
clientSession.removeNote(AuthenticatedClientSessionModel.STARTED_AT_NOTE);
|
||||
clientSession.removeNote(AuthenticatedClientSessionModel.USER_SESSION_STARTED_AT_NOTE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void testOfflineSessionExpiration(int idleTime, int maxLifespan, int offsetHalf, int offset) {
|
||||
int prev[] = null;
|
||||
getTestingClient().testing().setTestingInfinispanTimeService();
|
||||
@ -1408,4 +1424,40 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void offlineRefreshWhenNoStartedAtClientNote() throws Exception {
|
||||
int prevOfflineSession[] = null;
|
||||
try {
|
||||
prevOfflineSession = changeOfflineSessionSettings(true, 3600, 3600, 0, 0);
|
||||
|
||||
// login to obtain a refresh token
|
||||
oauth.scope("openid " + OAuth2Constants.OFFLINE_ACCESS);
|
||||
oauth.clientId("offline-client");
|
||||
oauth.redirectUri(offlineClientAppUri);
|
||||
oauth.doLogin("test-user@localhost", "password");
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "secret1");
|
||||
|
||||
EventRepresentation loginEvent = events.expectLogin()
|
||||
.client("offline-client")
|
||||
.detail(Details.REDIRECT_URI, offlineClientAppUri)
|
||||
.assertEvent();
|
||||
|
||||
// remove the started notes that can be missed in previous versions
|
||||
String clientSessionId = getOfflineClientSessionUuid(loginEvent.getSessionId(), loginEvent.getClientId());
|
||||
removeClientSessionStartedAtNote(loginEvent.getSessionId(), loginEvent.getClientId(), clientSessionId);
|
||||
|
||||
// check refresh is successful
|
||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1");
|
||||
assertEquals(200, response.getStatusCode());
|
||||
assertTrue("Invalid ExpiresIn", 0 < response.getRefreshExpiresIn() && response.getRefreshExpiresIn() <= 3600);
|
||||
|
||||
// check refresh a second time
|
||||
response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1");
|
||||
assertEquals(200, response.getStatusCode());
|
||||
assertTrue("Invalid ExpiresIn", 0 < response.getRefreshExpiresIn() && response.getRefreshExpiresIn() <= 3600);
|
||||
} finally {
|
||||
changeOfflineSessionSettings(false, prevOfflineSession[0], prevOfflineSession[1], prevOfflineSession[2], prevOfflineSession[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user