Skip to content

Commit 8da7c01

Browse files
committed
Merge tag '26.10.3' into develop
Update how invalid cookie/session is handled
2 parents 35ed310 + d00a752 commit 8da7c01

5 files changed

Lines changed: 32 additions & 8 deletions

File tree

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO.
44

5+
26.10.3 (2026-06-02)
6+
====================
7+
8+
- Update how invalid cookie/session is handled
9+
510
26.10.2 (2026-05-27)
611
====================
712

framework/sessions/__init__.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def create_session(response, data=None):
164164
def before_request():
165165
# TODO: Fix circular import
166166
from framework.auth.core import get_user
167-
from framework.auth import cas, utils
167+
from framework.auth import cas
168168
UserSessionMap = apps.get_model('osf.UserSessionMap')
169169

170170
# Request Type 1: Service ticket validation during CAS login.
@@ -215,8 +215,15 @@ def before_request():
215215
try:
216216
user_session = flask_get_session_from_cookie(cookie)
217217
except InvalidCookieOrSessionError:
218-
# If invalid session/cookie happens, perform a full logout to clear both CAS and OSF Sessions
219-
response = redirect(utils.get_default_osf_logout_url())
218+
# If invalid session/cookie happens, only remove the invalid cookie and redirect to the same request.
219+
# This ensures users landing on the page/link they previously clicked.
220+
# Case 1: If it's a public page, they land on the correct page.
221+
# Case 2: If it's a private page and if they already have a CAS cookie, they will be automatically logged
222+
# back in and land on the correct page.
223+
# Case 3: If it's a private page and if they don't have a CAS cookie, they will need to manually log in.
224+
# After successful login, they will land on the correct page.
225+
redirect_url = request.url
226+
response = redirect(redirect_url)
220227
response.delete_cookie(settings.COOKIE_NAME, domain=settings.OSF_COOKIE_DOMAIN)
221228
return response
222229
# Case 1: anonymous session that is used for first time external (e.g. ORCiD) login only

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "OSF",
3-
"version": "26.10.2",
3+
"version": "26.10.3",
44
"description": "Facilitating Open Science",
55
"repository": "https://github.com/CenterForOpenScience/osf.io",
66
"author": "Center for Open Science",

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
[tool.poetry]
22
name = "osf-io"
3-
version = "26.10.2"
3+
version = "26.10.3"
44
description = "The code for [https://osf.io](https://osf.io)."
5-
authors = ["Longze Chen <cslzchen@gmail.com>"]
5+
authors = [
6+
"Brian J. Geiger <bgeiger@pobox.com>",
7+
"Longze Chen <cslzchen@gmail.com>",
8+
]
69
license = "Apache License 2.0"
710
readme = "README.md"
811
packages = [{include = "osf"}]

tests/test_auth_basic_auth.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def setUp(self):
2929
self.reachable_project = ProjectFactory(title='Private Project User 1', is_public=False, creator=self.user1)
3030
self.unreachable_project = ProjectFactory(title='Private Project User 2', is_public=False, creator=self.user2)
3131
self.reachable_url = self.reachable_project.web_url_for('view_project')
32+
self.reachable_absolute_url = self.reachable_project.web_url_for('view_project', _absolute=True)
3233
self.unreachable_url = self.unreachable_project.web_url_for('view_project')
3334

3435
def test_missing_credential_fails(self):
@@ -97,6 +98,14 @@ def test_expired_cookie(self):
9798
session = SessionStore(session_key=session_key)
9899
session.delete()
99100
self.app.set_cookie(settings.COOKIE_NAME, str(cookie))
100-
res = self.app.get(self.reachable_url)
101+
res = self.app.get(self.reachable_absolute_url)
102+
assert res.status_code == 302
103+
assert f'{settings.COOKIE_NAME}=;' in res.headers.get('Set-Cookie')
104+
assert self.reachable_absolute_url == res.location
105+
106+
def test_invalid_cookie(self):
107+
self.app.set_cookie(settings.COOKIE_NAME, str('INVALID_COOKIE'))
108+
res = self.app.get(self.reachable_absolute_url)
101109
assert res.status_code == 302
102-
assert 'http://localhost:5000/logout/?next=http://localhost:4200/' == res.location
110+
assert f'{settings.COOKIE_NAME}=;' in res.headers.get('Set-Cookie')
111+
assert self.reachable_absolute_url == res.location

0 commit comments

Comments
 (0)