Projet

Général

Profil

0002-idp_oidc-correctly-load-session-in-OIDCCode-and-OIDC.patch

Benjamin Dauvergne, 03 décembre 2020 09:53

Télécharger (4,1 ko)

Voir les différences:

Subject: [PATCH 2/5] idp_oidc: correctly load session in OIDCCode and
 OIDCAccessToken (#47900)

* access_token can be valid without a session or with a session linked to the user
* code is only valid with a live session linked to its user
* session was not loaded correctly, it's only loaded after accessing its
  content, and session_key is only checked if the session is loaded.
 src/authentic2_idp_oidc/models.py | 70 +++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 23 deletions(-)
src/authentic2_idp_oidc/models.py
293 293
            self.scopes)
294 294

  
295 295

  
296
class OIDCCode(models.Model):
296
def get_session(session_key):
297
    engine = import_module(settings.SESSION_ENGINE)
298
    session = engine.SessionStore(session_key=session_key)
299
    session.items()
300
    if session._session_key == session_key:
301
        return session
302
    return None
303

  
304

  
305
class SessionMixin(object):
306
    @property
307
    def session(self):
308
        if not hasattr(self, '_session'):
309
            if self.session_key:
310
                self._session = get_session(self.session_key)
311
            else:
312
                self._session = None
313
        return getattr(self, '_session', None)
314

  
315
    @session.setter
316
    def session(self, session):
317
        if session:
318
            self.session_key = session.session_key
319
            self._session = session
320
        else:
321
            self.session_key = ''
322
            self._session = None
323

  
324

  
325
class OIDCCode(SessionMixin, models.Model):
297 326
    uuid = models.CharField(
298 327
        max_length=128,
299 328
        verbose_name=_('uuid'),
......
332 361

  
333 362
    objects = managers.OIDCExpiredManager()
334 363

  
335
    @property
336
    def session(self):
337
        if not hasattr(self, '_session'):
338
            engine = import_module(settings.SESSION_ENGINE)
339
            session = engine.SessionStore(session_key=self.session_key)
340
            session.load()
341
            if session._session_key == self.session_key:
342
                self._session = session
343
        return getattr(self, '_session', None)
344

  
345 364
    def scope_set(self):
346 365
        return utils.scope_set(self.scopes)
347 366

  
348 367
    def is_valid(self):
349
        return self.expired >= now() and self.session is not None
368
        if self.expired < now():
369
            return False
370
        if not self.session:
371
            return False
372
        if self.session.get('_auth_user_id') != str(self.user_id):
373
            return False
374
        return True
350 375

  
351 376
    def __repr__(self):
352 377
        return '<OIDCCode uuid:%s client:%s user:%s expired:%s scopes:%s>' % (
......
357 382
            self.scopes)
358 383

  
359 384

  
360
class OIDCAccessToken(models.Model):
385
class OIDCAccessToken(SessionMixin, models.Model):
361 386
    uuid = models.CharField(
362 387
        max_length=128,
363 388
        verbose_name=_('uuid'),
......
389 414
    def scope_set(self):
390 415
        return utils.scope_set(self.scopes)
391 416

  
392
    @property
393
    def session(self):
394
        if not hasattr(self, '_session'):
395
            engine = import_module(settings.SESSION_ENGINE)
396
            session = engine.SessionStore(session_key=self.session_key)
397
            if session._session_key == self.session_key:
398
                self._session = session
399
        return getattr(self, '_session', None)
400

  
401 417
    def is_valid(self):
402
        return self.expired >= now() and self.session is not None
418
        if self.expired < now():
419
            return False
420
        if not self.session_key:
421
            return True
422
        if not self.session:
423
            return False
424
        if self.session.get('_auth_user_id') != str(self.user_id):
425
            return False
426
        return True
403 427

  
404 428
    def __repr__(self):
405 429
        return '<OIDCAccessToken uuid:%s client:%s user:%s expired:%s scopes:%s>' % (
406
-