Project

General

Profile

Bug #7559

MultipleObjectsReturned: get() returned more than one LibertySessionDump -- it returned 2!

Added by Frédéric Péters about 4 years ago. Updated over 1 year ago.

Status:
Fermé
Priority:
Normal
Category:
-
Target version:
Start date:
13 Jun 2015
Due date:
% Done:

100%

Patch proposed:
No
Planning:
No

Description

I am not sure how things happened, multiple concurrent SSO made twice the same object in saml_libertysessiondump. (the concurrent SSO were the result of calls to menu.json of various applications, when building the sidepage menu)

  File "/home/fred/src/eo/authentic/src/authentic2/idp/saml/saml2_endpoints.py", line 526, in sso
    return sso_after_process_request(request, login, nid_format=nid_format)
  File "/home/fred/src/eo/authentic/src/authentic2/idp/saml/saml2_endpoints.py", line 894, in sso_after_process_request
    load_session(request, login)
  File "/home/fred/src/eo/authentic/src/authentic2/saml/common.py", line 286, in load_session
    kind=kind)
...
MultipleObjectsReturned: get() returned more than one LibertySessionDump -- it returned 2!

I wondered if maybe it was because it reused an old session key but the id say otherwise.

authentic_multitenant=> select id from saml_libertysessiondump where django_session_key = 'jqpvw7iayben5i5a50epqk2jvjmhsmp4';
 id 
----
 30
 31

Associated revisions

Revision 8a4830c6 (diff)
Added by Benjamin Dauvergne about 4 years ago

saml: prevent creation of duplicate LibertySessionDump (fixes #7559)

By adding a unicity constraint we prevent .get() of ever raising a
MultipleObjectsReturned exception.

History

#1 Updated by Benjamin Dauvergne about 4 years ago

Bug is really difficult, get_or_create() which used to save LibertySessionDump is not safe without a postgresql configured with the serializable isolation level, default level being read commited, as read commited cannot prevent the phantom read problem (the two transactions check if a given row, the two returns none, but in fact after the first transaction commit the second transaction pre-state has changed, there is now a row matching the query but it won't see it, see1).

Adding an unicity constraint on (django_session_key, kind) could maybe alleviate the biggest problem, that is the load_session() failing. But when two concurrent save will happen one them may fail but I think django has a retry loop inside get_or_create() to prevent the problem in most cases.

.fn1 http://stackoverflow.com/questions/13374335/what-is-the-difference-between-serializable-and-repeatable-read-isolation-level http://www.postgresql.org/docs/9.1/static/transaction-iso.html

#2 Updated by Benjamin Dauvergne about 4 years ago

  • Target version set to 2.2.0

#3 Updated by Benjamin Dauvergne about 4 years ago

  • % Done changed from 0 to 100
  • Status changed from Nouveau to Résolu (à déployer)

#4 Updated by Benjamin Dauvergne about 4 years ago

  • Assignee set to Benjamin Dauvergne

#5 Updated by Benjamin Dauvergne over 3 years ago

  • Status changed from Résolu (à déployer) to Solution déployée

#6 Updated by Benjamin Dauvergne over 1 year ago

  • Status changed from Solution déployée to Fermé

Also available in: Atom PDF