utils: add method to build a session dump from models (#69740)
Storing the LassoSession dump in the Django session is no longer needed, we can rebuild it from the information in the models.
This commit is contained in:
parent
600c8cfbc0
commit
7f9602c528
|
@ -1,12 +1,5 @@
|
|||
<ns0:Session xmlns:ns0="http://www.entrouvert.org/namespaces/lasso/0.0" xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion" Version="2">
|
||||
{% for session_info in session_infos %}
|
||||
<ns0:NidAndSessionIndex AssertionID=""
|
||||
ProviderID="{{ session_info.entity_id }}"
|
||||
SessionIndex="{{ session_info.session_index }}">
|
||||
<ns1:NameID Format="{{ session_info.name_id_format }}"
|
||||
{% if session_info.name_id_name_qualifier %}NameQualifier="{{ session_info.name_id_name_qualifier }}"{% endif %}
|
||||
{% if session_info.name_id_sp_name_qualifier %}SPNameQualifier="{{ session_info.name_id_sp_name_qualifier }}"{% endif %}
|
||||
>{{ session_info.name_id_content }}</ns1:NameID>
|
||||
</ns0:NidAndSessionIndex>
|
||||
{% endfor %}
|
||||
<ns0:Session xmlns:ns0="http://www.entrouvert.org/namespaces/lasso/0.0" xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion" Version="2">{% for session_index in session_indexes %}{% with nameid=session_index.saml_identifier %}
|
||||
<ns0:NidAndSessionIndex AssertionID="" ProviderID="{{ nameid.issuer.entity_id }}" SessionIndex="{{ session_index.session_index }}">
|
||||
<ns1:NameID Format="{{ nameid.nid_format }}"{% if nameid.nid_name_qualifier %} NameQualifier="{{ nameid.nid_name_qualifier }}"{% endif %}{% if nameid.nid_sp_name_qualifier %} SPNameQualifier="{{ nameid.nid_sp_name_qualifier }}"{% endif %}{% if nameid.nid_sp_provided_id %} SPProvidedId="{{ nameid.nid_sp_provided_id}}"{% endif %}>{{ nameid.name_id }}</ns1:NameID>
|
||||
</ns0:NidAndSessionIndex>{% endwith %}{% endfor %}
|
||||
</ns0:Session>
|
||||
|
|
|
@ -211,26 +211,8 @@ def get_setting(idp, name, default=None):
|
|||
return idp.get(name) or getattr(app_settings, name, default)
|
||||
|
||||
|
||||
def make_session_dump(lasso_name_id, indexes):
|
||||
session_infos = []
|
||||
name_id = force_str(lasso_name_id.content)
|
||||
name_id_format = force_str(lasso_name_id.format)
|
||||
name_qualifier = lasso_name_id.nameQualifier and force_str(lasso_name_id.nameQualifier)
|
||||
sp_name_qualifier = lasso_name_id.spNameQualifier and force_str(lasso_name_id.spNameQualifier)
|
||||
for index in indexes:
|
||||
issuer = index.saml_identifier.issuer.entity_id
|
||||
session_infos.append(
|
||||
{
|
||||
'entity_id': issuer,
|
||||
'session_index': index.session_index,
|
||||
'name_id_content': name_id,
|
||||
'name_id_format': name_id_format,
|
||||
'name_id_name_qualifier': name_qualifier,
|
||||
'name_id_sp_name_qualifier': sp_name_qualifier,
|
||||
}
|
||||
)
|
||||
session_dump = render_to_string('mellon/session_dump.xml', {'session_infos': session_infos})
|
||||
return session_dump
|
||||
def make_session_dump(session_indexes):
|
||||
return render_to_string('mellon/session_dump.xml', {'session_indexes': session_indexes})
|
||||
|
||||
|
||||
def create_logout(request):
|
||||
|
|
|
@ -318,8 +318,6 @@ class LoginView(ProfileMixin, LogMixin, View):
|
|||
else:
|
||||
self.log.warning('no user found for NameID %r', attributes['name_id_content'])
|
||||
return self.render(request, 'mellon/user_not_found.html', {'saml_attributes': attributes})
|
||||
request.session['lasso_session_dump'] = login.session.dump()
|
||||
|
||||
return HttpResponseRedirect(next_url)
|
||||
|
||||
def render_debug_template(self, request, login, attributes=None):
|
||||
|
@ -698,7 +696,7 @@ class LogoutView(ProfileMixin, LogMixin, View):
|
|||
indexes = indexes.filter(session_index__in=session_indexes)
|
||||
|
||||
# lasso has too much state :/
|
||||
logout.setSessionFromDump(utils.make_session_dump(logout.nameIdentifier, indexes))
|
||||
logout.setSessionFromDump(utils.make_session_dump(indexes))
|
||||
|
||||
try:
|
||||
logout.validateRequest()
|
||||
|
@ -743,10 +741,14 @@ class LogoutView(ProfileMixin, LogMixin, View):
|
|||
self.profile = logout = utils.create_logout(request)
|
||||
self.get_relay_state(create=True)
|
||||
try:
|
||||
if 'lasso_session_dump' in request.session:
|
||||
logout.setSessionFromDump(request.session['lasso_session_dump'])
|
||||
else:
|
||||
session_indexes = models.SessionIndex.objects.filter(
|
||||
saml_identifier__user=request.user, saml_identifier__issuer__entity_id=issuer
|
||||
).order_by('-id')[:1]
|
||||
if not session_indexes:
|
||||
self.log.error('unable to find lasso session dump')
|
||||
else:
|
||||
session_dump = utils.make_session_dump(session_indexes)
|
||||
logout.setSessionFromDump(session_dump)
|
||||
logout.initRequest(issuer, lasso.HTTP_METHOD_REDIRECT)
|
||||
logout.buildRequestMsg()
|
||||
except lasso.Error as e:
|
||||
|
|
|
@ -270,7 +270,7 @@ def test_sso_slo_next(db, app, idp, caplog, sp_settings):
|
|||
assert response.location == '/some/path/'
|
||||
|
||||
|
||||
def test_sso_slo_default_next_url(db, app, idp, caplog, sp_settings, rf):
|
||||
def test_sso_slo_default_next_url(db, app, idp, caplog, sp_settings, rf, django_user_model):
|
||||
from mellon.views import logout
|
||||
|
||||
response = app.get(reverse('mellon_login'))
|
||||
|
@ -279,8 +279,7 @@ def test_sso_slo_default_next_url(db, app, idp, caplog, sp_settings, rf):
|
|||
|
||||
request = rf.get('/logout/')
|
||||
request.session = app.session
|
||||
request.user = mock.Mock()
|
||||
request.user.is_authenticated = True
|
||||
request.user = django_user_model.objects.get()
|
||||
response = logout(request, logout_next_url='/other/path/')
|
||||
assert list(request.session.values()) == ['/other/path/']
|
||||
|
||||
|
@ -290,8 +289,7 @@ def test_sso_slo_default_next_url(db, app, idp, caplog, sp_settings, rf):
|
|||
|
||||
request = rf.get('/logout/?next=/some/path/')
|
||||
request.session = app.session
|
||||
request.user = mock.Mock()
|
||||
request.user.is_authenticated = True
|
||||
request.user = django_user_model.objects.get()
|
||||
response = logout(request, logout_next_url='/other/path/')
|
||||
assert list(request.session.values()) == ['/some/path/']
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ from xml_utils import assert_xml_constraints
|
|||
|
||||
from mellon.models import Issuer
|
||||
from mellon.models_utils import get_issuer
|
||||
from mellon.utils import create_metadata, flatten_datetime, iso8601_to_datetime
|
||||
from mellon.utils import create_metadata, flatten_datetime, iso8601_to_datetime, make_session_dump
|
||||
from mellon.views import check_next_url
|
||||
|
||||
|
||||
|
@ -236,3 +236,30 @@ def test_get_issuer_entity_id_migration(db, settings, metadata):
|
|||
assert issuer3.id == issuer1.id
|
||||
assert issuer3.entity_id == entity_id2
|
||||
assert issuer3.slug == 'idp'
|
||||
|
||||
|
||||
def test_make_session_dump(db, django_user_model):
|
||||
from mellon.models import SessionIndex, UserSAMLIdentifier
|
||||
|
||||
user = django_user_model.objects.create(username='user')
|
||||
issuer = Issuer.objects.create(entity_id='https://idp.example.com/metadata', slug='idp')
|
||||
saml_identifier = UserSAMLIdentifier.objects.create(
|
||||
user=user, name_id='1234', issuer=issuer, nid_format=lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT
|
||||
)
|
||||
|
||||
for i in range(2):
|
||||
SessionIndex.objects.create(session_index=str(i), saml_identifier=saml_identifier, session_key='abcd')
|
||||
|
||||
assert (
|
||||
make_session_dump(saml_identifier.sessionindex_set.all())
|
||||
== '''\
|
||||
<ns0:Session xmlns:ns0="http://www.entrouvert.org/namespaces/lasso/0.0" xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion" Version="2">
|
||||
<ns0:NidAndSessionIndex AssertionID="" ProviderID="https://idp.example.com/metadata" SessionIndex="0">
|
||||
<ns1:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">1234</ns1:NameID>
|
||||
</ns0:NidAndSessionIndex>
|
||||
<ns0:NidAndSessionIndex AssertionID="" ProviderID="https://idp.example.com/metadata" SessionIndex="1">
|
||||
<ns1:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">1234</ns1:NameID>
|
||||
</ns0:NidAndSessionIndex>
|
||||
</ns0:Session>
|
||||
'''
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue