utils: add function get_authentication_events (#32780)

This commit is contained in:
Benjamin Dauvergne 2019-05-03 15:55:23 +02:00
parent eeb809fbeb
commit b7d0c63b6b
4 changed files with 31 additions and 8 deletions

View File

@ -381,15 +381,14 @@ def record_authentication_event(request, how, nonce=None):
def find_authentication_event(request, nonce):
'''Find an authentication event occurring during this session and matching
this nonce.'''
authentication_events = request.session.get(constants.AUTHENTICATION_EVENTS_SESSION_KEY, [])
for event in authentication_events:
for event in get_authentication_events(request=request):
if event.get('nonce') == nonce:
return event
return None
def last_authentication_event(session):
authentication_events = session.get(constants.AUTHENTICATION_EVENTS_SESSION_KEY, [])
def last_authentication_event(request=None, session=None):
authentication_events = get_authentication_events(request=request, session=session)
if authentication_events:
return authentication_events[-1]
return None
@ -1120,3 +1119,11 @@ def lazy_label(default, func):
'''
return encoding.force_text(func() or default)
lazy_label = allow_lazy(lazy_label, six.text_type)
def get_authentication_events(request=None, session=None):
if request is not None and session is None:
session = getattr(request, 'session', None)
if session is not None:
return session.get(constants.AUTHENTICATION_EVENTS_SESSION_KEY, [])
return []

View File

@ -188,7 +188,7 @@ def authorize(request, *args, **kwargs):
# is raised and handled by ServiceAccessMiddleware
client.authorize(request.user)
last_auth = last_authentication_event(request.session)
last_auth = last_authentication_event(request=request)
if max_age is not None and time.time() - last_auth['when'] >= max_age:
if 'none' in prompt:
return authorization_error(request, redirect_uri, 'login_required',
@ -392,7 +392,7 @@ def token(request, *args, **kwargs):
expired=oidc_code.created + datetime.timedelta(seconds=expires_in))
start = now()
acr = '0'
if (oidc_code.nonce is not None and last_authentication_event(oidc_code.session).get('nonce') ==
if (oidc_code.nonce is not None and last_authentication_event(session=oidc_code.session).get('nonce') ==
oidc_code.nonce):
acr = '1'
# prefill id_token with user info

View File

@ -344,7 +344,7 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url,
assert user.attributes.last_name == 'Doe'
assert AttributeValue.objects.filter(content='John', verified=True).count() == 1
assert AttributeValue.objects.filter(content='Doe', verified=False).count() == 1
assert last_authentication_event(app.session)['nonce'] == nonce
assert last_authentication_event(session=app.session)['nonce'] == nonce
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code,
extra_user_info={'family_name_verified': True}, nonce=nonce):

View File

@ -1,4 +1,8 @@
from authentic2.utils import good_next_url, same_origin, select_next_url, user_can_change_password
from django.contrib.auth import authenticate
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.contrib.sessions.middleware import SessionMiddleware
from authentic2.utils import good_next_url, same_origin, select_next_url, user_can_change_password, login, get_authentication_events
def test_good_next_url(rf, settings):
@ -52,3 +56,15 @@ def test_user_can_change_password(simple_user, settings):
assert user_can_change_password(user=simple_user) is True
settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD = False
assert user_can_change_password(user=simple_user) is False
def test_get_authentication_events_hows(rf, simple_user):
user = authenticate(username=simple_user.username, password=simple_user.username)
request = rf.get('/login/')
middleware = SessionMiddleware()
middleware.process_request(request)
middleware = AuthenticationMiddleware()
middleware.process_request(request)
assert 'password' not in [ev['how'] for ev in get_authentication_events(request)]
login(request, user, 'password')
assert 'password' in [ev['how'] for ev in get_authentication_events(request)]