summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mellon/middleware.py19
-rw-r--r--mellon/views.py7
-rw-r--r--tests/test_sso_slo.py23
3 files changed, 44 insertions, 5 deletions
diff --git a/mellon/middleware.py b/mellon/middleware.py
index 0bcd59f..2d69b80 100644
--- a/mellon/middleware.py
+++ b/mellon/middleware.py
@@ -14,6 +14,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+from django.contrib import auth
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin
@@ -58,11 +59,21 @@ class PassiveAuthenticationMiddleware(MiddlewareMixin):
if not app_settings.OPENED_SESSION_COOKIE_NAME:
return
if hasattr(request, 'user') and request.user.is_authenticated:
- return
- if PASSIVE_TRIED_COOKIE in request.COOKIES:
- return
+ old_opened_session_cookie = request.session.get('mellon_opened_session_cookie')
+ if old_opened_session_cookie and old_opened_session_cookie != request.COOKIES.get(
+ app_settings.OPENED_SESSION_COOKIE_NAME
+ ):
+ # close current session if the opened session cookie changed...
+ auth.logout(request)
+ # and continue with unlogged behaviour
+ else:
+ # otherwise, if current session is still active, do nothing
+ return
if app_settings.OPENED_SESSION_COOKIE_NAME not in request.COOKIES:
return
+ opened_session_cookie = request.COOKIES[app_settings.OPENED_SESSION_COOKIE_NAME]
+ if request.COOKIES.get(PASSIVE_TRIED_COOKIE) == opened_session_cookie:
+ return
# all is good, try passive login
params = {
'next': request.build_absolute_uri(),
@@ -71,5 +82,5 @@ class PassiveAuthenticationMiddleware(MiddlewareMixin):
url = reverse('mellon_login') + '?%s' % urlencode(params)
response = HttpResponseRedirect(url)
# prevent loops
- response.set_cookie(PASSIVE_TRIED_COOKIE, value='1', max_age=None)
+ response.set_cookie(PASSIVE_TRIED_COOKIE, value=opened_session_cookie, max_age=None)
return response
diff --git a/mellon/views.py b/mellon/views.py
index 67f5873..e993378 100644
--- a/mellon/views.py
+++ b/mellon/views.py
@@ -335,6 +335,13 @@ class LoginView(ProfileMixin, LogMixin, View):
return
utils.login(self.request, user)
+ if (
+ app_settings.OPENED_SESSION_COOKIE_NAME
+ and app_settings.OPENED_SESSION_COOKIE_NAME in self.request.COOKIES
+ ):
+ self.request.session['mellon_opened_session_cookie'] = self.request.COOKIES[
+ app_settings.OPENED_SESSION_COOKIE_NAME
+ ]
session_index = attributes['session_index']
if session_index:
if not self.request.session.session_key:
diff --git a/tests/test_sso_slo.py b/tests/test_sso_slo.py
index 7eb5fae..3fd86f3 100644
--- a/tests/test_sso_slo.py
+++ b/tests/test_sso_slo.py
@@ -676,13 +676,14 @@ def test_passive_auth_middleware_ok(db, app, idp, caplog, settings):
settings.MELLON_OPENED_SESSION_COOKIE_NAME = 'IDP_SESSION'
assert 'MELLON_PASSIVE_TRIED' not in app.cookies
# webtest-lint is against unicode
- app.set_cookie('IDP_SESSION', '1')
+ app.set_cookie('IDP_SESSION', '1234')
response = app.get('/', headers={'Accept': 'text/html'}, status=302)
assert urlparse.urlparse(response.location).path == '/login/'
assert urlparse.parse_qs(urlparse.urlparse(response.location).query, keep_blank_values=True) == {
'next': ['http://testserver/'],
'passive': [''],
}
+ assert app.cookies['MELLON_PASSIVE_TRIED'] == '1234'
# simulate closing of session at IdP
app.cookiejar.clear('testserver.local', '/', 'IDP_SESSION')
@@ -703,6 +704,26 @@ def test_passive_auth_middleware_ok(db, app, idp, caplog, settings):
}
assert 'MELLON_PASSIVE_TRIED' in app.cookies
+ # but not two times
+ response = app.get('/', headers={'Accept': 'text/html'}, status=200)
+ # if session change at IdP
+ app.set_cookie('IDP_SESSION', 'abcd')
+ # then we try again...
+ response = app.get('/', headers={'Accept': 'text/html'}, status=302)
+
+ # ok, let's change again and login
+ app.set_cookie('IDP_SESSION', '5678')
+ response = app.get(reverse('mellon_login') + '?next=/whatever/')
+ url, body, relay_state = idp.process_authn_request_redirect(response['Location'])
+ response = app.post(reverse('mellon_login'), params={'SAMLResponse': body, 'RelayState': relay_state})
+ assert app.session['mellon_opened_session_cookie'] == '5678'
+ assert '_auth_user_id' in app.session
+ # ok change the idp session id
+ app.set_cookie('IDP_SESSION', '1234')
+ # if we try a request, we are logged out and redirected to try a new passive login
+ response = app.get('/', headers={'Accept': 'text/html'}, status=302)
+ assert '_auth_user_id' not in app.session
+
def test_passive_auth_middleware_no_passive_auth_parameter(db, app, idp, caplog, settings):
settings.MELLON_OPENED_SESSION_COOKIE_NAME = 'IDP_SESSION'