mirror of
https://github.com/pretix/pretix.git
synced 2025-12-10 01:12:28 +00:00
Compare commits
4 Commits
widget-sub
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc736e8548 | ||
|
|
8655486a58 | ||
|
|
9d410f33a0 | ||
|
|
c236144c68 |
@@ -8,6 +8,8 @@ tests:
|
|||||||
- XDG_CACHE_HOME=/cache bash .travis.sh tests
|
- XDG_CACHE_HOME=/cache bash .travis.sh tests
|
||||||
tags:
|
tags:
|
||||||
- python3
|
- python3
|
||||||
|
except:
|
||||||
|
- pypi
|
||||||
pypi:
|
pypi:
|
||||||
stage: release
|
stage: release
|
||||||
script:
|
script:
|
||||||
@@ -22,7 +24,7 @@ pypi:
|
|||||||
tags:
|
tags:
|
||||||
- python3
|
- python3
|
||||||
only:
|
only:
|
||||||
- release
|
- pypi
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- src/dist/
|
- 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.exceptions import PermissionDenied
|
||||||
from rest_framework.permissions import SAFE_METHODS, BasePermission
|
from rest_framework.permissions import SAFE_METHODS, BasePermission
|
||||||
|
|
||||||
@@ -21,6 +25,18 @@ class EventPermission(BasePermission):
|
|||||||
else:
|
else:
|
||||||
required_permission = None
|
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)
|
perm_holder = (request.auth if isinstance(request.auth, TeamAPIToken)
|
||||||
else request.user)
|
else request.user)
|
||||||
if 'event' in request.resolver_match.kwargs and 'organizer' in request.resolver_match.kwargs:
|
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)
|
return self._login_redirect(request)
|
||||||
|
|
||||||
if not settings.PRETIX_LONG_SESSIONS or not request.session.get('pretix_auth_long_session', False):
|
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())
|
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:
|
if time.time() - request.session.get('pretix_auth_login_time', time.time()) > settings.PRETIX_SESSION_TIMEOUT_ABSOLUTE:
|
||||||
logout(request)
|
logout(request)
|
||||||
request.session['pretix_auth_login_time'] = 0
|
request.session['pretix_auth_login_time'] = 0
|
||||||
return self._login_redirect(request)
|
return self._login_redirect(request)
|
||||||
if time.time() - last_used > settings.PRETIX_SESSION_TIMEOUT_RELATIVE and url_name != 'user.reauth':
|
if url_name != 'user.reauth':
|
||||||
return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
|
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:
|
if 'event' in url.kwargs and 'organizer' in url.kwargs:
|
||||||
request.event = Event.objects.filter(
|
request.event = Event.objects.filter(
|
||||||
|
|||||||
@@ -50,6 +50,17 @@ def user():
|
|||||||
return User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
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
|
@pytest.fixture
|
||||||
def token_client(client, team):
|
def token_client(client, team):
|
||||||
team.can_view_orders = True
|
team.can_view_orders = True
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from django.test import override_settings
|
||||||
|
|
||||||
from pretix.base.models import Organizer
|
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
|
assert resp.status_code == 403
|
||||||
else:
|
else:
|
||||||
assert resp.status_code in (404, 403)
|
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/')
|
response = self.client.get('/control/')
|
||||||
self.assertEqual(response.status_code, 200)
|
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):
|
def test_update_session_activity(self):
|
||||||
t1 = int(time.time()) - 5
|
t1 = int(time.time()) - 5
|
||||||
session = self.client.session
|
session = self.client.session
|
||||||
|
|||||||
Reference in New Issue
Block a user