microdot 2.5.0__tar.gz → 2.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. {microdot-2.5.0/src/microdot.egg-info → microdot-2.5.1}/PKG-INFO +2 -2
  2. {microdot-2.5.0 → microdot-2.5.1}/README.md +1 -1
  3. {microdot-2.5.0 → microdot-2.5.1}/pyproject.toml +1 -1
  4. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/__init__.py +1 -1
  5. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/csrf.py +7 -9
  6. {microdot-2.5.0 → microdot-2.5.1/src/microdot.egg-info}/PKG-INFO +2 -2
  7. {microdot-2.5.0 → microdot-2.5.1}/tests/test_csrf.py +20 -8
  8. {microdot-2.5.0 → microdot-2.5.1}/LICENSE +0 -0
  9. {microdot-2.5.0 → microdot-2.5.1}/MANIFEST.in +0 -0
  10. {microdot-2.5.0 → microdot-2.5.1}/docs/Makefile +0 -0
  11. {microdot-2.5.0 → microdot-2.5.1}/docs/_static/css/custom.css +0 -0
  12. {microdot-2.5.0 → microdot-2.5.1}/docs/api/asgi.rst +0 -0
  13. {microdot-2.5.0 → microdot-2.5.1}/docs/api/auth.rst +0 -0
  14. {microdot-2.5.0 → microdot-2.5.1}/docs/api/cors.rst +0 -0
  15. {microdot-2.5.0 → microdot-2.5.1}/docs/api/csrf.rst +0 -0
  16. {microdot-2.5.0 → microdot-2.5.1}/docs/api/index.rst +0 -0
  17. {microdot-2.5.0 → microdot-2.5.1}/docs/api/jinja.rst +0 -0
  18. {microdot-2.5.0 → microdot-2.5.1}/docs/api/login.rst +0 -0
  19. {microdot-2.5.0 → microdot-2.5.1}/docs/api/microdot.rst +0 -0
  20. {microdot-2.5.0 → microdot-2.5.1}/docs/api/multipart.rst +0 -0
  21. {microdot-2.5.0 → microdot-2.5.1}/docs/api/sessions.rst +0 -0
  22. {microdot-2.5.0 → microdot-2.5.1}/docs/api/sse.rst +0 -0
  23. {microdot-2.5.0 → microdot-2.5.1}/docs/api/test_client.rst +0 -0
  24. {microdot-2.5.0 → microdot-2.5.1}/docs/api/utemplate.rst +0 -0
  25. {microdot-2.5.0 → microdot-2.5.1}/docs/api/websocket.rst +0 -0
  26. {microdot-2.5.0 → microdot-2.5.1}/docs/api/wsgi.rst +0 -0
  27. {microdot-2.5.0 → microdot-2.5.1}/docs/conf.py +0 -0
  28. {microdot-2.5.0 → microdot-2.5.1}/docs/contributing.rst +0 -0
  29. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/auth.rst +0 -0
  30. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/cors.rst +0 -0
  31. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/csrf.rst +0 -0
  32. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/index.rst +0 -0
  33. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/login.rst +0 -0
  34. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/multipart.rst +0 -0
  35. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/production.rst +0 -0
  36. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/sessions.rst +0 -0
  37. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/sse.rst +0 -0
  38. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/templates.rst +0 -0
  39. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/test_client.rst +0 -0
  40. {microdot-2.5.0 → microdot-2.5.1}/docs/extensions/websocket.rst +0 -0
  41. {microdot-2.5.0 → microdot-2.5.1}/docs/implementation/freezing.rst +0 -0
  42. {microdot-2.5.0 → microdot-2.5.1}/docs/implementation/index.rst +0 -0
  43. {microdot-2.5.0 → microdot-2.5.1}/docs/implementation/migrating.rst +0 -0
  44. {microdot-2.5.0 → microdot-2.5.1}/docs/index.rst +0 -0
  45. {microdot-2.5.0 → microdot-2.5.1}/docs/intro.rst +0 -0
  46. {microdot-2.5.0 → microdot-2.5.1}/docs/make.bat +0 -0
  47. {microdot-2.5.0 → microdot-2.5.1}/docs/users-guide/concurrency.rst +0 -0
  48. {microdot-2.5.0 → microdot-2.5.1}/docs/users-guide/defining-routes.rst +0 -0
  49. {microdot-2.5.0 → microdot-2.5.1}/docs/users-guide/index.rst +0 -0
  50. {microdot-2.5.0 → microdot-2.5.1}/docs/users-guide/intro.rst +0 -0
  51. {microdot-2.5.0 → microdot-2.5.1}/docs/users-guide/request-object.rst +0 -0
  52. {microdot-2.5.0 → microdot-2.5.1}/docs/users-guide/responses.rst +0 -0
  53. {microdot-2.5.0 → microdot-2.5.1}/setup.cfg +0 -0
  54. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/asgi.py +0 -0
  55. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/auth.py +0 -0
  56. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/cors.py +0 -0
  57. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/helpers.py +0 -0
  58. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/jinja.py +0 -0
  59. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/login.py +0 -0
  60. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/microdot.py +0 -0
  61. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/multipart.py +0 -0
  62. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/session.py +0 -0
  63. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/sse.py +0 -0
  64. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/test_client.py +0 -0
  65. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/utemplate.py +0 -0
  66. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/websocket.py +0 -0
  67. {microdot-2.5.0 → microdot-2.5.1}/src/microdot/wsgi.py +0 -0
  68. {microdot-2.5.0 → microdot-2.5.1}/src/microdot.egg-info/SOURCES.txt +0 -0
  69. {microdot-2.5.0 → microdot-2.5.1}/src/microdot.egg-info/dependency_links.txt +0 -0
  70. {microdot-2.5.0 → microdot-2.5.1}/src/microdot.egg-info/not-zip-safe +0 -0
  71. {microdot-2.5.0 → microdot-2.5.1}/src/microdot.egg-info/requires.txt +0 -0
  72. {microdot-2.5.0 → microdot-2.5.1}/src/microdot.egg-info/top_level.txt +0 -0
  73. {microdot-2.5.0 → microdot-2.5.1}/tests/__init__.py +0 -0
  74. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.bin +0 -0
  75. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.css +0 -0
  76. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.gif +0 -0
  77. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.gz +0 -0
  78. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.html +0 -0
  79. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.jpg +0 -0
  80. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.js +0 -0
  81. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.json +0 -0
  82. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.png +0 -0
  83. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.txt +0 -0
  84. {microdot-2.5.0 → microdot-2.5.1}/tests/files/test.txt.gz +0 -0
  85. {microdot-2.5.0 → microdot-2.5.1}/tests/mock_socket.py +0 -0
  86. {microdot-2.5.0 → microdot-2.5.1}/tests/templates/hello.jinja.txt +0 -0
  87. {microdot-2.5.0 → microdot-2.5.1}/tests/templates/hello.utemplate.txt +0 -0
  88. {microdot-2.5.0 → microdot-2.5.1}/tests/templates/hello_utemplate_txt.py +0 -0
  89. {microdot-2.5.0 → microdot-2.5.1}/tests/test_asgi.py +0 -0
  90. {microdot-2.5.0 → microdot-2.5.1}/tests/test_auth.py +0 -0
  91. {microdot-2.5.0 → microdot-2.5.1}/tests/test_cors.py +0 -0
  92. {microdot-2.5.0 → microdot-2.5.1}/tests/test_end2end.py +0 -0
  93. {microdot-2.5.0 → microdot-2.5.1}/tests/test_jinja.py +0 -0
  94. {microdot-2.5.0 → microdot-2.5.1}/tests/test_login.py +0 -0
  95. {microdot-2.5.0 → microdot-2.5.1}/tests/test_microdot.py +0 -0
  96. {microdot-2.5.0 → microdot-2.5.1}/tests/test_multidict.py +0 -0
  97. {microdot-2.5.0 → microdot-2.5.1}/tests/test_multipart.py +0 -0
  98. {microdot-2.5.0 → microdot-2.5.1}/tests/test_request.py +0 -0
  99. {microdot-2.5.0 → microdot-2.5.1}/tests/test_response.py +0 -0
  100. {microdot-2.5.0 → microdot-2.5.1}/tests/test_session.py +0 -0
  101. {microdot-2.5.0 → microdot-2.5.1}/tests/test_sse.py +0 -0
  102. {microdot-2.5.0 → microdot-2.5.1}/tests/test_url_pattern.py +0 -0
  103. {microdot-2.5.0 → microdot-2.5.1}/tests/test_urlencode.py +0 -0
  104. {microdot-2.5.0 → microdot-2.5.1}/tests/test_utemplate.py +0 -0
  105. {microdot-2.5.0 → microdot-2.5.1}/tests/test_websocket.py +0 -0
  106. {microdot-2.5.0 → microdot-2.5.1}/tests/test_wsgi.py +0 -0
  107. {microdot-2.5.0 → microdot-2.5.1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microdot
3
- Version: 2.5.0
3
+ Version: 2.5.1
4
4
  Summary: The impossibly small web framework for MicroPython
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/miguelgrinberg/microdot
@@ -60,7 +60,7 @@ MicroPython and CPython:
60
60
 
61
61
  - Authentication support, similar to [Flask-Login](https://github.com/maxcountryman/flask-login) for Flask (**Added in version 2.1**)
62
62
  - Support for forms encoded in `multipart/form-data` format (**Added in version 2.2**)
63
- - CSRF protection extension
63
+ - CSRF protection extension (**Added in version 2.5**)
64
64
  - Pub/sub mini-framework for WebSocket and SSE
65
65
  - OpenAPI integration, similar to [APIFairy](https://github.com/miguelgrinberg/apifairy) for Flask
66
66
 
@@ -36,7 +36,7 @@ MicroPython and CPython:
36
36
 
37
37
  - Authentication support, similar to [Flask-Login](https://github.com/maxcountryman/flask-login) for Flask (**Added in version 2.1**)
38
38
  - Support for forms encoded in `multipart/form-data` format (**Added in version 2.2**)
39
- - CSRF protection extension
39
+ - CSRF protection extension (**Added in version 2.5**)
40
40
  - Pub/sub mini-framework for WebSocket and SSE
41
41
  - OpenAPI integration, similar to [APIFairy](https://github.com/miguelgrinberg/apifairy) for Flask
42
42
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "microdot"
3
- version = "2.5.0"
3
+ version = "2.5.1"
4
4
  authors = [
5
5
  { name = "Miguel Grinberg", email = "miguel.grinberg@gmail.com" },
6
6
  ]
@@ -1,4 +1,4 @@
1
1
  from microdot.microdot import Microdot, Request, Response, abort, redirect, \
2
2
  send_file, URLPattern, AsyncBytesIO, iscoroutine # noqa: F401
3
3
 
4
- __version__ = '2.5.0'
4
+ __version__ = '2.5.1'
@@ -56,6 +56,7 @@ class CSRF:
56
56
  ) or request.route in self.protected_routes:
57
57
  allow = False
58
58
  sfs = request.headers.get('Sec-Fetch-Site')
59
+ origin = request.headers.get('Origin')
59
60
  if sfs:
60
61
  # if the Sec-Fetch-Site header was given, ensure it is not
61
62
  # cross-site
@@ -63,14 +64,11 @@ class CSRF:
63
64
  allow = True
64
65
  elif sfs == 'same-site' and self.allow_subdomains:
65
66
  allow = True
66
- elif self.cors and self.cors.allowed_origins != '*':
67
- # if there is no Sec-Fetch-Site header but we have a list
68
- # of allowed origins, then we can validate the origin
69
- origin = request.headers.get('Origin')
70
- if origin is None:
71
- # origin wasn't given so this isn't a browser
72
- allow = True
73
- elif not self.allow_subdomains:
67
+ if not allow and origin and self.cors and \
68
+ self.cors.allowed_origins != '*':
69
+ # if we have a list of allowed origins, then we can
70
+ # validate the origin
71
+ if not self.allow_subdomains:
74
72
  allow = origin in self.cors.allowed_origins
75
73
  else:
76
74
  origin_scheme, origin_host = origin.split('://', 1)
@@ -83,7 +81,7 @@ class CSRF:
83
81
  ):
84
82
  allow = True
85
83
  break
86
- else:
84
+ if not allow and not sfs and not origin:
87
85
  allow = True # no headers to check
88
86
 
89
87
  if not allow:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microdot
3
- Version: 2.5.0
3
+ Version: 2.5.1
4
4
  Summary: The impossibly small web framework for MicroPython
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/miguelgrinberg/microdot
@@ -60,7 +60,7 @@ MicroPython and CPython:
60
60
 
61
61
  - Authentication support, similar to [Flask-Login](https://github.com/maxcountryman/flask-login) for Flask (**Added in version 2.1**)
62
62
  - Support for forms encoded in `multipart/form-data` format (**Added in version 2.2**)
63
- - CSRF protection extension
63
+ - CSRF protection extension (**Added in version 2.5**)
64
64
  - Pub/sub mini-framework for WebSocket and SSE
65
65
  - OpenAPI integration, similar to [APIFairy](https://github.com/miguelgrinberg/apifairy) for Flask
66
66
 
@@ -203,10 +203,6 @@ class TestCSRF(unittest.TestCase):
203
203
 
204
204
  res = self._run(client.get('/'))
205
205
  self.assertEqual(res.status_code, 204)
206
- res = self._run(client.get(
207
- '/', headers={'Origin': 'foo.com'}
208
- ))
209
- self.assertEqual(res.status_code, 204)
210
206
  res = self._run(client.get(
211
207
  '/', headers={'Origin': 'http://foo.com'}
212
208
  ))
@@ -230,6 +226,26 @@ class TestCSRF(unittest.TestCase):
230
226
  '/submit', headers={'Origin': 'http://bar.com:8888'}
231
227
  ))
232
228
  self.assertEqual(res.status_code, 403)
229
+ res = self._run(client.post(
230
+ '/submit', headers={
231
+ 'Sec-Fetch-Site': 'cross-site',
232
+ 'Origin': 'https://bar.com:8888',
233
+ },
234
+ ))
235
+ self.assertEqual(res.status_code, 204)
236
+ res = self._run(client.post(
237
+ '/submit', headers={
238
+ 'Sec-Fetch-Site': 'cross-site',
239
+ 'Origin': 'https://bar.com:8889',
240
+ },
241
+ ))
242
+ self.assertEqual(res.status_code, 403)
243
+ res = self._run(client.post(
244
+ '/submit', headers={
245
+ 'Sec-Fetch-Site': 'cross-site',
246
+ },
247
+ ))
248
+ self.assertEqual(res.status_code, 403)
233
249
  res = self._run(client.post(
234
250
  '/submit', headers={'Origin': 'https://x.y.bar.com:8888'}
235
251
  ))
@@ -257,10 +273,6 @@ class TestCSRF(unittest.TestCase):
257
273
 
258
274
  res = self._run(client.get('/'))
259
275
  self.assertEqual(res.status_code, 204)
260
- res = self._run(client.get(
261
- '/', headers={'Origin': 'foo.com'}
262
- ))
263
- self.assertEqual(res.status_code, 204)
264
276
  res = self._run(client.get(
265
277
  '/', headers={'Origin': 'http://foo.com'}
266
278
  ))
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes