fastlifeweb 0.21.0__py3-none-any.whl → 0.22.0__py3-none-any.whl

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 (62) hide show
  1. CHANGELOG.md +8 -1
  2. fastlife/__init__.py +40 -13
  3. fastlife/adapters/__init__.py +1 -1
  4. fastlife/adapters/fastapi/__init__.py +9 -0
  5. fastlife/adapters/fastapi/form.py +26 -0
  6. fastlife/{request → adapters/fastapi}/form_data.py +1 -1
  7. fastlife/{request → adapters/fastapi}/localizer.py +4 -2
  8. fastlife/adapters/fastapi/request.py +33 -0
  9. fastlife/{routing → adapters/fastapi/routing}/route.py +3 -3
  10. fastlife/{routing → adapters/fastapi/routing}/router.py +1 -1
  11. fastlife/adapters/itsdangerous/__init__.py +3 -0
  12. fastlife/adapters/itsdangerous/session.py +50 -0
  13. fastlife/adapters/jinjax/jinjax_ext/inspectable_component.py +7 -7
  14. fastlife/adapters/jinjax/jinjax_ext/jinjax_doc.py +1 -1
  15. fastlife/adapters/jinjax/renderer.py +5 -5
  16. fastlife/adapters/jinjax/widget_factory/factory.py +13 -3
  17. fastlife/adapters/jinjax/widgets/base.py +1 -1
  18. fastlife/adapters/jinjax/widgets/model.py +1 -1
  19. fastlife/adapters/jinjax/widgets/sequence.py +1 -1
  20. fastlife/adapters/jinjax/widgets/union.py +1 -1
  21. fastlife/components/Form.jinja +1 -1
  22. fastlife/components/pydantic_form/FatalError.jinja +8 -0
  23. fastlife/config/__init__.py +3 -6
  24. fastlife/config/configurator.py +17 -15
  25. fastlife/config/resources.py +1 -2
  26. fastlife/config/views.py +2 -2
  27. fastlife/domain/model/asgi.py +3 -0
  28. fastlife/{request → domain/model}/form.py +13 -22
  29. fastlife/{request → domain/model}/request.py +8 -31
  30. fastlife/domain/model/security_policy.py +105 -0
  31. fastlife/middlewares/base.py +1 -1
  32. fastlife/middlewares/reverse_proxy/x_forwarded.py +1 -2
  33. fastlife/middlewares/session/__init__.py +2 -2
  34. fastlife/middlewares/session/middleware.py +4 -3
  35. fastlife/middlewares/session/serializer.py +0 -44
  36. fastlife/{services/policy.py → service/check_permission.py} +1 -1
  37. fastlife/{security → service}/csrf.py +2 -2
  38. fastlife/{services → service}/locale_negociator.py +5 -8
  39. fastlife/{config → service}/registry.py +13 -7
  40. fastlife/service/security_policy.py +100 -0
  41. fastlife/{services → service}/templates.py +1 -6
  42. fastlife/{services → service}/translations.py +3 -0
  43. fastlife/{config/settings.py → settings.py} +6 -12
  44. fastlife/shared_utils/infer.py +24 -1
  45. fastlife/{templates/constants.py → template_globals.py} +2 -2
  46. fastlife/testing/testclient.py +2 -2
  47. fastlife/views/__init__.py +1 -0
  48. fastlife/views/pydantic_form.py +6 -0
  49. {fastlifeweb-0.21.0.dist-info → fastlifeweb-0.22.0.dist-info}/METADATA +1 -1
  50. {fastlifeweb-0.21.0.dist-info → fastlifeweb-0.22.0.dist-info}/RECORD +57 -53
  51. tailwind.config.js +1 -1
  52. fastlife/request/__init__.py +0 -5
  53. fastlife/security/__init__.py +0 -1
  54. fastlife/security/policy.py +0 -188
  55. fastlife/templates/__init__.py +0 -7
  56. fastlife/templates/inline.py +0 -26
  57. /fastlife/{routing → adapters/fastapi/routing}/__init__.py +0 -0
  58. /fastlife/domain/model/{security.py → csrf.py} +0 -0
  59. /fastlife/{services → service}/__init__.py +0 -0
  60. {fastlifeweb-0.21.0.dist-info → fastlifeweb-0.22.0.dist-info}/WHEEL +0 -0
  61. {fastlifeweb-0.21.0.dist-info → fastlifeweb-0.22.0.dist-info}/entry_points.txt +0 -0
  62. {fastlifeweb-0.21.0.dist-info → fastlifeweb-0.22.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,19 +1,29 @@
1
- CHANGELOG.md,sha256=GaTZcagNH8oWB_T917vp4fV52KakMUJO2Tzu5Mme7ns,6617
2
- fastlife/__init__.py,sha256=r7aiYUizYR5f2jZ5UBTugsP6Adm-k9AU-tlpPl71QLk,957
3
- fastlife/adapters/__init__.py,sha256=WYjEN8gp4r7LCHqmIO5VzzvsT8QGRE3w4G47UwYDtAo,94
1
+ CHANGELOG.md,sha256=gtRawAWGc5B7HSVjRWA2eng5K_1jDm-AZrioc2niKWw,6987
2
+ fastlife/__init__.py,sha256=vccDwPrkKjB4N-yBdqWN5fCaUJzUnFyNAE35pcIz9kU,1664
3
+ fastlife/adapters/__init__.py,sha256=imPD1hImpgrYkvUJRhHA5kVyGAua7VbP2WGkhSWKJT8,93
4
+ fastlife/adapters/fastapi/__init__.py,sha256=1goV1FGFP04TGyskJBLKZam4Gvt1yoAvLMNs4ekWSSQ,243
5
+ fastlife/adapters/fastapi/form.py,sha256=csxsDI6RK-g41pMwFhaVQCLDhF7dAZzgUp-VcrC3NFY,823
6
+ fastlife/adapters/fastapi/form_data.py,sha256=2DQ0o-RvY6iROUKQjS-UJdNYEVSsNPd-AjpergI3w54,4473
7
+ fastlife/adapters/fastapi/localizer.py,sha256=XD1kCJuAlkGevivmvAJEcGMCBWMef9rAfTOGmt3PVWU,436
8
+ fastlife/adapters/fastapi/request.py,sha256=oyAZ1QKW2mh-9CadQdOdn_BqnVVjaZ6aG4eTNK2R2j0,1095
9
+ fastlife/adapters/fastapi/routing/__init__.py,sha256=8EMnQE5n8oA4J9_c3nxzwKDVt3tefZ6fGH0d2owE8mo,195
10
+ fastlife/adapters/fastapi/routing/route.py,sha256=g-MlXFvyRzVsNO_bBYDQQHD03fmRXEOm9KHxIHFZmug,1461
11
+ fastlife/adapters/fastapi/routing/router.py,sha256=jzrnU_Lyywu21e3spPaWQw8ujZh_Yy_EJOojcCi6ew4,499
12
+ fastlife/adapters/itsdangerous/__init__.py,sha256=7ocGY7v0cxooZBKQYjA2JkmzRqiBvcU1uzA84UsTVAI,84
13
+ fastlife/adapters/itsdangerous/session.py,sha256=9h_WRsXqZbytHZOv5B_K3OWD5mbfYzxHulXoOf6D2MI,1685
4
14
  fastlife/adapters/jinjax/__init__.py,sha256=4JRAUwFGpTxYtRlg5sU79AahxyAiRMhllRFHoI-dnug,117
5
15
  fastlife/adapters/jinjax/jinjax_ext/__init__.py,sha256=z6NWvHzTNEq6bVO4iJoTR6-y4A6UtS_VuSMV_tff1jY,49
6
16
  fastlife/adapters/jinjax/jinjax_ext/docstring.py,sha256=Zlx0oSxsRU9vQvGoyScXf9uB1W8JaoreGoJK3Xi26RE,2791
7
17
  fastlife/adapters/jinjax/jinjax_ext/inspectable_catalog.py,sha256=KHOYTT6UNA41QwyLNQVoG4trOVXYdChlRmqq_G1pv1s,2987
8
- fastlife/adapters/jinjax/jinjax_ext/inspectable_component.py,sha256=Cz6PrRhO3lXUI9baxosOr6MtZFjuOki9YTEWMkfbbR0,2909
9
- fastlife/adapters/jinjax/jinjax_ext/jinjax_doc.py,sha256=uPcYiUTrliR2lLpRuQUrirmFzTEVRTwo1mUZE4Z5onc,10225
10
- fastlife/adapters/jinjax/renderer.py,sha256=PMqPpnF6wGwWAb4sXw_B-h35n7UHRViU8VxySlyWlBM,5240
18
+ fastlife/adapters/jinjax/jinjax_ext/inspectable_component.py,sha256=Ye_0XIKPC2H2XAvqEc1Er3YWyvNyYS4chuVkTSY5bAk,2909
19
+ fastlife/adapters/jinjax/jinjax_ext/jinjax_doc.py,sha256=S4-JNQ2NehUdKkc6mzAWRE_oyuw3XYPkR53RArgpDFk,10218
20
+ fastlife/adapters/jinjax/renderer.py,sha256=8Pv2Ivg8iObPa-LeIfj764p2MEq78wzHqxZeLDIdLc8,5255
11
21
  fastlife/adapters/jinjax/widget_factory/__init__.py,sha256=Dy_2xr_YDAyEF9WtNpjV-aYaehRO1iKEIHVFdfFeszw,59
12
22
  fastlife/adapters/jinjax/widget_factory/base.py,sha256=TLEpYdekR4AeHhIie_DICc_oSvQaUaL8GlatqNiRewg,1046
13
23
  fastlife/adapters/jinjax/widget_factory/bool_builder.py,sha256=ElIDb6rlUiwuDAetC22TreoMa9HDgoZ2euVV1VurFFY,1291
14
24
  fastlife/adapters/jinjax/widget_factory/emailstr_builder.py,sha256=hO0_4yd0lZ8mLqAzM_FMecdtkSa03AIG13cvs6K9JPA,1532
15
25
  fastlife/adapters/jinjax/widget_factory/enum_builder.py,sha256=agx67oUeVy5_BKzY4WV0DxT67R43Vy74CoeHl9PBvK4,1527
16
- fastlife/adapters/jinjax/widget_factory/factory.py,sha256=xEgrJ2U4Ys0XKhOCbw_Im2De_gD2fRO_BJgb1a0fCZI,5571
26
+ fastlife/adapters/jinjax/widget_factory/factory.py,sha256=zTa6zbpW5lAh_eHlhO6XBP2GbeDTHatymhMAJQ-alTI,5915
17
27
  fastlife/adapters/jinjax/widget_factory/literal_builder.py,sha256=mrtWbDMKNFtw5ufJK3DnkkttGGk16EnDQhejyOd57Ys,1758
18
28
  fastlife/adapters/jinjax/widget_factory/model_builder.py,sha256=WgIEUExtGO_s9AlNQlaTG_136ipe64MIJsNP0nlnsOc,2236
19
29
  fastlife/adapters/jinjax/widget_factory/secretstr_builder.py,sha256=JJLqN74tUSTDDBYcRLDuqOLSL0P16S1Fp-SqTCdjjgg,1573
@@ -22,21 +32,21 @@ fastlife/adapters/jinjax/widget_factory/set_builder.py,sha256=kwtVLATkoOFTcKBKHk
22
32
  fastlife/adapters/jinjax/widget_factory/simpletype_builder.py,sha256=olP66B9AMY1X8fgEAxhMdozWN_w1TtcIAIW6uPJRSng,1570
23
33
  fastlife/adapters/jinjax/widget_factory/union_builder.py,sha256=qQOK3Y4I0Tg0XOzU_DwseaaKRmqQ7ORMfFyIHd6oysU,2841
24
34
  fastlife/adapters/jinjax/widgets/__init__.py,sha256=HERnX9xiXUbTDz3XtlnHWABTBjhIq_kkBgWs5E6ZIMY,42
25
- fastlife/adapters/jinjax/widgets/base.py,sha256=hG6_MWnedKC55P2WAqtXokplMwAOmjb4WUVLx2n8ZOE,4121
35
+ fastlife/adapters/jinjax/widgets/base.py,sha256=jU-oklWuM6MPlNzBvYO0HtxUrUteb-Dh96OudPLFJx4,4120
26
36
  fastlife/adapters/jinjax/widgets/boolean.py,sha256=GFvyO2Lz-vTJ8lpX2UrkJk7ymu0vU-xnBBEmyBKamJg,613
27
37
  fastlife/adapters/jinjax/widgets/checklist.py,sha256=xsr_edMu1nTcNnMEs1AAS3U-ugK95pEqn5NV5hjTeI0,1747
28
38
  fastlife/adapters/jinjax/widgets/dropdown.py,sha256=ou8U48txShr8IXdwF4_pBvTn1VcR9SazZKzbLcsN3_0,1458
29
39
  fastlife/adapters/jinjax/widgets/hidden.py,sha256=IKcVYs6NjN8YjW-UTr3DRBong6Wrc0QLgcp8U9JoQmE,638
30
- fastlife/adapters/jinjax/widgets/model.py,sha256=JKLDUxIReLO_0VcU2px3WHfF9d-eeNy4ZvJKwvGKzso,1299
31
- fastlife/adapters/jinjax/widgets/sequence.py,sha256=qWiTrVe1BTl7_ZVsep6QzUZxKfeJj6PD0xl62KiEnpE,2560
40
+ fastlife/adapters/jinjax/widgets/model.py,sha256=YBIEWa_6mnmrBnesXjLTrpJ4drUS2CIorNmhK24cz7Q,1298
41
+ fastlife/adapters/jinjax/widgets/sequence.py,sha256=XhIPRJyE9UXFetlDQA83N64kKlTqkj6WPcgPm6XF7mo,2559
32
42
  fastlife/adapters/jinjax/widgets/text.py,sha256=uYdJ1bjA3-2vEumh2nnd264wAaHU758ZxEiN2BaqtcE,2143
33
- fastlife/adapters/jinjax/widgets/union.py,sha256=-Pp8HDFmzoV4mT0u8oqqC3AVsWMt7vYo_ios0nyRLzw,2603
43
+ fastlife/adapters/jinjax/widgets/union.py,sha256=roCoFA82dLjF1XFW6UYaV7SCQWdFsSAT8Ux7KEB6_Us,2602
34
44
  fastlife/components/A.jinja,sha256=rjnOFNpM2SUeJ0P8FDe3jzc_1WlsL65Kv-tb6KMCEpw,1389
35
45
  fastlife/components/Button.jinja,sha256=COtCjDpzGLNqtBUYsHw7gdUay4kff3KdLJFAzrEnMmo,2310
36
46
  fastlife/components/Checkbox.jinja,sha256=47_E9uPdr3QKUvRVhNQA7VE0uh5FVslQM26cdF0WCtY,753
37
47
  fastlife/components/CsrfToken.jinja,sha256=mS0q-3_hAevl_waWEPaN0QAYOBzMyzl-W1PSpEHUBA0,215
38
48
  fastlife/components/Details.jinja,sha256=BKyhSU7bZdbd_deTjmAGcMbgUoQW3h8JSR3thH-2oJA,741
39
- fastlife/components/Form.jinja,sha256=Wb0nK5xuhqhkuQll9j76i3nBJcYCIjXG9RE9nWeoPZc,2095
49
+ fastlife/components/Form.jinja,sha256=Aukx9cVR8Af1nIsdHst3Qk7Bz34g1RpDhl7WOIcy0Tg,2094
40
50
  fastlife/components/H1.jinja,sha256=ODwQMgwtuy2E2ShgamjFDlnCwOQQuuLIhvEzUF66nYM,375
41
51
  fastlife/components/H2.jinja,sha256=LcBE2R_N50gio01nxH9qhp8_G1HxOT91xG_u8J8ae_Q,375
42
52
  fastlife/components/H3.jinja,sha256=3PzxfQh07A35Og6dE5ow9BZdNp2Qnu7OuVeWREvD7Uo,375
@@ -1672,61 +1682,55 @@ fastlife/components/icons/solid/WrenchScrewdriver.jinja,sha256=bqF-g6PTJds_KK2cM
1672
1682
  fastlife/components/icons/solid/XCircle.jinja,sha256=pO93hG8JImNOy94B62tN7fdzkzGvSsqkSkkZlkLaxeo,791
1673
1683
  fastlife/components/icons/solid/XMark.jinja,sha256=c-ngdLuYwEMicwm4-Aj4xcEc1uQ_LrBoPhdDhQutEA8,705
1674
1684
  fastlife/components/pydantic_form/Error.jinja,sha256=vVSb1BKyKLOD4IOAM7aCKSNh7aAlmoiZVgRuvDCwLIo,205
1685
+ fastlife/components/pydantic_form/FatalError.jinja,sha256=lFVlNrXzBR6ExMahq77h0tYlD46T2yUzsBwqO8Gn58g,338
1675
1686
  fastlife/components/pydantic_form/Hint.jinja,sha256=8leBpfMGDmalc_KAjr2paTojr_rwq-luS6m_1BGj7Tw,202
1676
1687
  fastlife/components/pydantic_form/Widget.jinja,sha256=PgguUpvhG6CY9AW6H8qQMjKqjlybjDCAaFFAOHzrzVQ,418
1677
- fastlife/config/__init__.py,sha256=R0HXh0rt6Aecf5kJmXvhH-6QrQb1SyuI83bOU8T80fc,488
1678
- fastlife/config/configurator.py,sha256=vkoMcq4Ndr1JjEZWavoFspRyYGhdsvCo3LBj3icfu3Q,24618
1688
+ fastlife/config/__init__.py,sha256=5qpuaVYqi-AS0GgsfggM6rFsSwXgrqrLBo9jH6dVroc,407
1689
+ fastlife/config/configurator.py,sha256=nxowUriGj_MYcBlcBLB49HepDIbHiF4gG3baC_V3mFM,24702
1679
1690
  fastlife/config/exceptions.py,sha256=9MdBnbfy-Aw-KaIFzju0Kh8Snk41-v9LqK2w48Tdy1s,1169
1680
1691
  fastlife/config/openapiextra.py,sha256=rYoerrn9sni2XwnO3gIWqaz7M0aDZPhVLjzqhDxue0o,514
1681
- fastlife/config/registry.py,sha256=zP_LPvwTcUZdrrsCnRaUfJzeYq7M_eVdRWlN0oO52RE,1754
1682
- fastlife/config/resources.py,sha256=Wu3vVr7XD18Gf4-MYYCxAAnuRmsAJmpllonts_BVGdQ,8593
1683
- fastlife/config/settings.py,sha256=t9goMfnc_oWrS_c3vgivIe0w6N2Byohcfol2CAnLiJs,3892
1684
- fastlife/config/views.py,sha256=2YjkCN9da1ck20c69IZIozM1qRjAxWdSPjcxqupUX_o,2392
1692
+ fastlife/config/resources.py,sha256=u6OgnbHfGkC5idH-YPNkIPf8GJnZpJoGVZ-Ym022BCo,8533
1693
+ fastlife/config/views.py,sha256=9CZ0qNi8vKvQuGo1GgM6cwNK8WwHOxwIHqtikAOaOHY,2399
1685
1694
  fastlife/domain/__init__.py,sha256=3zDDos5InVX0el9OO0lgSDGzdUNYIhlA6w4uhBh2pF8,29
1686
1695
  fastlife/domain/model/__init__.py,sha256=aoBjaSpDscuFXvtknJHwiNyoJRUpE-v4X54h_wNuo2Y,27
1687
- fastlife/domain/model/security.py,sha256=BUiWK-S7rVciWHO1qTkM8e_KxzpF6gGC4MMJK1v6iDo,414
1696
+ fastlife/domain/model/asgi.py,sha256=RSTnfTsofOmCaWzHNuRGowjlyHYmoDCrXFbvNY_B55k,129
1697
+ fastlife/domain/model/csrf.py,sha256=BUiWK-S7rVciWHO1qTkM8e_KxzpF6gGC4MMJK1v6iDo,414
1698
+ fastlife/domain/model/form.py,sha256=WriBT1qUUIbf5x5iewo9ChEcr6k0en8jMTD0iaei5Pk,3253
1699
+ fastlife/domain/model/request.py,sha256=K0_pSOboKw5IRL8SCIsEuPZlPPe3h0F5cugZEVFdfoo,2531
1700
+ fastlife/domain/model/security_policy.py,sha256=iYBKXOYaXxM_n-rsyB25lO6RblSx9icTx1Bg-s3Iz9k,2942
1688
1701
  fastlife/domain/model/template.py,sha256=z9oxdKme1hMPuvk7mBiKR_tuVY8TqH77aTYqMgvEGl8,876
1689
1702
  fastlife/domain/model/types.py,sha256=64jJKFAi5x0e3vr8naHU1m_as0Qy8MS-s9CG0z6K1qc,381
1690
1703
  fastlife/middlewares/__init__.py,sha256=C3DUOzR5EhlAv5Zq7h-Abyvkd7bUsJohTRSB2wpRYQE,220
1691
- fastlife/middlewares/base.py,sha256=9OYqByRuVoIrLt353NOedPQTLdr7LSmxhb2BZcp20qk,638
1704
+ fastlife/middlewares/base.py,sha256=7FZE_1YU7wNew2u1qdYXjamosk4CXJmg1mJWGp6Xhc0,649
1692
1705
  fastlife/middlewares/reverse_proxy/__init__.py,sha256=g1SoVDmenKzpAAPYHTEsWgdBByOxtLg9fGx6RV3i0ok,846
1693
- fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=0O9tziA63gQBmKATQz3B8H8G9CjZjnfM9NaisrvJHRY,1714
1694
- fastlife/middlewares/session/__init__.py,sha256=3XgXcIO6yQls5G7x8K2T8b7a_enA_7rQptWZcp3j2Ak,1400
1695
- fastlife/middlewares/session/middleware.py,sha256=R48x3MJ-tu8siy8G12hDHa83sMcZz6E1eEb0xwk77E4,3166
1696
- fastlife/middlewares/session/serializer.py,sha256=wpaktDP5v1spmbD-D3Q68EK9A0KInE4DT8mkogBJ3Fc,2157
1706
+ fastlife/middlewares/reverse_proxy/x_forwarded.py,sha256=PPDjcfwik5eoYaolSY1Y4x5QMKpDV0XrOP_i4Am0y30,1724
1707
+ fastlife/middlewares/session/__init__.py,sha256=ZhXWXs53A__F9wJKBJ87rW8Qyt5Mn866vhzKDxVZ4t0,1348
1708
+ fastlife/middlewares/session/middleware.py,sha256=ituZ5hNipDMkgCXNE4zbnmOcWEF151sucPo4I_FpY-I,3137
1709
+ fastlife/middlewares/session/serializer.py,sha256=nbJGiCJ_ryZxkW1I28kmK6hD3U98D4ZlUQA7B8_tngQ,635
1697
1710
  fastlife/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1698
- fastlife/request/__init__.py,sha256=-wrh12uWM7ysmIUE6FszBit2H6iI5LWVEnHxQJ_23ZE,157
1699
- fastlife/request/form.py,sha256=BiuvbV85NkvnJECSxqabfq3PhMfdKMPVobS35PhxSFA,3595
1700
- fastlife/request/form_data.py,sha256=JZmKbKZz8nnspvCHYHQrz-xsFVJFaWHkTilUWk7Fx-M,4448
1701
- fastlife/request/localizer.py,sha256=9MXAcsod-Po5qeg4lttD3dyumiI0y5vGHCwSSmt9or8,349
1702
- fastlife/request/request.py,sha256=6y7Su4tS7GLx-udzvKQBMb1-Sdt3GaCWaBz8vKSN5Hw,3291
1703
- fastlife/routing/__init__.py,sha256=8EMnQE5n8oA4J9_c3nxzwKDVt3tefZ6fGH0d2owE8mo,195
1704
- fastlife/routing/route.py,sha256=vqjfMsHAVO0l2B8fuB8t19CKMtE7WoBkG4kvi4lUonM,1441
1705
- fastlife/routing/router.py,sha256=ho9TvTkX2iUW6GEh99FgclZVFKkCCCxYG4pPHeUtGn8,482
1706
- fastlife/security/__init__.py,sha256=QYDcJ3oXQzqXQxoDD_6biGAtercFrtePttoifiL1j34,25
1707
- fastlife/security/csrf.py,sha256=lQ6GcSrs6GiUN03hRJqlqw2a9CJ9Wkt1joLE9lszd6w,1870
1708
- fastlife/security/policy.py,sha256=4WHu8xhR7tAdXUHpHY1kdVIdTOFsUl92R8IsIRyYMSU,5579
1709
- fastlife/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1710
- fastlife/services/locale_negociator.py,sha256=Np2O8s7xnYTpf5eCG7LvcfFJ2LV7p_k86NNrU9Lju88,846
1711
- fastlife/services/policy.py,sha256=RfYGPjfEAAoHECUnZVLPZgN0iRanu8UKQSky6oAz81o,1687
1712
- fastlife/services/templates.py,sha256=ICNznXw3lEEiMyU60uqmq1uu8IWjF2iro1l-8SE0w_8,2716
1713
- fastlife/services/translations.py,sha256=dfLopdQnkMTaehth2guRVBOKxxt7paMp8SgoJ4z0Ilc,5664
1711
+ fastlife/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1712
+ fastlife/service/check_permission.py,sha256=-XD9qA11dLwen0bNCTy2Id_dCjzTJ0j7xuwB9IOtEY0,1695
1713
+ fastlife/service/csrf.py,sha256=wC1PaKOmZ3il0FF_kevxnlg9PxDqruRdLrNnOA3ZHrU,1886
1714
+ fastlife/service/locale_negociator.py,sha256=wXgQR8jCtPd5XtM-vvGZ4OrVnBQlt0deSoE2nInNfb0,770
1715
+ fastlife/service/registry.py,sha256=B6n5b_b0RgxJj0qFOpnrJFmG7_MPtvShwV6yH9V6vi0,2098
1716
+ fastlife/service/security_policy.py,sha256=Ytl8hgXtytvBNoBRHRmqVD96fJMnERnaL90q6XG7yI8,3036
1717
+ fastlife/service/templates.py,sha256=QPAIUbbZiekazz_jV3q4JCwQd6Q4KA6a4RDek2RWuhE,2548
1718
+ fastlife/service/translations.py,sha256=D-1D3pVNytEcps1u-0K7FmgQ8Wo6Yu4XVHvZrPhBmAI,5795
1719
+ fastlife/settings.py,sha256=q-rz4CEF2RQGow5-m-yZJOvdh3PPb2c1Q_ZLJGnu4VQ,3647
1714
1720
  fastlife/shared_utils/__init__.py,sha256=i66ytuf-Ezo7jSiNQHIsBMVIcB-tDX0tg28-pUOlhzE,26
1715
- fastlife/shared_utils/infer.py,sha256=3G_u6q2aWzeiVlAyGaWIlnAcz90m4bFNwpPYd5JIqfE,723
1721
+ fastlife/shared_utils/infer.py,sha256=0GflLkaWJ-4LZ1Ig3moR-_o55wwJ_p_vJ4xo-yi3lyA,1406
1716
1722
  fastlife/shared_utils/resolver.py,sha256=Wb9cO2MWavpti63hju15xmwFMgaD5DsQaxikRpB39E8,3713
1717
- fastlife/templates/__init__.py,sha256=OEXVdehy-rZ9IHikjNAAlfVdC0tJPlkTsIFTltIAFGo,162
1718
- fastlife/templates/constants.py,sha256=MGdUjkF9hsPMN8rOS49eWbAApcb8FL-FAeFvJU8k90M,8387
1719
- fastlife/templates/inline.py,sha256=PEG53QXSYie6MMOM7ty2zl_uvdE4TvrZJGrySSJTgvU,722
1723
+ fastlife/template_globals.py,sha256=rJ7XB9DlPubejs_GDlEyO9V98QZTJnmdTznlguYOyoc,8386
1720
1724
  fastlife/testing/__init__.py,sha256=VpxkS3Zp3t_hH8dBiLaGFGhsvt511dhBS_8fMoFXdmU,99
1721
1725
  fastlife/testing/dom.py,sha256=dVzDoZokn-ii681UaEwAr-khM5KE-CHgXSSLSo24oH0,4489
1722
1726
  fastlife/testing/form.py,sha256=ST0xNCoUqz_oD92cWHzQ6CbJ5hFopvu_NNKpOfiuYWY,7874
1723
1727
  fastlife/testing/session.py,sha256=LEFFbiR67_x_g-ioudkY0C7PycHdbDfaIaoo_G7GXQ8,2226
1724
- fastlife/testing/testclient.py,sha256=WmUnGkDPuSd4dKzTiXWyHWlJ31zBbySvMH9m8p0acg8,6741
1725
- fastlife/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1726
- fastlife/views/pydantic_form.py,sha256=4dv37JORLpvkgCgMGZfUN_qy7wme040GLZAzOTFqdnU,1367
1727
- fastlifeweb-0.21.0.dist-info/METADATA,sha256=lw-gAs-o2cUJKjUL2xz1H_o0tW8Kbpgnc8qbrhKXzxQ,3663
1728
- fastlifeweb-0.21.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
1729
- fastlifeweb-0.21.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1730
- fastlifeweb-0.21.0.dist-info/licenses/LICENSE,sha256=NlRX9Z-dcv8X1VFW9odlIQBbgNN9pcO94XzvKp2R16o,1075
1731
- tailwind.config.js,sha256=y_xTuRmjIdrfyo92PoUW0wjFTnkO27xepwfirkaCFno,1351
1732
- fastlifeweb-0.21.0.dist-info/RECORD,,
1728
+ fastlife/testing/testclient.py,sha256=JTIgeMKooA8L4gEodeC3gy4Lo27y3WNswSEIKLlVVPs,6745
1729
+ fastlife/views/__init__.py,sha256=zG8gveL8e2zBdYx6_9jtZfpQ6qJT-MFnBY3xXkLwHZI,22
1730
+ fastlife/views/pydantic_form.py,sha256=o7EUItciAGL1OSaGNHo-3BTrYAk34GuWE7zGikjiAGY,1486
1731
+ fastlifeweb-0.22.0.dist-info/METADATA,sha256=8ual_JaeNHufsRyP5pdCPu2yHuVpzMzR53aitRbHmjo,3663
1732
+ fastlifeweb-0.22.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
1733
+ fastlifeweb-0.22.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1734
+ fastlifeweb-0.22.0.dist-info/licenses/LICENSE,sha256=NlRX9Z-dcv8X1VFW9odlIQBbgNN9pcO94XzvKp2R16o,1075
1735
+ tailwind.config.js,sha256=EN3EahBDmQBbmJvkw3SdGWNOkfkzw0cg-QvBikOhkrw,1348
1736
+ fastlifeweb-0.22.0.dist-info/RECORD,,
tailwind.config.js CHANGED
@@ -2,7 +2,7 @@
2
2
  module.exports = {
3
3
  darkMode: "class",
4
4
  content: [
5
- "./src/fastlife/templates/constants.py",
5
+ "./src/fastlife/template_globals.py",
6
6
  "./src/fastlife/components/*.jinja",
7
7
  "./src/fastlife/components/**/*.jinja",
8
8
  "./tests/fastlife_app/templates/*.jinja",
@@ -1,5 +0,0 @@
1
- """HTTP Request."""
2
-
3
- from .request import GenericRequest, Registry, Request, get_request
4
-
5
- __all__ = ["Request", "Registry", "GenericRequest", "get_request"]
@@ -1 +0,0 @@
1
- """Security features."""
@@ -1,188 +0,0 @@
1
- """Security policy."""
2
-
3
- import abc
4
- import logging
5
- from collections.abc import Callable, Coroutine
6
- from typing import Annotated, Any, Generic, Literal, TypeVar
7
- from uuid import UUID
8
-
9
- from fastapi import Depends, HTTPException
10
- from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
11
-
12
- from fastlife import GenericRequest, get_request
13
- from fastlife.config.registry import TRegistry
14
-
15
- CheckPermissionHook = Callable[..., Coroutine[Any, Any, None]] | Callable[..., None]
16
- CheckPermission = Callable[[str], CheckPermissionHook]
17
-
18
- TUser = TypeVar("TUser")
19
-
20
- log = logging.getLogger(__name__)
21
-
22
-
23
- class Unauthorized(HTTPException):
24
- """An exception raised to stop a request exectution and return an HTTP Error."""
25
-
26
- def __init__(
27
- self,
28
- status_code: int = HTTP_401_UNAUTHORIZED,
29
- detail: str = "Unauthorized",
30
- headers: dict[str, str] | None = None,
31
- ) -> None:
32
- super().__init__(status_code, detail, headers)
33
-
34
-
35
- class Forbidden(HTTPException):
36
- """An exception raised to stop a request exectution and return an HTTP Error."""
37
-
38
- def __init__(
39
- self,
40
- status_code: int = HTTP_403_FORBIDDEN,
41
- detail: str = "Forbidden",
42
- headers: dict[str, str] | None = None,
43
- ) -> None:
44
- super().__init__(status_code, detail, headers)
45
-
46
-
47
- class BoolMeta(type):
48
- def __bool__(cls) -> bool:
49
- return cls.kind == "allowed" # type: ignore
50
-
51
- def __repr__(cls) -> str:
52
- return cls.reason # type: ignore
53
-
54
-
55
- class HasPermission(int, metaclass=BoolMeta):
56
- """
57
- A type used to know if a permission is allowed or not.
58
-
59
- It behave has a boolean, but 3 possibilities exists defind has 3 sub-types
60
- {class}`Allowed` {class}`Unauthenticated` or {class}`Denied`.
61
-
62
- In many cases Unauthenticated call may redirect to a login page,
63
- where authenticated user are not redirected. they have an error message,
64
- or the frontend may use the information to adapt its interface.
65
- """
66
-
67
- kind: Literal["allowed", "unauthenticated", "denied"]
68
- reason: str
69
-
70
- def __new__(cls, reason: str) -> "HasPermission":
71
- instance = super().__new__(cls)
72
- instance.reason = reason
73
- return instance
74
-
75
- def __repr__(self) -> str:
76
- return self.reason
77
-
78
- def __bool__(self) -> bool:
79
- return self.kind == "allowed"
80
-
81
-
82
- class Allowed(HasPermission):
83
- """Represent a permission check result that is allowed."""
84
-
85
- kind = "allowed"
86
- reason = "Allowed"
87
-
88
-
89
- class Unauthenticated(HasPermission):
90
- """
91
- Represent a permission check result that is not allowed due to
92
- missing authentication mechanism.
93
- """
94
-
95
- kind = "unauthenticated"
96
- reason = "Authentication required"
97
-
98
-
99
- class Denied(HasPermission):
100
- """
101
- Represent a permission check result that is not allowed due to lack of permission.
102
- """
103
-
104
- kind = "denied"
105
- reason = "Access denied to this resource"
106
-
107
-
108
- class AbstractSecurityPolicy(abc.ABC, Generic[TUser, TRegistry]):
109
- """Security policy base classe."""
110
-
111
- Forbidden = Forbidden
112
- """The exception raised if the user identified is not granted."""
113
- Unauthorized = Unauthorized
114
- """The exception raised if no user has been identified."""
115
-
116
- request: GenericRequest[TRegistry]
117
- """Request where the security policy is applied."""
118
-
119
- def __init__(
120
- self, request: Annotated[GenericRequest[TRegistry], Depends(get_request)]
121
- ):
122
- """
123
- Build the security policy.
124
-
125
- When implementing a security policy, multiple parameters can be added
126
- to the constructor as FastAPI dependencies, using the `Depends` FastAPI
127
- annotation.
128
- The security policy is installed has a depenency of the router that hold
129
- a route prefix of the application.
130
- """
131
- self.request = request
132
- self.request.security_policy = self # we do backref to implement has_permission
133
-
134
- @abc.abstractmethod
135
- async def identity(self) -> TUser | None:
136
- """
137
- Return app-specific user object or raise an HTTPException.
138
- """
139
-
140
- @abc.abstractmethod
141
- async def authenticated_userid(self) -> str | UUID | None:
142
- """
143
- Return app-specific user object or raise an HTTPException.
144
- """
145
-
146
- @abc.abstractmethod
147
- async def has_permission(
148
- self, permission: str
149
- ) -> HasPermission | type[HasPermission]:
150
- """Allow access to everything if signed in."""
151
-
152
- @abc.abstractmethod
153
- async def remember(self, user: TUser) -> None:
154
- """Save the user identity in the request session."""
155
-
156
- @abc.abstractmethod
157
- async def forget(self) -> None:
158
- """Destroy the request session."""
159
-
160
-
161
- class InsecurePolicy(AbstractSecurityPolicy[None, Any]):
162
- """
163
- An implementation of the security policy made for explicit unsecured access.
164
-
165
- Setting a permission on a view require a security policy, if not set, accessing
166
- to a view will raise a RuntimeError. To bypass this error for testing purpose
167
- or your own reason, the InsecurePolicy has to be set to the configurator.
168
- """
169
-
170
- async def identity(self) -> None:
171
- """Nobodies is identified."""
172
- return None
173
-
174
- async def authenticated_userid(self) -> str | UUID:
175
- """An uuid mades of 0."""
176
- return UUID(int=0)
177
-
178
- async def has_permission(
179
- self, permission: str
180
- ) -> HasPermission | type[HasPermission]:
181
- """Access is allways granted."""
182
- return Allowed
183
-
184
- async def remember(self, user: None) -> None:
185
- """Do nothing."""
186
-
187
- async def forget(self) -> None:
188
- """Do nothing."""
@@ -1,7 +0,0 @@
1
- """
2
- Utilities for rendering HTML templates for page and components as FastAPI dependencies.
3
- """
4
-
5
- from .inline import InlineTemplate
6
-
7
- __all__ = ["InlineTemplate"]
@@ -1,26 +0,0 @@
1
- """Inline templates."""
2
-
3
- import inspect
4
- from collections.abc import Callable
5
- from typing import Any, get_args
6
-
7
- from fastlife.domain.model.template import InlineTemplate
8
- from fastlife.shared_utils.infer import is_union
9
-
10
-
11
- def is_inline_template_returned(endpoint: Callable[..., Any]) -> bool:
12
- signature = inspect.signature(endpoint)
13
- return_annotation = signature.return_annotation
14
-
15
- if isinstance(return_annotation, type) and issubclass(
16
- return_annotation, InlineTemplate
17
- ):
18
- return True
19
-
20
- if is_union(return_annotation):
21
- return any(
22
- isinstance(arg, type) and issubclass(arg, InlineTemplate)
23
- for arg in get_args(return_annotation)
24
- )
25
-
26
- return False
File without changes
File without changes