0001-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 | |
... | ... | |
600 | 601 |
cookie_store = http.cookies.SimpleCookie() |
601 | 602 |
cookie_store.load(resp.headers['Set-Cookie']) |
602 | 603 |
assert list(cookie_store.keys()) == [cookie_name] |
603 |
assert 'Secure' in resp.headers['Set-Cookie'] |
|
604 | 604 |
assert 'HttpOnly' in resp.headers['Set-Cookie'] |
605 | 605 |
assert 'SameSite=None' in resp.headers['Set-Cookie'] |
606 | 606 |
assert 'path=/' in resp.headers['Set-Cookie'] |
... | ... | |
611 | 611 |
) |
612 | 612 |
assert cookie_name in app.cookies |
613 | 613 | |
614 |
# if we try again, no passive authentication occurs |
|
615 |
resp = app.get('/?parameter=value') |
|
616 |
assert resp.status_int != 302 |
|
617 | ||
618 |
# if IDP_OPENED_SESSION is modified, then passive authentication is tried again |
|
619 |
app.set_cookie('IDP_OPENED_SESSION', '2') |
|
620 |
resp = app.get('/?parameter=value') |
|
621 |
assert resp.status_int == 302 |
|
622 | ||
623 |
# simulate a saml login |
|
624 |
user = pub.user_class() |
|
625 |
user.store() |
|
626 |
request = mock.Mock() |
|
627 |
request.get_environ.return_value = '1.1.1.1' |
|
628 |
with mock.patch('quixote.session.get_request', return_value=request), mock.patch( |
|
629 |
'wcs.qommon.saml2', return_value=mock.Mock(cookies={'IDP_OPENED_SESSION': '2'}) |
|
630 |
): |
|
631 |
session = get_session_manager().session_class(id=None) |
|
632 |
session.set_user(user.id) |
|
633 |
session.opened_session_value = '2' |
|
634 |
session.id = 'abcd' |
|
635 |
session.store() |
|
636 |
app.set_cookie(pub.config.session_cookie_name, session.id) |
|
637 |
assert get_session(app).opened_session_value == '2' |
|
638 | ||
639 |
resp = app.get('/?parameter=value') |
|
640 |
assert resp.status_int == 200 |
|
641 |
assert get_session(app).opened_session_value == '2' |
|
642 |
assert get_session(app).user == user.id |
|
643 |
# PASSIVE_TRIED_COOKIE was removed, since we logged in. |
|
644 |
assert cookie_name not in app.cookies |
|
645 | ||
646 |
# if OPENED_SESSION_COOKIE change then we are logged out |
|
647 |
app.set_cookie('IDP_OPENED_SESSION', '3') |
|
648 |
resp = app.get('/?parameter=value') |
|
649 |
assert not get_session(app) |
|
650 |
assert not get_session_manager().session_class.get(session.id, ignore_errors=True) |
|
651 | ||
614 | 652 | |
615 | 653 |
def test_no_opened_session_cookie(pub): |
616 | 654 |
app = get_app(pub) |
wcs/root.py | ||
---|---|---|
353 | 353 |
def _q_traverse(self, path): |
354 | 354 |
self.feed_substitution_parts() |
355 | 355 | |
356 |
output = self.try_passive_sso() |
|
357 |
if output: |
|
358 |
return output |
|
359 | ||
356 | 360 |
response = get_response() |
357 | 361 |
if not hasattr(response, 'filter'): |
358 | 362 |
response.filter = {} |
... | ... | |
370 | 374 |
except errors.TraversalError: |
371 | 375 |
pass |
372 | 376 | |
373 |
output = root.RootDirectory()._q_traverse(path) |
|
374 |
return self.automatic_sso(output) |
|
375 | ||
376 |
def automatic_sso(self, output): |
|
377 |
request = get_request() |
|
378 |
response = get_response() |
|
377 |
return root.RootDirectory()._q_traverse(path) |
|
379 | 378 | |
379 |
def try_passive_sso(self): |
|
380 | 380 |
publisher = get_publisher() |
381 | 381 |
OPENED_SESSION_COOKIE = publisher.get_site_option('idp_session_cookie_name') |
382 | 382 |
PASSIVE_TRIED_COOKIE = '%s-passive-auth-tried' % publisher.config.session_cookie_name |
383 |
if OPENED_SESSION_COOKIE not in request.cookies and PASSIVE_TRIED_COOKIE in request.cookies: |
|
383 | ||
384 |
if not OPENED_SESSION_COOKIE: |
|
385 |
return |
|
386 |
ident_methods = get_cfg('identification', {}).get('methods', []) |
|
387 |
idps = get_cfg('idp', {}) |
|
388 |
if len(idps) != 1: |
|
389 |
return |
|
390 |
if ident_methods and 'idp' not in ident_methods: |
|
391 |
return |
|
392 | ||
393 |
request = get_request() |
|
394 |
cookies = request.cookies |
|
395 |
response = get_response() |
|
396 | ||
397 |
# expire PASSIVE_TRIED_COOKIE if already logged or if not equal to PASSIVE_TRIED_COOKIE |
|
398 |
if PASSIVE_TRIED_COOKIE in cookies and ( |
|
399 |
request.user or cookies.get(PASSIVE_TRIED_COOKIE) != cookies.get(OPENED_SESSION_COOKIE) |
|
400 |
): |
|
384 | 401 |
response.expire_cookie(PASSIVE_TRIED_COOKIE) |
385 |
return output |
|
386 |
elif OPENED_SESSION_COOKIE in request.cookies and PASSIVE_TRIED_COOKIE not in request.cookies: |
|
387 |
ident_methods = get_cfg('identification', {}).get('methods', []) |
|
388 |
idps = get_cfg('idp', {}) |
|
389 |
if request.user: |
|
390 |
return output |
|
391 |
if len(idps) != 1: |
|
392 |
return output |
|
393 |
if ident_methods and 'idp' not in ident_methods: |
|
394 |
return output |
|
395 |
response.set_cookie( |
|
396 |
PASSIVE_TRIED_COOKIE, |
|
397 |
'1', |
|
398 |
secure=1, |
|
399 |
httponly=1, |
|
400 |
path=publisher.config.session_cookie_path, |
|
401 |
domain=publisher.config.session_cookie_domain, |
|
402 |
) |
|
403 |
url = request.get_url() |
|
404 |
query = request.get_query() |
|
405 |
if query: |
|
406 |
url += '?' + query |
|
407 |
return root.tryauth(url) |
|
408 |
else: |
|
409 |
return output |
|
402 | ||
403 |
if request.user: |
|
404 |
if request.session.opened_session_value and request.session.opened_session_value != cookies.get( |
|
405 |
OPENED_SESSION_COOKIE |
|
406 |
): |
|
407 |
# logout current user if saved value for OPENED_SESSION_COOKIE differs from the current one |
|
408 |
get_session_manager().expire_session() |
|
409 |
else: |
|
410 |
# already logged, stop here. |
|
411 |
return |
|
412 |
if OPENED_SESSION_COOKIE not in cookies or cookies.get(OPENED_SESSION_COOKIE) == cookies.get( |
|
413 |
PASSIVE_TRIED_COOKIE |
|
414 |
): |
|
415 |
# no session on the idp or passive sso already tried, stop here. |
|
416 |
return |
|
417 |
response.set_cookie( |
|
418 |
PASSIVE_TRIED_COOKIE, |
|
419 |
cookies.get(OPENED_SESSION_COOKIE), |
|
420 |
secure=request.scheme == 'https', |
|
421 |
httponly=1, |
|
422 |
path=publisher.config.session_cookie_path, |
|
423 |
domain=publisher.config.session_cookie_domain, |
|
424 |
) |
|
425 |
url = request.get_url() |
|
426 |
query = request.get_query() |
|
427 |
if query: |
|
428 |
url += '?' + query |
|
429 |
return root.tryauth(url) |
|
410 | 430 | |
411 | 431 |
def _q_lookup(self, component): |
412 | 432 |
# is this a category ? |
413 |
- |