Skip to content

Commit 7d8cf44

Browse files
sorcery suggested fixes
1 parent 3515791 commit 7d8cf44

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

src/pretalx/agenda/views/schedule.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838

3939
class ScheduleMixin:
40+
MY_STARRED_ICS_TOKEN_SESSION_KEY = 'my_starred_ics_token'
41+
4042
@cached_property
4143
def version(self):
4244
if version := self.kwargs.get("version"):
@@ -69,19 +71,27 @@ def dispatch(self, request, *args, **kwargs):
6971
return super().dispatch(request, *args, **kwargs)
7072

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

7890
@staticmethod
7991
def parse_ics_token(token):
8092
"""Parse and validate the token, return user_id if valid"""
8193
try:
8294
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")
8595
return value["user_id"]
8696
except (signing.BadSignature, signing.SignatureExpired, KeyError, ValueError) as e:
8797
logger.warning('Failed to parse ICS token: %s', e)
@@ -97,7 +107,7 @@ def check_token_expiry(token):
97107
- True if token is valid and not expiring soon (>= 4 days)
98108
"""
99109
try:
100-
value = signing.loads(token, salt="my-starred-ics")
110+
value = signing.loads(token, salt="my-starred-ics", max_age=15*24*60*60)
101111
expiry_date = timezone.datetime.fromtimestamp(value["exp"], tz=timezone.utc)
102112
time_until_expiry = expiry_date - timezone.now()
103113
return time_until_expiry >= timedelta(days=4)
@@ -357,7 +367,6 @@ class ChangelogView(EventPermissionRequired, TemplateView):
357367

358368
class CalendarRedirectView(EventPermissionRequired, ScheduleMixin, TemplateView):
359369
"""Handles redirects for both Google Calendar and other calendar applications"""
360-
MY_STARRED_ICS_TOKEN_SESSION_KEY = 'my_starred_ics_token'
361370
permission_required = "agenda.view_schedule"
362371

363372
def get(self, request, *args, **kwargs):
@@ -371,7 +380,8 @@ def get(self, request, *args, **kwargs):
371380
if is_my:
372381
# For starred sessions
373382
if not request.user.is_authenticated:
374-
return HttpResponseRedirect(self.request.event.urls.login)
383+
login_url = f"{self.request.event.urls.login}?next={request.get_full_path()}"
384+
return HttpResponseRedirect(login_url)
375385

376386
# Check for existing valid token
377387
existing_token = request.session.get(self.MY_STARRED_ICS_TOKEN_SESSION_KEY)
@@ -380,14 +390,13 @@ def get(self, request, *args, **kwargs):
380390
# If we have an existing token, check if it's still valid and not expiring soon
381391
if existing_token:
382392
token_status = self.check_token_expiry(existing_token)
383-
if token_status is True:
393+
if token_status is True: # Token is valid and has at least 4 days left
384394
token = existing_token
385395
generate_new_token = False
386396

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

392401
# Build tokenized URL for starred sessions
393402
ics_url = request.build_absolute_uri(
@@ -426,4 +435,4 @@ def get(self, request, *args, **kwargs):
426435
f'<body><p style="text-align: center; padding:2vw; font-family: Roboto,Helvetica Neue,HelveticaNeue,Helvetica,Arial,sans-serif;">Redirecting to: {webcal_url}</p><script>window.location.href="{webcal_url}";</script></body></html>',
427436
content_type='text/html'
428437
)
429-
return response
438+
return response

0 commit comments

Comments
 (0)