0002-misc-retry-passive-sso-when-session-expire-and-logou.patch
tests/test_saml_auth.py | ||
---|---|---|
22 | 22 |
from wcs.qommon.misc import get_lasso_server |
23 | 23 |
from wcs.qommon.saml2 import Saml2Directory, SOAPException |
24 | 24 | |
25 |
from .test_fc_auth import get_session |
|
25 | 26 |
from .test_hobo_notify import PROFILE |
26 | 27 |
from .utilities import clean_temporary_pub, create_temporary_pub, get_app |
27 | 28 | |
... | ... | |
604 | 605 |
cookie_store = http.cookies.SimpleCookie() |
605 | 606 |
cookie_store.load(resp.headers['Set-Cookie']) |
606 | 607 |
assert list(cookie_store.keys()) == [cookie_name] |
607 |
assert 'Secure' in resp.headers['Set-Cookie'] |
|
608 | 608 |
assert 'HttpOnly' in resp.headers['Set-Cookie'] |
609 | 609 |
assert 'SameSite=None' in resp.headers['Set-Cookie'] |
610 | 610 |
assert 'path=/' in resp.headers['Set-Cookie'] |
... | ... | |
615 | 615 |
) |
616 | 616 |
assert cookie_name in app.cookies |
617 | 617 | |
618 |
# if we try again, no passive authentication occurs |
|
619 |
resp = app.get('/?parameter=value') |
|
620 |
assert resp.status_int != 302 |
|
621 | ||
622 |
# if IDP_OPENED_SESSION is modified, then passive authentication is tried again |
|
623 |
app.set_cookie('IDP_OPENED_SESSION', '2') |
|
624 |
resp = app.get('/?parameter=value') |
|
625 |
assert resp.status_int == 302 |
|
626 | ||
627 |
# simulate a saml login |
|
628 |
user = pub.user_class() |
|
629 |
user.store() |
|
630 |
request = mock.Mock() |
|
631 |
request.get_environ.return_value = '1.1.1.1' |
|
632 |
with mock.patch('quixote.session.get_request', return_value=request), mock.patch( |
|
633 |
'wcs.qommon.saml2', return_value=mock.Mock(cookies={'IDP_OPENED_SESSION': '2'}) |
|
634 |
): |
|
635 |
session = get_session_manager().session_class(id=None) |
|
636 |
session.set_user(user.id) |
|
637 |
session.opened_session_value = '2' |
|
638 |
session.id = 'abcd' |
|
639 |
session.store() |
|
640 |
app.set_cookie(pub.config.session_cookie_name, session.id) |
|
641 |
assert get_session(app).opened_session_value == '2' |
|
642 | ||
643 |
resp = app.get('/?parameter=value') |
|
644 |
assert resp.status_int == 200 |
|
645 |
assert get_session(app).opened_session_value == '2' |
|
646 |
assert get_session(app).user == user.id |
|
647 |
# PASSIVE_TRIED_COOKIE was removed, since we logged in. |
|
648 |
assert cookie_name not in app.cookies |
|
649 | ||
650 |
# if OPENED_SESSION_COOKIE change then we are logged out |
|
651 |
app.set_cookie('IDP_OPENED_SESSION', '3') |
|
652 |
resp = app.get('/?parameter=value') |
|
653 |
assert not get_session(app) |
|
654 |
assert not get_session_manager().session_class.get(session.id, ignore_errors=True) |
|
655 | ||
618 | 656 | |
619 | 657 |
def test_no_opened_session_cookie(pub): |
620 | 658 |
app = get_app(pub) |
wcs/root.py | ||
---|---|---|
287 | 287 |
self.forced_language = False |
288 | 288 |
self.feed_substitution_parts() |
289 | 289 | |
290 |
output = self.try_passive_sso() |
|
291 |
if output: |
|
292 |
return output |
|
293 | ||
290 | 294 |
response = get_response() |
291 | 295 |
if not hasattr(response, 'filter'): |
292 | 296 |
response.filter = {} |
... | ... | |
304 | 308 |
except errors.TraversalError: |
305 | 309 |
pass |
306 | 310 | |
307 |
output = root.RootDirectory()._q_traverse(path) |
|
308 |
return self.automatic_sso(output) |
|
309 | ||
310 |
def automatic_sso(self, output): |
|
311 |
request = get_request() |
|
312 |
response = get_response() |
|
311 |
return root.RootDirectory()._q_traverse(path) |
|
313 | 312 | |
313 |
def try_passive_sso(self): |
|
314 | 314 |
publisher = get_publisher() |
315 | 315 |
OPENED_SESSION_COOKIE = publisher.get_site_option('idp_session_cookie_name') |
316 | 316 |
PASSIVE_TRIED_COOKIE = '%s-passive-auth-tried' % publisher.config.session_cookie_name |
317 |
if OPENED_SESSION_COOKIE not in request.cookies and PASSIVE_TRIED_COOKIE in request.cookies: |
|
317 | ||
318 |
if not OPENED_SESSION_COOKIE: |
|
319 |
return |
|
320 |
ident_methods = get_cfg('identification', {}).get('methods', []) |
|
321 |
idps = get_cfg('idp', {}) |
|
322 |
if len(idps) != 1: |
|
323 |
return |
|
324 |
if ident_methods and 'idp' not in ident_methods: |
|
325 |
return |
|
326 | ||
327 |
request = get_request() |
|
328 |
cookies = request.cookies |
|
329 |
response = get_response() |
|
330 | ||
331 |
# expire PASSIVE_TRIED_COOKIE if already logged or if not equal to PASSIVE_TRIED_COOKIE |
|
332 |
if PASSIVE_TRIED_COOKIE in cookies and ( |
|
333 |
request.user or cookies.get(PASSIVE_TRIED_COOKIE) != cookies.get(OPENED_SESSION_COOKIE) |
|
334 |
): |
|
318 | 335 |
response.expire_cookie(PASSIVE_TRIED_COOKIE) |
319 |
return output |
|
320 |
elif OPENED_SESSION_COOKIE in request.cookies and PASSIVE_TRIED_COOKIE not in request.cookies: |
|
321 |
ident_methods = get_cfg('identification', {}).get('methods', []) |
|
322 |
idps = get_cfg('idp', {}) |
|
323 |
if request.user: |
|
324 |
return output |
|
325 |
if len(idps) != 1: |
|
326 |
return output |
|
327 |
if ident_methods and 'idp' not in ident_methods: |
|
328 |
return output |
|
329 |
response.set_cookie( |
|
330 |
PASSIVE_TRIED_COOKIE, |
|
331 |
'1', |
|
332 |
secure=1, |
|
333 |
httponly=1, |
|
334 |
path=publisher.config.session_cookie_path, |
|
335 |
domain=publisher.config.session_cookie_domain, |
|
336 |
) |
|
337 |
url = request.get_url() |
|
338 |
query = request.get_query() |
|
339 |
if query: |
|
340 |
url += '?' + query |
|
341 |
return root.tryauth(url) |
|
342 |
else: |
|
343 |
return output |
|
336 | ||
337 |
if request.user: |
|
338 |
if request.session.opened_session_value and request.session.opened_session_value != cookies.get( |
|
339 |
OPENED_SESSION_COOKIE |
|
340 |
): |
|
341 |
# logout current user if saved value for OPENED_SESSION_COOKIE differs from the current one |
|
342 |
get_session_manager().expire_session() |
|
343 |
else: |
|
344 |
# already logged, stop here. |
|
345 |
return |
|
346 |
if OPENED_SESSION_COOKIE not in cookies or cookies.get(OPENED_SESSION_COOKIE) == cookies.get( |
|
347 |
PASSIVE_TRIED_COOKIE |
|
348 |
): |
|
349 |
# no session on the idp or passive sso already tried, stop here. |
|
350 |
return |
|
351 |
response.set_cookie( |
|
352 |
PASSIVE_TRIED_COOKIE, |
|
353 |
cookies.get(OPENED_SESSION_COOKIE), |
|
354 |
secure=request.scheme == 'https', |
|
355 |
httponly=1, |
|
356 |
path=publisher.config.session_cookie_path, |
|
357 |
domain=publisher.config.session_cookie_domain, |
|
358 |
) |
|
359 |
url = request.get_url() |
|
360 |
query = request.get_query() |
|
361 |
if query: |
|
362 |
url += '?' + query |
|
363 |
return root.tryauth(url) |
|
344 | 364 | |
345 | 365 |
def _q_lookup(self, component): |
346 | 366 |
if ( |
347 |
- |