forked from CGM_Public/pretix_original
Compare commits
4 Commits
ci-postgre
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc736e8548 | ||
|
|
8655486a58 | ||
|
|
9d410f33a0 | ||
|
|
c236144c68 |
@@ -8,6 +8,8 @@ tests:
|
||||
- XDG_CACHE_HOME=/cache bash .travis.sh tests
|
||||
tags:
|
||||
- python3
|
||||
except:
|
||||
- pypi
|
||||
pypi:
|
||||
stage: release
|
||||
script:
|
||||
@@ -22,7 +24,7 @@ pypi:
|
||||
tags:
|
||||
- python3
|
||||
only:
|
||||
- release
|
||||
- pypi
|
||||
artifacts:
|
||||
paths:
|
||||
- src/dist/
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "1.9.0"
|
||||
__version__ = "1.9.1"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import time
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import logout
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.permissions import SAFE_METHODS, BasePermission
|
||||
|
||||
@@ -21,6 +25,18 @@ class EventPermission(BasePermission):
|
||||
else:
|
||||
required_permission = None
|
||||
|
||||
if request.user.is_authenticated:
|
||||
# If this logic is updated, make sure to also update the logic in pretix/control/middleware.py
|
||||
if not settings.PRETIX_LONG_SESSIONS or not request.session.get('pretix_auth_long_session', False):
|
||||
last_used = request.session.get('pretix_auth_last_used', time.time())
|
||||
if time.time() - request.session.get('pretix_auth_login_time', time.time()) > settings.PRETIX_SESSION_TIMEOUT_ABSOLUTE:
|
||||
logout(request)
|
||||
request.session['pretix_auth_login_time'] = 0
|
||||
return False
|
||||
if time.time() - last_used > settings.PRETIX_SESSION_TIMEOUT_RELATIVE:
|
||||
return False
|
||||
request.session['pretix_auth_last_used'] = int(time.time())
|
||||
|
||||
perm_holder = (request.auth if isinstance(request.auth, TeamAPIToken)
|
||||
else request.user)
|
||||
if 'event' in request.resolver_match.kwargs and 'organizer' in request.resolver_match.kwargs:
|
||||
|
||||
@@ -64,15 +64,17 @@ class PermissionMiddleware(MiddlewareMixin):
|
||||
return self._login_redirect(request)
|
||||
|
||||
if not settings.PRETIX_LONG_SESSIONS or not request.session.get('pretix_auth_long_session', False):
|
||||
# If this logic is updated, make sure to also update the logic in pretix/api/auth/permission.py
|
||||
last_used = request.session.get('pretix_auth_last_used', time.time())
|
||||
if time.time() - request.session.get('pretix_auth_login_time', time.time()) > settings.PRETIX_SESSION_TIMEOUT_ABSOLUTE:
|
||||
logout(request)
|
||||
request.session['pretix_auth_login_time'] = 0
|
||||
return self._login_redirect(request)
|
||||
if time.time() - last_used > settings.PRETIX_SESSION_TIMEOUT_RELATIVE and url_name != 'user.reauth':
|
||||
return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
|
||||
if url_name != 'user.reauth':
|
||||
if time.time() - last_used > settings.PRETIX_SESSION_TIMEOUT_RELATIVE:
|
||||
return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
|
||||
|
||||
request.session['pretix_auth_last_used'] = int(time.time())
|
||||
request.session['pretix_auth_last_used'] = int(time.time())
|
||||
|
||||
if 'event' in url.kwargs and 'organizer' in url.kwargs:
|
||||
request.event = Event.objects.filter(
|
||||
|
||||
@@ -50,6 +50,17 @@ def user():
|
||||
return User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user_client(client, team, user):
|
||||
team.can_view_orders = True
|
||||
team.can_view_vouchers = True
|
||||
team.all_events = True
|
||||
team.save()
|
||||
team.members.add(user)
|
||||
client.force_authenticate(user=user)
|
||||
return client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def token_client(client, team):
|
||||
team.can_view_orders = True
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from django.test import override_settings
|
||||
|
||||
from pretix.base.models import Organizer
|
||||
|
||||
@@ -130,3 +133,99 @@ def test_token_event_permission_not_allowed(token_client, team, organizer, event
|
||||
assert resp.status_code == 403
|
||||
else:
|
||||
assert resp.status_code in (404, 403)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_log_out_after_absolute_timeout(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = False
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 12 - 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dont_logout_before_absolute_timeout(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = True
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 12 + 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(PRETIX_LONG_SESSIONS=False)
|
||||
def test_ignore_long_session_if_disabled_in_config(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = True
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 12 - 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dont_logout_in_long_session(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = True
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 12 - 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_log_out_after_relative_timeout(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = False
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 6
|
||||
session['pretix_auth_last_used'] = int(time.time()) - 3600 * 3 - 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dont_logout_before_relative_timeout(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = True
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 6
|
||||
session['pretix_auth_last_used'] = int(time.time()) - 3600 * 3 + 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dont_logout_by_relative_in_long_session(user_client, team, organizer, event):
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = True
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 5
|
||||
session['pretix_auth_last_used'] = int(time.time()) - 3600 * 3 - 60
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_update_session_activity(user_client, team, organizer, event):
|
||||
t1 = int(time.time()) - 5
|
||||
session = user_client.session
|
||||
session['pretix_auth_long_session'] = False
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 5
|
||||
session['pretix_auth_last_used'] = t1
|
||||
session.save()
|
||||
|
||||
response = user_client.get('/api/v1/organizers/{}/events/'.format(organizer.slug))
|
||||
assert response.status_code == 200
|
||||
|
||||
assert user_client.session['pretix_auth_last_used'] > t1
|
||||
|
||||
@@ -566,6 +566,26 @@ class SessionTimeOutTest(TestCase):
|
||||
response = self.client.get('/control/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_log_out_after_relative_timeout_really_enforced(self):
|
||||
# Regression test added after a security problem in 1.9.1
|
||||
# The problem was that, once the relative timeout happened, the user was redirected
|
||||
# to /control/reauth/, but loading /control/reauth/ was already considered to be
|
||||
# "session activitiy". Therefore, after loding /control/reauth/, the session was no longer
|
||||
# in the timeout state and the user was able to access pages again without re-entering the
|
||||
# password.
|
||||
session = self.client.session
|
||||
session['pretix_auth_long_session'] = False
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 6
|
||||
session['pretix_auth_last_used'] = int(time.time()) - 3600 * 3 - 60
|
||||
session.save()
|
||||
|
||||
response = self.client.get('/control/')
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertRedirects(response, '/control/reauth/?next=/control/')
|
||||
self.client.get('/control/reauth/?next=/control/')
|
||||
response = self.client.get('/control/')
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_update_session_activity(self):
|
||||
t1 = int(time.time()) - 5
|
||||
session = self.client.session
|
||||
|
||||
Reference in New Issue
Block a user