root: implement automatic tryauth (#12867)

This commit is contained in:
Benjamin Dauvergne 2019-04-15 15:53:17 +02:00 committed by Serghei Mihai
parent 7d03a0859e
commit 7134680e7c
2 changed files with 60 additions and 2 deletions

View File

@ -443,3 +443,30 @@ def test_saml_idp_logout(pub):
saml2.slo_idp(urlparse.urlparse(logout.msgUrl).query)
assert req.response.headers['location'].startswith('http://sso.example.net/saml2/slo_return?SAMLResponse=')
assert req.session is None
def test_opened_session_cookie(pub):
app = get_app(pub)
app.set_cookie('IDP_OPENED_SESSION', '1')
resp = app.get('/')
assert resp.status_int == 200
pub.site_options.set('options', 'idp_session_cookie_name', 'IDP_OPENED_SESSION')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/?parameter=value')
assert 'secure' in resp.headers['Set-Cookie']
assert 'httponly' in resp.headers['Set-Cookie']
assert 'path=/' in resp.headers['Set-Cookie']
assert resp.status_int == 302
assert resp.location == 'http://example.net/login/?ReturnUrl=http%3A//example.net/%3Fparameter%3Dvalue&IsPassive=true'
cookie_name = '%s-passive-auth-tried' % pub.config.session_cookie_name
assert cookie_name in app.cookies
def test_no_opened_session_cookie(pub):
app = get_app(pub)
resp = app.get('/')
assert resp.status_int == 200
cookie_name = '%s-passive-auth-tried' % pub.config.session_cookie_name
assert cookie_name not in app.cookies

View File

@ -21,7 +21,7 @@ import re
from django.utils.six.moves.urllib import parse as urllib
from quixote import get_publisher, get_response, get_session, redirect, get_session_manager
from quixote import get_publisher, get_response, get_session, redirect, get_session_manager, get_request
from quixote.directory import Directory
from quixote.html import htmltext, TemplateIO
from quixote.util import StaticDirectory
@ -343,7 +343,38 @@ class RootDirectory(Directory):
except errors.TraversalError:
pass
return root.RootDirectory()._q_traverse(path)
output = root.RootDirectory()._q_traverse(path)
return self.automatic_sso(output)
def automatic_sso(self, output):
request = get_request()
response = get_response()
publisher = get_publisher()
OPENED_SESSION_COOKIE = publisher.get_site_option('idp_session_cookie_name')
PASSIVE_TRIED_COOKIE = '%s-passive-auth-tried' % publisher.config.session_cookie_name
if OPENED_SESSION_COOKIE not in request.cookies and PASSIVE_TRIED_COOKIE in request.cookies:
response.expire_cookie(PASSIVE_TRIED_COOKIE)
return output
elif OPENED_SESSION_COOKIE in request.cookies and PASSIVE_TRIED_COOKIE not in request.cookies:
ident_methods = get_cfg('identification', {}).get('methods', [])
idps = get_cfg('idp', {})
if request.user:
return output
if len(idps) != 1:
return output
if ident_methods and 'idp' not in ident_methods:
return output
response.set_cookie(PASSIVE_TRIED_COOKIE, '1', secure=1, httponly=1,
path=publisher.config.session_cookie_path,
domain=publisher.config.session_cookie_domain)
url = request.get_url()
query = request.get_query()
if query:
url += '?' + query
return root.tryauth(url)
else:
return output
def _q_lookup(self, component):
# is this a category ?