Skip to content

Commit e18e472

Browse files
sorcery suggested fixes
1 parent 3515791 commit e18e472

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

src/pretalx/agenda/views/schedule.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838

3939
class ScheduleMixin:
40+
MY_STARRED_ICS_TOKEN_SESSION_KEY = 'my_starred_ics_token'
4041
@cached_property
4142
def version(self):
4243
if version := self.kwargs.get("version"):
@@ -69,19 +70,27 @@ def dispatch(self, request, *args, **kwargs):
6970
return super().dispatch(request, *args, **kwargs)
7071

7172
@staticmethod
72-
def generate_ics_token(user_id):
73-
"""Generate a signed token with user ID and 15-day expiry"""
74-
expiry = timezone.now() + timedelta(days=15)
73+
def generate_ics_token(request, user_id):
74+
"""Generate a signed token with user ID and 15-day expiry, invalidating previous tokens"""
75+
# Clear any existing token from the session
76+
key = ScheduleMixin.MY_STARRED_ICS_TOKEN_SESSION_KEY
77+
if key in request.session:
78+
del request.session[key]
79+
80+
# Generate new token
81+
expiry = timezone.now() + timedelta(minutes=5)
7582
value = {"user_id": user_id, "exp": int(expiry.timestamp())}
76-
return signing.dumps(value, salt="my-starred-ics")
83+
token = signing.dumps(value, salt="my-starred-ics")
84+
85+
# Store new token in session
86+
request.session[key] = token
87+
return token
7788

7889
@staticmethod
7990
def parse_ics_token(token):
8091
"""Parse and validate the token, return user_id if valid"""
8192
try:
82-
value = signing.loads(token, salt="my-starred-ics", max_age=15*24*60*60)
83-
if value["exp"] < int(timezone.now().timestamp()):
84-
raise ValueError("Token expired")
93+
value = signing.loads(token, salt="my-starred-ics", max_age=5*60)
8594
return value["user_id"]
8695
except (signing.BadSignature, signing.SignatureExpired, KeyError, ValueError) as e:
8796
logger.warning('Failed to parse ICS token: %s', e)
@@ -97,10 +106,10 @@ def check_token_expiry(token):
97106
- True if token is valid and not expiring soon (>= 4 days)
98107
"""
99108
try:
100-
value = signing.loads(token, salt="my-starred-ics")
109+
value = signing.loads(token, salt="my-starred-ics", max_age=5*60)
101110
expiry_date = timezone.datetime.fromtimestamp(value["exp"], tz=timezone.utc)
102111
time_until_expiry = expiry_date - timezone.now()
103-
return time_until_expiry >= timedelta(days=4)
112+
return time_until_expiry >= timedelta(minutes=1)
104113
except Exception as e:
105114
logger.warning('Failed to check token expiry: %s', e)
106115
return None # Invalid token
@@ -357,7 +366,6 @@ class ChangelogView(EventPermissionRequired, TemplateView):
357366

358367
class CalendarRedirectView(EventPermissionRequired, ScheduleMixin, TemplateView):
359368
"""Handles redirects for both Google Calendar and other calendar applications"""
360-
MY_STARRED_ICS_TOKEN_SESSION_KEY = 'my_starred_ics_token'
361369
permission_required = "agenda.view_schedule"
362370

363371
def get(self, request, *args, **kwargs):
@@ -371,7 +379,8 @@ def get(self, request, *args, **kwargs):
371379
if is_my:
372380
# For starred sessions
373381
if not request.user.is_authenticated:
374-
return HttpResponseRedirect(self.request.event.urls.login)
382+
login_url = f"{self.request.event.urls.login}?next={request.get_full_path()}"
383+
return HttpResponseRedirect(login_url)
375384

376385
# Check for existing valid token
377386
existing_token = request.session.get(self.MY_STARRED_ICS_TOKEN_SESSION_KEY)
@@ -380,14 +389,13 @@ def get(self, request, *args, **kwargs):
380389
# If we have an existing token, check if it's still valid and not expiring soon
381390
if existing_token:
382391
token_status = self.check_token_expiry(existing_token)
383-
if token_status is True:
392+
if token_status is True: # Token is valid and has at least 4 days left
384393
token = existing_token
385394
generate_new_token = False
386395

387-
# Generate new token if needed
396+
# Generate new token if needed (this will invalidate any existing token)
388397
if generate_new_token:
389-
token = self.generate_ics_token(request.user.id)
390-
request.session[self.MY_STARRED_ICS_TOKEN_SESSION_KEY] = token
398+
token = self.generate_ics_token(request, request.user.id)
391399

392400
# Build tokenized URL for starred sessions
393401
ics_url = request.build_absolute_uri(

0 commit comments

Comments
 (0)