Skip to content

Commit a349040

Browse files
committed
feat(revoke-token): on login, if there already is a oc_user_oidc_sessions row with the SID, update it
Signed-off-by: Julien Veyssier <[email protected]>
1 parent aa3978a commit a349040

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

lib/Controller/LoginController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ public function code(string $state = '', string $code = '', string $scope = '',
610610
// for backchannel logout
611611
try {
612612
$authToken = $this->authTokenProvider->getToken($this->session->getId());
613-
$this->sessionMapper->createSession(
613+
$this->sessionMapper->createOrUpdateSession(
614614
$idTokenPayload->sid ?? 'fallback-sid',
615615
$idTokenPayload->sub ?? 'fallback-sub',
616616
$idTokenPayload->iss ?? 'fallback-iss',

lib/Db/SessionMapper.php

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,41 +157,57 @@ public function cleanupSessions(int $minCreationTimestamp): void {
157157
}
158158

159159
/**
160-
* Create a session
160+
* Create or update a Nextcloud Oidc session
161+
*
162+
* We have a unique constraint on the "sid" column because there cannot be multiple Nextcloud Oidc sessions for the same IdP session (sid)
163+
* So if we log in with an IdP session that was already used in a previous Nextcloud Oidc session, we can safely assume
164+
* the related real Nextcloud session does not exist anymore. So we update the row for this "sid".
165+
*
166+
* In short: If there are multiple Nextcloud logins using the same IdP session, we only store the last one
161167
*
162168
* @param string $sid
163169
* @param string $sub
164170
* @param string $iss
165171
* @param int $authtokenId
166-
* @param string $ncSessionid
172+
* @param string $ncSessionId
167173
* @param string $idToken
168174
* @param string $userId
169175
* @param int $providerId
170176
* @param bool $idpSessionClosed
171177
* @return Session|null
172178
* @throws Exception
173179
*/
174-
public function createSession(
175-
string $sid, string $sub, string $iss, int $authtokenId, string $ncSessionid,
180+
public function createOrUpdateSession(
181+
string $sid, string $sub, string $iss, int $authtokenId, string $ncSessionId,
176182
string $idToken, string $userId, int $providerId, bool $idpSessionClosed = false,
177183
): ?Session {
184+
$createdAt = (new DateTime())->getTimestamp();
185+
178186
try {
179187
// do not create if one with same sid already exists (which should not happen)
180-
return $this->findSessionBySid($sid);
188+
$existingSession = $this->findSessionBySid($sid);
189+
$existingSession->setSub($sub);
190+
$existingSession->setIss($iss);
191+
$existingSession->setAuthtokenId($authtokenId);
192+
$existingSession->setNcSessionId($ncSessionId);
193+
$existingSession->setCreatedAt($createdAt);
194+
$existingSession->setIdToken($this->crypto->encrypt($idToken));
195+
$existingSession->setUserId($userId);
196+
$existingSession->setProviderId($providerId);
197+
$existingSession->setIdpSessionClosed($idpSessionClosed ? 1 : 0);
198+
return $this->update($existingSession);
181199
} catch (MultipleObjectsReturnedException $e) {
182200
// this can't happen
183201
return null;
184202
} catch (DoesNotExistException $e) {
185203
}
186204

187-
$createdAt = (new DateTime())->getTimestamp();
188-
189205
$session = new Session();
190206
$session->setSid($sid);
191207
$session->setSub($sub);
192208
$session->setIss($iss);
193209
$session->setAuthtokenId($authtokenId);
194-
$session->setNcSessionId($ncSessionid);
210+
$session->setNcSessionId($ncSessionId);
195211
$session->setCreatedAt($createdAt);
196212
$session->setIdToken($this->crypto->encrypt($idToken));
197213
$session->setUserId($userId);

0 commit comments

Comments
 (0)