sanic-security 1.11.6__tar.gz → 1.12.0__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 (27) hide show
  1. sanic_security-1.12.0/LICENSE +21 -0
  2. sanic_security-1.11.6/README.md → sanic_security-1.12.0/PKG-INFO +85 -38
  3. sanic_security-1.11.6/PKG-INFO → sanic_security-1.12.0/README.md +577 -591
  4. sanic_security-1.12.0/pyproject.toml +31 -0
  5. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/authentication.py +140 -136
  6. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/authorization.py +51 -42
  7. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/configuration.py +26 -20
  8. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/exceptions.py +43 -21
  9. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/models.py +114 -62
  10. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/test/server.py +67 -23
  11. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/test/tests.py +80 -15
  12. sanic_security-1.12.0/sanic_security/utils.py +86 -0
  13. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/verification.py +20 -19
  14. sanic_security-1.12.0/sanic_security.egg-info/PKG-INFO +608 -0
  15. sanic_security-1.12.0/sanic_security.egg-info/SOURCES.txt +19 -0
  16. sanic_security-1.12.0/sanic_security.egg-info/dependency_links.txt +1 -0
  17. sanic_security-1.12.0/sanic_security.egg-info/requires.txt +16 -0
  18. sanic_security-1.12.0/sanic_security.egg-info/top_level.txt +1 -0
  19. sanic_security-1.12.0/setup.cfg +4 -0
  20. sanic_security-1.11.6/LICENSE +0 -661
  21. sanic_security-1.11.6/pyproject.toml +0 -28
  22. sanic_security-1.11.6/sanic_security/test/__pycache__/__init__.cpython-39.pyc +0 -0
  23. sanic_security-1.11.6/sanic_security/test/__pycache__/server.cpython-39.pyc +0 -0
  24. sanic_security-1.11.6/sanic_security/test/__pycache__/tests.cpython-39.pyc +0 -0
  25. sanic_security-1.11.6/sanic_security/utils.py +0 -82
  26. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/__init__.py +0 -0
  27. {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/test/__init__.py +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Nicholas Aidan Stewart
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,3 +1,34 @@
1
+ Metadata-Version: 2.1
2
+ Name: sanic-security
3
+ Version: 1.12.0
4
+ Summary: An effective, simple, and async security library for the Sanic framework.
5
+ Author-email: Aidan Stewart <na.stewart365@gmail.com>
6
+ Project-URL: Documentation, https://security.na-stewart.com/
7
+ Project-URL: Repository, https://github.com/na-stewart/sanic-security
8
+ Keywords: security,authentication,authorization,verification,async,sanic
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Security
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python
14
+ Requires-Python: >=3.8
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: tortoise-orm>=0.17.0
18
+ Requires-Dist: pyjwt>=1.7.0
19
+ Requires-Dist: captcha>=0.4
20
+ Requires-Dist: pillow>=9.5.0
21
+ Requires-Dist: argon2-cffi>=20.1.0
22
+ Requires-Dist: sanic>=21.3.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: httpx; extra == "dev"
25
+ Requires-Dist: black; extra == "dev"
26
+ Requires-Dist: blacken-docs; extra == "dev"
27
+ Requires-Dist: pdoc3; extra == "dev"
28
+ Requires-Dist: cryptography; extra == "dev"
29
+ Provides-Extra: crypto
30
+ Requires-Dist: cryptography>=3.3.1; extra == "crypto"
31
+
1
32
  <!-- PROJECT SHIELDS -->
2
33
  <!--
3
34
  *** I'm using markdown "reference style" links for readability.
@@ -8,7 +39,7 @@
8
39
  -->
9
40
 
10
41
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
11
- [![Downloads](https://pepy.tech/badge/sanic-security)](https://pepy.tech/project/sanic-security)
42
+ [![Downloads](https://static.pepy.tech/badge/sanic-security)](https://pepy.tech/project/sanic-security)
12
43
  [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/sanic-security.svg)](https://anaconda.org/conda-forge/sanic-security)
13
44
 
14
45
 
@@ -48,15 +79,13 @@
48
79
  Sanic Security is an authentication, authorization, and verification library designed for use with [Sanic](https://github.com/huge-success/sanic).
49
80
  This library contains a variety of features including:
50
81
 
51
- * Login, registration, and authentication
82
+ * Login, registration, and authentication with refresh mechanisms
52
83
  * Two-factor authentication
53
84
  * Captcha
54
85
  * Two-step verification
55
86
  * Role based authorization with wildcard permissions
56
87
 
57
- Please visit [security.na-stewart.com](https://security.na-stewart.com) for documentation,
58
-
59
- and check out [blog.na-stewart.com](https://github.com/na-stewart/Aidans-Page) for an example implementation.
88
+ Please visit [security.na-stewart.com](https://security.na-stewart.com) for documentation and [click here for a comprehensive implementation guide](https://blog.na-stewart.com/entry?id=3).
60
89
 
61
90
  <!-- GETTING STARTED -->
62
91
  ## Getting Started
@@ -126,15 +155,16 @@ You can load environment variables with a different prefix via calling the `conf
126
155
  | **MAX_CHALLENGE_ATTEMPTS** | 5 | The maximum amount of session challenge attempts allowed. |
127
156
  | **CAPTCHA_SESSION_EXPIRATION** | 60 | The amount of seconds till captcha session expiration on creation. Setting to 0 will disable expiration. |
128
157
  | **CAPTCHA_FONT** | captcha-font.ttf | The file path to the font being used for captcha generation. |
129
- | **TWO_STEP_SESSION_EXPIRATION** | 200 | The amount of seconds till two step session expiration on creation. Setting to 0 will disable expiration. |
130
- | **AUTHENTICATION_SESSION_EXPIRATION** | 2692000 | The amount of seconds till authentication session expiration on creation. Setting to 0 will disable expiration. |
158
+ | **TWO_STEP_SESSION_EXPIRATION** | 200 | The amount of seconds till two-step session expiration on creation. Setting to 0 will disable expiration. |
159
+ | **AUTHENTICATION_SESSION_EXPIRATION** | 86400 | The amount of seconds till authentication session expiration on creation. Setting to 0 will disable expiration. |
160
+ | **AUTHENTICATION_REFRESH_EXPIRATION** | 2592000 | The amount of seconds till authentication refresh expiration. |
131
161
  | **ALLOW_LOGIN_WITH_USERNAME** | False | Allows login via username and email. |
132
162
  | **INITIAL_ADMIN_EMAIL** | admin@example.com | Email used when creating the initial admin account. |
133
163
  | **INITIAL_ADMIN_PASSWORD** | admin123 | Password used when creating the initial admin account. |
134
164
 
135
165
  ## Usage
136
166
 
137
- Sanic Security's authentication and verification functionality is session based. A new session will be created for the user after the user logs in or requests some form of verification (two-step, captcha). The session data is then encoded into a JWT and stored on a cookie on the user’s browser. The session cookie would be sent
167
+ Sanic Security's authentication and verification functionality is session based. A new session will be created for the user after the user logs in or requests some form of verification (two-step, captcha). The session data is then encoded into a JWT and stored on a cookie on the user’s browser. The session cookie is then sent
138
168
  along with every subsequent request. The server can then compare the session stored on the cookie against the session information stored in the database to verify user’s identity and send a response with the corresponding state.
139
169
 
140
170
  The tables in the below examples represent example [request form-data](https://sanicframework.org/en/guide/basics/request.html#form).
@@ -168,11 +198,11 @@ async def on_register(request):
168
198
  account = await register(request)
169
199
  two_step_session = await request_two_step_verification(request, account)
170
200
  await email_code(
171
- account.email, two_step_session.code # Code = AJ8HGD
201
+ account.email, two_step_session.code # Code = 197251
172
202
  ) # Custom method for emailing verification code.
173
203
  response = json(
174
204
  "Registration successful! Email verification required.",
175
- two_step_session.bearer.json,
205
+ two_step_session.json,
176
206
  )
177
207
  two_step_session.encode(response)
178
208
  return response
@@ -190,9 +220,7 @@ Verifies the client's account via two-step session code.
190
220
  @app.post("api/security/verify")
191
221
  async def on_verify(request):
192
222
  two_step_session = await verify_account(request)
193
- return json(
194
- "You have verified your account and may login!", two_step_session.bearer.json
195
- )
223
+ return json("You have verified your account and may login!", two_step_session.json)
196
224
  ```
197
225
 
198
226
  * Login (With Two-factor Authentication)
@@ -211,11 +239,11 @@ async def on_login(request):
211
239
  request, authentication_session.bearer
212
240
  )
213
241
  await email_code(
214
- authentication_session.bearer.email, two_step_session.code # Code = BG5KLP
242
+ authentication_session.bearer.email, two_step_session.code # Code = 197251
215
243
  ) # Custom method for emailing verification code.
216
244
  response = json(
217
245
  "Login successful! Two-factor authentication required.",
218
- authentication_session.bearer.json,
246
+ authentication_session.json,
219
247
  )
220
248
  authentication_session.encode(response)
221
249
  two_step_session.encode(response)
@@ -231,12 +259,27 @@ Fulfills client authentication session's second factor requirement via two-step
231
259
  | **code** | BG5KLP |
232
260
 
233
261
  ```python
234
- @app.post("api/security/validate-2fa")
262
+ @app.post("api/security/fulfill-2fa")
235
263
  async def on_two_factor_authentication(request):
236
264
  authentication_session = await fulfill_second_factor(request)
237
265
  response = json(
238
266
  "Authentication session second-factor fulfilled! You are now authenticated.",
239
- authentication_session.bearer.json,
267
+ authentication_session.json,
268
+ )
269
+ authentication_session.encode(response)
270
+ return response
271
+ ```
272
+
273
+ * Anonymous Login
274
+
275
+ Simply create a new session and encode it.
276
+
277
+ ```python
278
+ @app.post("api/security/login/anon")
279
+ async def on_anonymous_login(request):
280
+ authentication_session = await AuthenticationSession.new(request)
281
+ response = json(
282
+ "Anonymous client now associated with session!", authentication_session.json
240
283
  )
241
284
  authentication_session.encode(response)
242
285
  return response
@@ -248,32 +291,42 @@ async def on_two_factor_authentication(request):
248
291
  @app.post("api/security/logout")
249
292
  async def on_logout(request):
250
293
  authentication_session = await logout(request)
251
- response = json("Logout successful!", authentication_session.bearer.json)
252
- return response
294
+ return json("Logout successful!", authentication_session.json)
253
295
  ```
254
296
 
255
297
  * Authenticate
256
298
 
299
+ New/Refreshed session automatically returned if expired during authentication, requires encoding.
300
+
257
301
  ```python
258
302
  @app.post("api/security/auth")
259
303
  async def on_authenticate(request):
260
304
  authentication_session = await authenticate(request)
261
- return json(
305
+ response = json(
262
306
  "You have been authenticated.",
263
- authentication_session.bearer.json,
307
+ authentication_session.json,
264
308
  )
309
+ if authentication_session.is_refresh:
310
+ authentication_session.encode(response)
311
+ return response
265
312
  ```
266
313
 
267
314
  * Requires Authentication (This method is not called directly and instead used as a decorator.)
268
315
 
316
+ New/Refreshed session automatically returned if expired during authentication, requires encoding.
317
+
269
318
  ```python
270
319
  @app.post("api/security/auth")
271
320
  @requires_authentication
272
321
  async def on_authenticate(request):
273
- return json(
322
+ authentication_session = request.ctx.authentication_session.json
323
+ response = json(
274
324
  "You have been authenticated.",
275
- request.ctx.authentication_session.bearer.json,
325
+ authentication_session.json,
276
326
  )
327
+ if authentication_session.is_refresh:
328
+ authentication_session.encode(response)
329
+ return response
277
330
  ```
278
331
 
279
332
  ## Captcha
@@ -285,10 +338,6 @@ downloading a .ttf font and defining the file's path in the configuration.
285
338
 
286
339
  [Recommended Font](https://www.1001fonts.com/source-sans-pro-font.html)
287
340
 
288
- Captcha challenge example:
289
-
290
- [![Captcha image.](https://github.com/na-stewart/sanic-security/blob/main/images/captcha.png?raw=true)](https://github.com/na-stewart/sanic-security/blob/main/images/captcha.png?raw=true)
291
-
292
341
  * Request Captcha
293
342
 
294
343
  ```python
@@ -320,7 +369,7 @@ async def on_captcha(request):
320
369
  | **captcha** | FV9NMQ |
321
370
 
322
371
  ```python
323
- @app.post("ap/security/captcha")
372
+ @app.post("api/security/captcha")
324
373
  @requires_captcha
325
374
  async def on_captcha(request):
326
375
  return json("Captcha attempt successful!", request.ctx.captcha_session.json)
@@ -341,12 +390,12 @@ Two-step verification should be integrated with other custom functionality. For
341
390
  async def on_two_step_request(request):
342
391
  two_step_session = await request_two_step_verification(request)
343
392
  await email_code(
344
- account.email, two_step_session.code # Code = DT6JZX
393
+ two_step_session.bearer.email, two_step_session.code # Code = 197251
345
394
  ) # Custom method for emailing verification code.
346
- response = json("Verification request successful!", two_step_session.bearer.json)
395
+ response = json("Verification request successful!", two_step_session.json)
347
396
  two_step_session.encode(response)
348
397
  return response
349
- ```
398
+ ```
350
399
 
351
400
  * Resend Two-step Verification Code
352
401
 
@@ -355,9 +404,9 @@ async def on_two_step_request(request):
355
404
  async def on_two_step_resend(request):
356
405
  two_step_session = await TwoStepSession.decode(request)
357
406
  await email_code(
358
- account.email, two_step_session.code # Code = DT6JZX
407
+ two_step_session.bearer.email, two_step_session.code # Code = 197251
359
408
  ) # Custom method for emailing verification code.
360
- return json("Verification code resend successful!", two_step_session.bearer.json)
409
+ return json("Verification code resend successful!", two_step_session.json)
361
410
  ```
362
411
 
363
412
  * Two-step Verification
@@ -370,9 +419,7 @@ async def on_two_step_resend(request):
370
419
  @app.post("api/security/two-step")
371
420
  async def on_two_step_verification(request):
372
421
  two_step_session = await two_step_verification(request)
373
- response = json(
374
- "Two-step verification attempt successful!", two_step_session.bearer.json
375
- )
422
+ response = json("Two-step verification attempt successful!", two_step_session.json)
376
423
  return response
377
424
  ```
378
425
 
@@ -388,7 +435,7 @@ async def on_two_step_verification(request):
388
435
  async def on_two_step_verification(request):
389
436
  response = json(
390
437
  "Two-step verification attempt successful!",
391
- request.ctx.two_step_session.bearer.json,
438
+ request.ctx.two_step_session.json,
392
439
  )
393
440
  return response
394
441
  ```
@@ -532,7 +579,7 @@ Contributions are what make the open source community such an amazing place to b
532
579
  <!-- LICENSE -->
533
580
  ## License
534
581
 
535
- Distributed under the GNU Affero General Public License v3.0. See `LICENSE` for more information.
582
+ Distributed under the MIT License. See `LICENSE` for more information.
536
583
 
537
584
  <!-- Versioning -->
538
585
  ## Versioning