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.
- sanic_security-1.12.0/LICENSE +21 -0
- sanic_security-1.11.6/README.md → sanic_security-1.12.0/PKG-INFO +85 -38
- sanic_security-1.11.6/PKG-INFO → sanic_security-1.12.0/README.md +577 -591
- sanic_security-1.12.0/pyproject.toml +31 -0
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/authentication.py +140 -136
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/authorization.py +51 -42
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/configuration.py +26 -20
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/exceptions.py +43 -21
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/models.py +114 -62
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/test/server.py +67 -23
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/test/tests.py +80 -15
- sanic_security-1.12.0/sanic_security/utils.py +86 -0
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/verification.py +20 -19
- sanic_security-1.12.0/sanic_security.egg-info/PKG-INFO +608 -0
- sanic_security-1.12.0/sanic_security.egg-info/SOURCES.txt +19 -0
- sanic_security-1.12.0/sanic_security.egg-info/dependency_links.txt +1 -0
- sanic_security-1.12.0/sanic_security.egg-info/requires.txt +16 -0
- sanic_security-1.12.0/sanic_security.egg-info/top_level.txt +1 -0
- sanic_security-1.12.0/setup.cfg +4 -0
- sanic_security-1.11.6/LICENSE +0 -661
- sanic_security-1.11.6/pyproject.toml +0 -28
- sanic_security-1.11.6/sanic_security/test/__pycache__/__init__.cpython-39.pyc +0 -0
- sanic_security-1.11.6/sanic_security/test/__pycache__/server.cpython-39.pyc +0 -0
- sanic_security-1.11.6/sanic_security/test/__pycache__/tests.cpython-39.pyc +0 -0
- sanic_security-1.11.6/sanic_security/utils.py +0 -82
- {sanic_security-1.11.6 → sanic_security-1.12.0}/sanic_security/__init__.py +0 -0
- {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
|
[](https://github.com/psf/black)
|
11
|
-
[](https://pepy.tech/project/sanic-security)
|
42
|
+
[](https://pepy.tech/project/sanic-security)
|
12
43
|
[](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
|
130
|
-
| **AUTHENTICATION_SESSION_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
|
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 =
|
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.
|
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 =
|
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.
|
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/
|
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.
|
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
|
-
|
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
|
-
|
305
|
+
response = json(
|
262
306
|
"You have been authenticated.",
|
263
|
-
authentication_session.
|
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
|
-
|
322
|
+
authentication_session = request.ctx.authentication_session.json
|
323
|
+
response = json(
|
274
324
|
"You have been authenticated.",
|
275
|
-
|
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
|
-
[](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("
|
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
|
-
|
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.
|
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
|
-
|
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.
|
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.
|
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
|
582
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
536
583
|
|
537
584
|
<!-- Versioning -->
|
538
585
|
## Versioning
|