add a remember me button (fixes #25579)

It simply use session.set_expiry() to augment the session duration.
This commit is contained in:
Benjamin Dauvergne 2018-08-03 17:12:30 +02:00
parent 7cdda30e99
commit 99a7b14bf0
6 changed files with 60 additions and 1 deletions

View File

@ -193,6 +193,10 @@ default_settings = dict(
default={},
definition='Exclusion filter (as in QuerySet.exclude() to apply to User queryset before '
'authentication'),
A2_USER_REMEMBER_ME=Setting(
default=None,
definition='Session duration as seconds when using the remember me '
'checkbox. Truthiness activates the checkbox.'),
A2_LOGIN_REDIRECT_AUTHENTICATED_USERS_TO_HOMEPAGE=Setting(
default=False,
definition='Redirect authenticated users to homepage'),

View File

@ -34,6 +34,9 @@ class LoginPasswordBackend(object):
how = 'password-on-https'
else:
how = 'password'
if form.cleaned_data.get('remember_me'):
request.session['remember_me'] = True
request.session.set_expiry(app_settings.A2_USER_REMEMBER_ME)
return utils.login(request, form.get_user(), how,
service_slug=request.GET.get(constants.SERVICE_FIELD_NAME))
context['form'] = form

View File

@ -159,6 +159,11 @@ def modelform_factory(model, **kwargs):
class AuthenticationForm(auth_forms.AuthenticationForm):
password = PasswordField(label=_('Password'))
remember_me = forms.BooleanField(
initial=False,
required=False,
label=_('Remember me'),
help_text=_('Do not ask for authentication next time'))
def __init__(self, *args, **kwargs):
super(AuthenticationForm, self).__init__(*args, **kwargs)
@ -167,6 +172,9 @@ class AuthenticationForm(auth_forms.AuthenticationForm):
duration=app_settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_DURATION,
factor=app_settings.A2_LOGIN_EXPONENTIAL_RETRY_TIMEOUT_FACTOR)
if not app_settings.A2_USER_REMEMBER_ME:
del self.fields['remember_me']
if self.request:
self.remote_addr = self.request.META['REMOTE_ADDR']
else:

View File

@ -76,3 +76,44 @@ def test_encoded_utf8_in_next_url(app, db):
response = response.follow()
needle = 'next=%s' % quote(url)
assert needle in response.content
def test_session_expire(app, simple_user, freezer):
freezer.move_to('2018-01-01')
# Verify session work as usual
login(app, simple_user)
response = app.get('/')
assert simple_user.first_name in response
freezer.move_to('2018-01-15')
response = app.get('/')
assert simple_user.first_name not in response
def test_session_remember_me_ok(app, settings, simple_user, freezer):
settings.A2_USER_REMEMBER_ME = 3600 * 24 * 30
freezer.move_to('2018-01-01')
# Verify session are longer
login(app, simple_user, remember_me=True)
response = app.get('/')
assert simple_user.first_name in response
# less than 30 days, session is still alive
freezer.move_to('2018-01-30')
response = app.get('/')
assert simple_user.first_name in response
def test_session_remember_me_nok(app, settings, simple_user, freezer):
settings.A2_USER_REMEMBER_ME = 3600 * 24 * 30
freezer.move_to('2018-01-01')
# Verify session are longer
login(app, simple_user, remember_me=True)
response = app.get('/')
assert simple_user.first_name in response
# more than 30 days, session is dead
freezer.move_to('2018-01-31')
response = app.get('/')
assert simple_user.first_name not in response

View File

@ -16,7 +16,7 @@ skipif_sqlite = pytest.mark.skipif('sqlite' in settings.DATABASES['default']['EN
reason='this test does not work with sqlite')
def login(app, user, path=None, password=None):
def login(app, user, path=None, password=None, remember_me=None):
if path:
login_page = app.get(path, status=302).maybe_follow()
else:
@ -26,6 +26,8 @@ def login(app, user, path=None, password=None):
form.set('username', user.username if hasattr(user, 'username') else user)
# password is supposed to be the same as username
form.set('password', password or user.username)
if remember_me is not None:
form.set('remember_me', bool(remember_me))
response = form.submit(name='login-password-submit').follow()
if path:
assert response.request.path == path

View File

@ -43,6 +43,7 @@ deps =
pyquery
httmock
pytz
pytest-freezegun
commands =
./getlasso.sh
authentic: py.test {env:FAST:} {env:REUSEDB:} {env:COVERAGE:} {posargs:tests/ --random}