From 6ffb8a8fe920111c4d8c16e98715a0d5ee2d1da3 Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Tue, 18 Jun 2024 20:27:01 +0100 Subject: [PATCH] Cookie path support in session and test client --- src/microdot/session.py | 2 +- src/microdot/test_client.py | 8 +++++--- tests/test_microdot.py | 1 + tests/test_response.py | 3 +++ tests/test_session.py | 26 ++++++++++++++++++++++++-- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/microdot/session.py b/src/microdot/session.py index 7ad248d..d8ce085 100644 --- a/src/microdot/session.py +++ b/src/microdot/session.py @@ -117,7 +117,7 @@ def index(request, session): """ @request.after_request def _delete_session(request, response): - response.delete_cookie('session') + response.delete_cookie('session', **self.cookie_options) return response def encode(self, payload, secret_key=None): diff --git a/src/microdot/test_client.py b/src/microdot/test_client.py index 9eb4dc6..1018f84 100644 --- a/src/microdot/test_client.py +++ b/src/microdot/test_client.py @@ -156,7 +156,6 @@ def _update_cookies(self, res): age = 0 if age <= 0: delete = True - break elif option.startswith('expires='): _, e = option.split('=', 1) # this is a very limited parser for cookie expiry @@ -164,12 +163,15 @@ def _update_cookies(self, res): # the date is 1/1/1970 if '1 jan 1970' in e.lower(): # pragma: no branch delete = True - break elif option.startswith('path='): _, path = option.split('=', 1) if delete: if cookie_name in self.cookies: # pragma: no branch - del self.cookies[cookie_name] + cookie_path = self.cookies[cookie_name][1] \ + if isinstance(self.cookies[cookie_name], tuple) \ + else '/' + if path == cookie_path: + del self.cookies[cookie_name] else: if path == '/': self.cookies[cookie_name] = cookie_options[0] diff --git a/tests/test_microdot.py b/tests/test_microdot.py index e0bf255..c80fe16 100644 --- a/tests/test_microdot.py +++ b/tests/test_microdot.py @@ -203,6 +203,7 @@ def index(req): req.cookies['one'] + req.cookies['two'] + req.cookies['three']) res.set_cookie('four', '4') res.delete_cookie('two', path='/') + res.delete_cookie('one', path='/bad') return res client = TestClient(app, cookies={'one': '1', 'two': '2'}) diff --git a/tests/test_response.py b/tests/test_response.py index ae2f4c4..337f8dc 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -193,6 +193,7 @@ def test_cookies(self): expires='Tue, 05 Nov 2019 02:23:54 GMT', max_age=123, secure=True, http_only=True) res.delete_cookie('foo8', http_only=True) + res.delete_cookie('foo9', path='/s') self.assertEqual(res.headers, {'Set-Cookie': [ 'foo1=bar1', 'foo2=bar2; Path=/; Partitioned', @@ -205,6 +206,8 @@ def test_cookies(self): 'HttpOnly', ('foo8=; Expires=Thu, 01 Jan 1970 00:00:01 GMT; Max-Age=0; ' 'HttpOnly'), + ('foo9=; Path=/s; Expires=Thu, 01 Jan 1970 00:00:01 GMT; ' + 'Max-Age=0'), ]}) def test_redirect(self): diff --git a/tests/test_session.py b/tests/test_session.py index cb9b2bf..0359ed9 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -85,7 +85,7 @@ def index(req): def test_session_default_path(self): app = Microdot() - session_ext.initialize(app, secret_key='some-other-secret') + Session(app, secret_key='some-other-secret') client = TestClient(app) @app.get('/') @@ -100,15 +100,26 @@ def index(req, session): def child(req, session): return str(session.get('foo')) + @app.get('/delete') + @with_session + def delete(req, session): + session.delete() + return '' + res = self._run(client.get('/')) self.assertEqual(res.status_code, 200) res = self._run(client.get('/child')) self.assertEqual(res.text, 'bar') + res = self._run(client.get('/delete')) + res = self._run(client.get('/child')) + self.assertEqual(res.text, 'None') def test_session_custom_path(self): app = Microdot() + session_ext = Session() session_ext.initialize(app, secret_key='some-other-secret', - cookie_options={'path': '/child'}) + cookie_options={'path': '/child', + 'http_only': False}) client = TestClient(app) @app.get('/') @@ -128,9 +139,20 @@ def child(req, session): def foo(req, session): return str(session.get('foo')) + @app.get('/child/delete') + @with_session + def delete(req, session): + session.delete() + return '' + res = self._run(client.get('/child')) self.assertEqual(res.status_code, 200) res = self._run(client.get('/')) self.assertEqual(res.text, 'None') res = self._run(client.get('/child/foo')) self.assertEqual(res.text, 'bar') + res = self._run(client.get('/child/delete')) + res = self._run(client.get('/')) + self.assertEqual(res.text, 'None') + res = self._run(client.get('/child/foo')) + self.assertEqual(res.text, 'None')