asyncio style refactoring
This commit is contained in:
@@ -14,7 +14,7 @@ app.include_router(router=protected_user_action_routes)
|
|||||||
|
|
||||||
|
|
||||||
@app.get("")
|
@app.get("")
|
||||||
def root()->dict:
|
async def root()->dict:
|
||||||
return {"root":"hello, this is root"}
|
return {"root":"hello, this is root"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Generated
+116
-82
@@ -1,5 +1,21 @@
|
|||||||
# This file is automatically @generated by Poetry 2.4.1 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.4.1 and should not be changed by hand.
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aiosqlite"
|
||||||
|
version = "0.22.1"
|
||||||
|
description = "asyncio bridge to the standard sqlite3 module"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.9"
|
||||||
|
groups = ["main"]
|
||||||
|
files = [
|
||||||
|
{file = "aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb"},
|
||||||
|
{file = "aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["attribution (==1.8.0)", "black (==25.11.0)", "build (>=1.2)", "coverage[toml] (==7.10.7)", "flake8 (==7.3.0)", "flake8-bugbear (==24.12.12)", "flit (==3.12.0)", "mypy (==1.19.0)", "ufmt (==2.8.0)", "usort (==1.0.8.post1)"]
|
||||||
|
docs = ["sphinx (==8.1.3)", "sphinx-mdinclude (==0.6.2)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alembic"
|
name = "alembic"
|
||||||
version = "1.18.5"
|
version = "1.18.5"
|
||||||
@@ -567,92 +583,91 @@ standard-no-fastapi-cloud-cli = ["email-validator (>=2.0.0)", "fastapi-cli[stand
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "greenlet"
|
name = "greenlet"
|
||||||
version = "3.5.3"
|
version = "3.5.4"
|
||||||
description = "Lightweight in-process concurrent programming"
|
description = "Lightweight in-process concurrent programming"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.10"
|
python-versions = ">=3.10"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""
|
|
||||||
files = [
|
files = [
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c180d22d325fb613956b443c3c6f4406eb70e6defc70d3974da2a7b59e06f48c"},
|
{file = "greenlet-3.5.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:ac5bf81d79d2c8eeb2ef6359b2e1687a1e9ebf46c2b1f970da9a9255df51d190"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483d08c11181c83a6ce1a7a61df0f624a208ec40817a3bb2302714592eee4f04"},
|
{file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89f3738167bab8c1084b94e23023d41d247117ac149fa0fbcb5bd4cf6262b353"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1dae6e0091eae084317e411f047f0b7cb241c6db570f7c45fd6b900a274914ce"},
|
{file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e9a5e3406e3ed8125ae1a3b37c12f3434e2b1f0fa053197c5557895b4fb09606"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0f6ff50ff8dbd51fae9b37f4101648b04ea0df19b3f50ab2beb5061e7716a5c8"},
|
{file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a2d614cb2372c7101a12ea8b96dd56f81c986d247c5a73db67063f3ed1ca4a52"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bcd2d72ccd70a1ec68ba6ef93e7fbb4420ef9997dabc7010d893bd4015e0bec"},
|
{file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4ab9f0704bccf6d3b38e0d2130b7b33271cff11453690da074fa280c3aa8e8e7"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:37bf9c538f5ae6e63d643f88dec37c0c83bdf0e2ebc62961dedcf458822f7b71"},
|
{file = "greenlet-3.5.4-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:188e4d142f243051d92a1f5c244a741da02dddc070a0620c842804d7b56d008c"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:73f152c895e09907e0dbe24f6c2db37beb085cd63db91c3825a0fcd0064124a8"},
|
{file = "greenlet-3.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2cdaadc3d31445a8f782bde3cd37e49a2c2a9c6da6daf76a3e34c683b271a3c7"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8bdb43e1a1d1873721acab2be99c5befd4d2044ddfd52e4d610801019880a702"},
|
{file = "greenlet-3.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:70bdfacdc183dac838b2a0aaff2dd6134a457c52fe68a9c6bbab435483d2b9df"},
|
||||||
{file = "greenlet-3.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:0909f9355a9f24845d3299f3112e266a06afb68302041989fd26bd68894933db"},
|
{file = "greenlet-3.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:69173331fbc5d64bfac0065d7e22c39cfcd089e9b18d125bdcd5079363b09616"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:aca9b4ce85b152b5524ef7d88170efdff80dc0032aa8b75f9aaf7f3479ea95b4"},
|
{file = "greenlet-3.5.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e883de250e299654b1f1680f72a1a9f9ba62c9bd1bce84099c90657349a8dfbb"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f71be4920368fe1fabeeaa53d1e3548337e2b223d9565f8ad5e392a75ba23fc"},
|
{file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32802705c2c1ff25e8237b3bdacf2594fa02be80af8a66703eb7853ea7e68686"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d77e67f65f98449e3fb83f795b5d0a8437aead2f874ca89c96576caf4be3af6"},
|
{file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57aa201b351f7c7c75627c60d29e4d5b97a07d37efeb62b903466fca42c097d7"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e18619ba655ac05d78d80fc83cac4ba892bd6927b99e3b8237aee861aaacc8bb"},
|
{file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9667862a2e38ad379f11b845daeda22c8989186def44f06962c9c4c05e556da7"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8540f1e6205bd13ca0ce685581037219ca54a1b41a0a15d228c6c9b8ad5903d7"},
|
{file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3fe76c2cac86b4f7a1e92865ac0a54384deb05c92986287c1a7110d9bd53071"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:d27c0c653a60d9535f690226474a5cc1036a8b0d7b57504d1c4f89c44a07a80c"},
|
{file = "greenlet-3.5.4-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:ae53534b5dec0f4c2ec26f898f538dc8ea1ca3ef2927d597a9439e40a09da937"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ef56fe650f50575bf843acde967b9c567687f3c22340941a899b7bc56e956a8"},
|
{file = "greenlet-3.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1e1a4a684b16c45ba324e60b32a4386a87722bcb815d2a149d2182f9b401ca72"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5121af01cf911e70056c00d4b46d5e9b5d1415550038573d744138bacb59e6b8"},
|
{file = "greenlet-3.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e849e6e139b9671adeac505f72fc05f4af7fd1921faef40295e214fc3b361b59"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:0f41e4a05a3c0cb31b17023eff28dd111e1d16bf7d7d00406cd7df23f31398a7"},
|
{file = "greenlet-3.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:dc418cf4c873357964d6624445ed09472e50def990c65dd4e76fc3ba8cd9cef6"},
|
||||||
{file = "greenlet-3.5.3-cp311-cp311-win_arm64.whl", hash = "sha256:ec6f1af59f6b5f3fc9678e2ea062d8377d22ac644f7844cb7a292910cf12ff44"},
|
{file = "greenlet-3.5.4-cp311-cp311-win_arm64.whl", hash = "sha256:c38c902a0986eba1f6e7ba1ab39ad5195926abde90f3fe080e08212db62176da"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:719757059f5a53fd0dde23f78cffeafcdd97b21c850ddb7ca684a3c1a1f122e2"},
|
{file = "greenlet-3.5.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3d66250e8b09f182ede05490998c818b5961f7a3640332d44c4927caec7bbfe4"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efa9f765dd09f9d0cdac651ffdf631ee59ec5dc6ee7a73e0c012ba9c52fbdf5b"},
|
{file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c90e930c9c192e5b3ee9fb8bcd920ea3926155e2e3ded39fc697323addecee17"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7faba15ac005376e02a0384504e0243be3370ce010296a44a820feb342b505ab"},
|
{file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:791fdfeeb9c6e0c7b10fa151bf110d2a6974866f13dcb5b1c7efae698245893a"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5795cd1101371140551c645f2d408b8d3c01a5a29cf8a9bce6e759c983682d23"},
|
{file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b7c895310363f310361e0fe2072af85269d2a2a285cd04c0c59e79a5e3670dcf"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:87142215824be6ac05e2e8e2786eec307ccbc27c36723c3881959df654af6861"},
|
{file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f88193799d43dbf8c8a806d6405c9c52fe2af40bf75072a606357b33cc336c7f"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:af4923b3096e26a36d7e9cf24ab88083a20f97d191e3b97f253731ce9b41b28c"},
|
{file = "greenlet-3.5.4-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:13b980043cb1b3134e81ea469da1250ddcc6bfe6d245bbaa59168d9cdc8f228f"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215275b1b49320987352e6c1b054acca0064f965a2c66992bed9a6f7d913f149"},
|
{file = "greenlet-3.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7a5f095767c4493afcd06067f2bb3b8716e3f3f9e92b99c88e7e99f885b3d4d"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6b1b0eed82364b0e32c4ea0f221452d33e6bb17ae094d9f72aed9851812747ea"},
|
{file = "greenlet-3.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:42afdc1ab5f66da8c586c32af9224a74a706b4f0ea0dc3a4188a0860a09c65c9"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:cde8adafa2365676f74a979744629589999093bc86e2484214f58e61df08902c"},
|
{file = "greenlet-3.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:60149df8f462d1b230038e6590c23c3b4768bb5d6c022b3b6e82532b34b0b8a3"},
|
||||||
{file = "greenlet-3.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:c4e7b79d83805475f0102008843f6eb45fd3bb0b2e88c774adab5fbaab27117d"},
|
{file = "greenlet-3.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:77d6ce04fed0d9aeed42e0f37923cc43eba9b027bdd9c34546bb4ccd143d0fe0"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c8d87c2134d871df96ecdea9cec7cbaab286dadab0f56476e57aaf9e8ac11550"},
|
{file = "greenlet-3.5.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:24e61b88cb7e1b1d794b32a10cc346ac779681d6d74ff137a3e0a444d2bf1f02"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d185dd1621757e70c3861cceffd5317ab4e7ed7eb09c82994828468527ade5"},
|
{file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:870d730fec833f5a06906a32596cc099b9161594642a92a520b7a88911c95356"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1c514a468149bf8fbbab874188a3535cd8a48a3e353eb53a3d424296f8dbacd3"},
|
{file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec5ff0d1878df6af3bf9b638a5a92a7d5693291de77c91bff10fa48519c604ef"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9ad04dd75458c6300b047c61b8639092433d205a25a14e310d6582a480efcca1"},
|
{file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:07bd44616608d873d06735b63ef1a88191d6ca57c8d291d6559c71bc14c0893c"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:915f887cf2682b66419b879423a2e072634aa7b7dce6f3ada4957cfced3f1e9a"},
|
{file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d84d993f6e575c950d91a23c1345d18fe1a4310d447bf630849d7809196b52f0"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:afaabdd554cd7ae9bbb3ca070b0d7fdfd207dbf1d16865f7233837709d354bda"},
|
{file = "greenlet-3.5.4-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:3529a8a933582ad19e224792cac7372489526576b75b4c124e8e4f29948f4861"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:766cfd421c13e450feb340cd472a3ed9957d438727b7b4593ad7c76c5d2b0deb"},
|
{file = "greenlet-3.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:58023945f421093de5e6fa108c0985a8659d43f49e0216da25099369a121bcbd"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ecda9ec22edf38fa389369eaed8c3d37c05f3c54e69f69438dbb2cc1de1458b"},
|
{file = "greenlet-3.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bae2728e1897aa8df8cb1af38cd48b3a743aefe29372de7b8b7a9f532501e69f"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:c82304750f057167ff60d188df1d0cc1764ce9567eadf03e6a7443bcedd0b30b"},
|
{file = "greenlet-3.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:ca5726c0b08ca35ae873557266a78b2c3f3b2b7d7401aa5ff886c2045dd0111c"},
|
||||||
{file = "greenlet-3.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:dc133a1569ee667b2a6ef56ce551084aeefd87a5acbc4736d336d1e2edc6cfc4"},
|
{file = "greenlet-3.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:7c1303791d603080cac6fc3b34df51c3b75b723739c282c8029e48a0d241672f"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:fd2e02fa07485778536a036222d616ab957b1d533f36b3ed98ce725d9c9d3117"},
|
{file = "greenlet-3.5.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:7e8afa5eac028f8140ceafe5ceec66e6aa127ddcb21452d2a564dcd2900b5f22"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0a0628d1597eb0897b62f55d1343f772405fd25f3b2a796c76874b0c2e22e8"},
|
{file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73b37afe369021423ea53dd3123e04bffa7e93ac64429b9f50835b2e4fcae7cf"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ebd933a6adabc298bab47731a130fe6bfb888bd934eee37810f151159544540d"},
|
{file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ef964f56dfcb6f9bbef2a190d9126795eac408716aeae47b5e7c73c32aafca9"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8d19fe6c39ebff9259f07bcc685d3290f8fa4ea2278e51dd0008e4d6b0f2d814"},
|
{file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cef589bc65fae02d10bca2ac341191c5b33acc2967892ebf4fcbd10eabb7a74c"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b9d501b40e80b70e32323c799dd9b420a5577a9601469d362ae1ffb690f3a7c"},
|
{file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c53ff01a5c53a40f2c16820ebc56d7c61a77f5fbe009dadd96292d5682f80f8"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:962c5df2db8cb446da51edf1ca5296c389d93b99c9d8aa2ee4c7d0d8f1218260"},
|
{file = "greenlet-3.5.4-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:dfc41ae893d9ceaf22c824f2153a88b30651b20e8758c2cd9ac143f23640563c"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a1fad1d11e7d6aab184107baa8e4ece11ccba3ec9599cd7efa5ff4d70d43256a"},
|
{file = "greenlet-3.5.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecca4d80d55a01ad6b23b33262662956149fbb7b2c6be2910f1705921958cbf3"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fad5aec764399f1b5cc347ad250a59660f20c8f8888ea6bae1f93b769cce1154"},
|
{file = "greenlet-3.5.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffbc533e0eaf8e80d8471411646ab88fe58f641d508c0b02b24494479f4d9ec"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:7669aa24cf2a1041d6f7899575b494a3ab4cf68bfcc8609b1dc0be7272db835e"},
|
{file = "greenlet-3.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:305f69e6c4523d7f6979ed001cff4e5853c063e5da04880296603aa0227e544c"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:5b4807c4082c9d1b6d9eed56fcd041863e37f2228106eef24c30ca096e238605"},
|
{file = "greenlet-3.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:f260930bbbbcf9caee661211235a5111c86dfe5832fdf6ae4570da1e0995320f"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:271a8ea7c1024e8a0d7dd2be66dd66dda8a07193f41a17b9e924f7600f5b62be"},
|
{file = "greenlet-3.5.4-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:41ddab54e4b238f4a6c323f39b4e59e176affd5a94d461a9fb7583dac74240a3"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19131729ae0ddc3c2e1ef85e650169b5e37ee32e400f215f78b94d7b0d567310"},
|
{file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3dabe3e2809013052c68bdf0b7fa5f5f2859c43a80803131ad61af9cabd7867"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1540dd8e5fc2a5aec40fbb98ef8e149fa47c89a4b4a1cf2575a14d3d1869d7a8"},
|
{file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:27d3f00718634d4520a3a150154ac5da36f257869d41321953375b90bfbbc72c"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b897d97759425953f69a9c0fac67f8fe333ec0ce7377ef186fb2b0c3ad5e354d"},
|
{file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:39169a11d87a6a263afda3e9a27d1df16d0f919d40a4837cc73986c9884c0dd8"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e81fa194a1d20967877bdf9c7794db2bc99063e5be36aee710c08f04c5bb087f"},
|
{file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbd60b5763c6543c1827e48faaf14ea9bfbad245f52b1a4d76a2a2d8884c6c66"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:3236754d423955ea08e9bb5f6c04a7895f9e22c290b66aa7653fcb922d839eb0"},
|
{file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:bd3d1145f603b2db19feb9078c2e6855eb7c67e15580c010ed815cee519b86fd"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:55cf4d777485d43110e47133cbba6d74a8885a87ec1227ef0267f9ee80c5aa21"},
|
{file = "greenlet-3.5.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f00f910f0e7b35416c63b23ad78b769aeccfc1775f712b43c4ee525624a2eef7"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:12a248ba75f6a9a236375f52296c498c89ff1d8badf32deb9eca7abd5853f7da"},
|
{file = "greenlet-3.5.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:91c26423753b92caf41ab3f98fd547d7374d4d9fc2d85be041886c1579d9255e"},
|
||||||
{file = "greenlet-3.5.3-cp314-cp314t-win_amd64.whl", hash = "sha256:efc6bd60ea02e085862c74a3ef64b147ffc6f1a5ea7d9f26e7a939943f68c1e3"},
|
{file = "greenlet-3.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:ee032b91fd8ec29ec6c4cea2b8c561b178435134bd0752c7334b94e9c736c132"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:ea03f2f04367845d6b58eeed276e1e56e51f0b97d8ad5a88a7d20a91dc9056cc"},
|
{file = "greenlet-3.5.4-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:178111881dd7a6c946471fda85485ec796e1043c2b939f694b096e2ecf986809"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78dbef602fda6d97d957eb7937f70c9ce9e9527330347f8f6b6f9e554a9e7a47"},
|
{file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d92df08dd65fede97fc37aad36c2e9dcda3b31c467f8e0c2c096456cb818e927"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f73857adb8fee13fa56c172bd11262f888c0c648f9fea113e777bb2c7904a81"},
|
{file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99e8f8c4ebc4fd80aa26c1280ae9ad43a0976e786349703a181cf0bae60413e5"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cefa9cef4b371f9844c6053db71f1138bc6807bab1578b0dae5149c1f1141357"},
|
{file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1f17e362d78e37559e0506c5a7d066bdd45073c36a0127a543e8a0df27242ff3"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:232fec92e823addaf02d9472cf7381e24a1d046a6ced1103c5caa4c21b9dfc1d"},
|
{file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:394de08dad5ffcb1f50c2159d93e398d9d2da3ed437645eaa54771fa720db9f0"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:6219b6d04dbf6ba6084d77dc609e8473060dc55f759cbf626d512122781fa128"},
|
{file = "greenlet-3.5.4-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:cd320d998cbaa032932830448e39abf3c6a12901295e386e8114db926e10cffb"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:2421c3564da9429d5586d46ca31ebb26516b5498a802cf65c041a8e8a8980d34"},
|
{file = "greenlet-3.5.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:c883d61f2282d72c767a14936641b3efcbde9d82f1080712aaea0b1d3126cb88"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e0f0d160f0b2e558e6c75f7930967183255dc9735e5f5b8cae58ee09c9576d8b"},
|
{file = "greenlet-3.5.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2a924f15d17957e252a810acefcb5942f5ca712298e8b6fcaed9a307d357522c"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-win_amd64.whl", hash = "sha256:dd99329bbc15ca78dcc583dba05d0b1b0bae01ab6c2174989f5aaee3e41ac930"},
|
{file = "greenlet-3.5.4-cp315-cp315-win_amd64.whl", hash = "sha256:ed17e5f3420360d5b459de8462efb52060399a5326a613d4cde31cef63ef95da"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315-win_arm64.whl", hash = "sha256:499fef2acede88c1864a57bb586b4bf533c81e1b82df7ab93451cdb47dfec227"},
|
{file = "greenlet-3.5.4-cp315-cp315-win_arm64.whl", hash = "sha256:f908898d6fa484ce4b6f447ce70ea99b52c503fee419e53cf74d60a16bc9e667"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:176bc16a721fa5fc294d70b87b4dfa5fbdd251b3da5d5372735ecef9bd7d6d0c"},
|
{file = "greenlet-3.5.4-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:1833637f17d5e7472548a48575c394fe39f1b1890d676d162d86593610f44d8c"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:629b614d2b786e89c50440e246f33eea78f58a962d0bdbbcc809e6d13605903f"},
|
{file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:12cda9122e03341f1cb6b8207a19d7a9d375e52f1b4e9243918375f40fd7b4b9"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b2e857ae16f5f72142edf75f9f176fe7526ba19a2841df1420516f83831c9f2"},
|
{file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d83ae0e32d14957ab7170785a20f582635c8474deab1bfbb552b17e769a6ce25"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d192579ed281051396dddd7f7754dac6259e6b1fb26378c87b66622f8e3f91"},
|
{file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:123aa379c962ed5fe90a880327e0c3066124ac64ec99e12a238be9fd8eb3db3d"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e515757e2e36bcbf1fad09a46e1557e8b1ae1797d4b44d09da7deed88ad28608"},
|
{file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f1467de1bb767f75db0aa34c195e3a496d8d1278c796e70c24ce205d3e99cde"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:4399eb8d041f20b68d943918bc55502a93d6fdc0a37c14da7881c04139acee9d"},
|
{file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:adf2244d7f69409925a8f22ed22cc5f93cdfe5c9dc87ff3476be2c2aaae61a05"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b363d46ed1ea431825fdb01471bb024fc08399bad1572a616e853c7684415adb"},
|
{file = "greenlet-3.5.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0fa53040b78b578120eecdc0265e3f1051487cc425d11a2b7c761daadf4feaa8"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:e44da2f5bbdaabaf7d80b73dbb430c7035771e9f244e3c8b769715c9d8fa0a16"},
|
{file = "greenlet-3.5.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:60e0bc961d367df506660e9ac0177a76bc6d81305300704b0977d1634f76efe2"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-win_amd64.whl", hash = "sha256:8ff8bed3e3baa20a3ea261ce00526f1898ad4801d4886fd2220580ee0ad8fadf"},
|
{file = "greenlet-3.5.4-cp315-cp315t-win_amd64.whl", hash = "sha256:f680e549edb3eaf21eea4e7fe101e15ec180c74b7879ab46adc080f22d4015d2"},
|
||||||
{file = "greenlet-3.5.3-cp315-cp315t-win_arm64.whl", hash = "sha256:b7068bd09f761f3f5b4d214c2bed063186b2a86148c740b3873e3f56d79bac31"},
|
{file = "greenlet-3.5.4-cp315-cp315t-win_arm64.whl", hash = "sha256:08fc36de8442d5c3e95b044550dbea9bf144d31ec0cc58e36fb241cb6ef6a994"},
|
||||||
{file = "greenlet-3.5.3.tar.gz", hash = "sha256:a61efc018fd3eb317eeca31aba90ee9e7f26f22884a79b6c6ec715bf71bb62f1"},
|
{file = "greenlet-3.5.4.tar.gz", hash = "sha256:0232ae1de90a8e07867bb127d7a6ba2301e859145489f25cda8a6096dabe1d20"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@@ -1684,6 +1699,25 @@ pygments = ">=2.7.2"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
|
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest-asyncio"
|
||||||
|
version = "1.4.0"
|
||||||
|
description = "Pytest support for asyncio"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10"
|
||||||
|
groups = ["main"]
|
||||||
|
files = [
|
||||||
|
{file = "pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1"},
|
||||||
|
{file = "pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pytest = ">=8.4,<10"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)", "sphinx-tabs (>=3.5)"]
|
||||||
|
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest-cov"
|
name = "pytest-cov"
|
||||||
version = "7.1.0"
|
version = "7.1.0"
|
||||||
@@ -2151,4 +2185,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.13"
|
python-versions = ">=3.13"
|
||||||
content-hash = "ebbba0a60f3f121f79117d05b5a6dbd8914ca1d971776808c7d1cfd146b562bc"
|
content-hash = "9f5afa235b9e6861253603be40e4b5c3ae8d59b6d8bff7669d4e7670183ff336"
|
||||||
|
|||||||
+4
-1
@@ -25,7 +25,10 @@ dependencies = [
|
|||||||
"httpie (>=3.2.4,<4.0.0)",
|
"httpie (>=3.2.4,<4.0.0)",
|
||||||
"pytest-cov (>=7.1.0,<8.0.0)",
|
"pytest-cov (>=7.1.0,<8.0.0)",
|
||||||
"allure-pytest (>=2.16.0,<3.0.0)",
|
"allure-pytest (>=2.16.0,<3.0.0)",
|
||||||
"pytest-mock (>=3.15.1,<4.0.0)"
|
"pytest-mock (>=3.15.1,<4.0.0)",
|
||||||
|
"aiosqlite (>=0.22.1,<0.23.0)",
|
||||||
|
"greenlet (>=3.5.4,<4.0.0)",
|
||||||
|
"pytest-asyncio (>=1.4.0,<2.0.0)"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,3 +10,5 @@ markers=
|
|||||||
integra: integrations test
|
integra: integrations test
|
||||||
e2e: e2e tests
|
e2e: e2e tests
|
||||||
smoke: smoke tests
|
smoke: smoke tests
|
||||||
|
|
||||||
|
asyncio_mode = auto
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from sqlalchemy import and_, not_, select, update
|
from sqlalchemy import and_, not_, select, update
|
||||||
|
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
from src.models.database_models.model import RefreshTokens, engine
|
from src.models.database_models.model import RefreshTokens, engine
|
||||||
@@ -10,32 +11,32 @@ from src.models.pydantic_models.model import RefreshTokensOut
|
|||||||
|
|
||||||
class JwtCrudActions:
|
class JwtCrudActions:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.Session=sessionmaker(bind=engine)
|
self.Session=async_sessionmaker(bind=engine)
|
||||||
|
|
||||||
def get_token_by_user_id(self, user_id:UUID)->RefreshTokensOut|None:
|
async def get_token_by_user_id(self, user_id:UUID)->RefreshTokensOut|None:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
query=select(RefreshTokens).where(and_(RefreshTokens.user_id==user_id, not_(RefreshTokens.is_revoked)))
|
query=select(RefreshTokens).where(and_(RefreshTokens.user_id==user_id, not_(RefreshTokens.is_revoked)))
|
||||||
response=session.scalars(query).first()
|
response= (await session.scalars(query)).first()
|
||||||
if response is None:
|
if response is None:
|
||||||
return None
|
return None
|
||||||
return RefreshTokensOut.model_validate(response)
|
return RefreshTokensOut.model_validate(response)
|
||||||
|
|
||||||
def get_token_by_id(self, token_id:UUID)->RefreshTokensOut|None:
|
async def get_token_by_id(self, token_id:UUID)->RefreshTokensOut|None:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
query=select(RefreshTokens).where(RefreshTokens.id==token_id)
|
query=select(RefreshTokens).where(RefreshTokens.id==token_id)
|
||||||
response=session.scalars(query).one_or_none()
|
response= (await session.scalars(query)).one_or_none()
|
||||||
if response is None:
|
if response is None:
|
||||||
return None
|
return None
|
||||||
return RefreshTokensOut.model_validate(response)
|
return RefreshTokensOut.model_validate(response)
|
||||||
|
|
||||||
def create_token(self, data:dict)->None:
|
async def create_token(self, data:dict)->None:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
new_token=RefreshTokens(**data)
|
new_token=RefreshTokens(**data)
|
||||||
session.add(new_token)
|
session.add(new_token)
|
||||||
|
|
||||||
|
|
||||||
def create_and_update_token(self, data: dict, old_jti: UUID, new_jti: UUID) -> bool:
|
async def create_and_update_token(self, data: dict, old_jti: UUID, new_jti: UUID) -> bool:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
new_token = RefreshTokens(**data)
|
new_token = RefreshTokens(**data)
|
||||||
|
|
||||||
query = (
|
query = (
|
||||||
@@ -44,7 +45,7 @@ class JwtCrudActions:
|
|||||||
.values(is_revoked=True, replaced_by=new_jti)
|
.values(is_revoked=True, replaced_by=new_jti)
|
||||||
.returning(RefreshTokens.id)
|
.returning(RefreshTokens.id)
|
||||||
)
|
)
|
||||||
updated_id = session.execute(query).scalar_one_or_none()
|
updated_id = (await session.execute(query)).scalar_one_or_none()
|
||||||
|
|
||||||
if updated_id is None:
|
if updated_id is None:
|
||||||
return False
|
return False
|
||||||
@@ -53,15 +54,15 @@ class JwtCrudActions:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def revoke_all(self, user_id:UUID)->bool:
|
async def revoke_all(self, user_id:UUID)->bool:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
session.execute(update(RefreshTokens).where(RefreshTokens.user_id==user_id).values(is_revoked=True)) #bulk update
|
await session.execute(update(RefreshTokens).where(RefreshTokens.user_id==user_id).values(is_revoked=True)) #bulk update
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def logout(self,token_id:UUID)->bool:
|
async def logout(self,token_id:UUID)->bool:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
query=select(RefreshTokens).where(RefreshTokens.id == token_id)
|
query=select(RefreshTokens).where(RefreshTokens.id == token_id)
|
||||||
response=session.scalars(query).one_or_none()
|
response= (await session.scalars(query)).one_or_none()
|
||||||
if response is None:
|
if response is None:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.ext.asyncio import async_sessionmaker
|
||||||
|
|
||||||
from src.models.database_models.model import User, engine
|
from src.models.database_models.model import User, engine
|
||||||
from src.models.pydantic_models.model import UserOutDB
|
from src.models.pydantic_models.model import UserOutDB
|
||||||
@@ -10,20 +10,20 @@ from src.models.pydantic_models.model import UserOutDB
|
|||||||
class UsersCrudActions:
|
class UsersCrudActions:
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.Session=sessionmaker(bind=engine)
|
self.Session=async_sessionmaker(bind=engine)
|
||||||
|
|
||||||
def get_user_by_email(self, email:str)->UserOutDB|None:
|
async def get_user_by_email(self, email:str)->UserOutDB|None:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
query=select(User).where(User.email==email)
|
query=select(User).where(User.email==email)
|
||||||
response=session.scalars(query).one_or_none()
|
response=(await session.scalars(query)).one_or_none()
|
||||||
if response is None:
|
if response is None:
|
||||||
return None
|
return None
|
||||||
return UserOutDB.model_validate(response)
|
return UserOutDB.model_validate(response)
|
||||||
|
|
||||||
def get_user_by_id(self, id:UUID)->UserOutDB|None:
|
async def get_user_by_id(self, id:UUID)->UserOutDB|None:
|
||||||
with self.Session() as session, session.begin():
|
async with self.Session() as session, session.begin():
|
||||||
query=select(User).where(User.id==id)
|
query=select(User).where(User.id==id)
|
||||||
response=session.scalars(query).one_or_none()
|
response=(await session.scalars(query)).one_or_none()
|
||||||
if response is None:
|
if response is None:
|
||||||
return None
|
return None
|
||||||
return UserOutDB.model_validate(response)
|
return UserOutDB.model_validate(response)
|
||||||
@@ -10,12 +10,12 @@ from sqlalchemy import (
|
|||||||
String,
|
String,
|
||||||
Table,
|
Table,
|
||||||
Uuid,
|
Uuid,
|
||||||
create_engine,
|
|
||||||
func,
|
func,
|
||||||
)
|
)
|
||||||
|
from sqlalchemy.ext.asyncio import create_async_engine
|
||||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
||||||
|
|
||||||
engine = create_engine("sqlite:///DB/database.db", echo=True)
|
engine = create_async_engine("sqlite+aiosqlite:///DB/database.db", echo=True)
|
||||||
|
|
||||||
'''remember as a boilerplate, or just cp/pst'''
|
'''remember as a boilerplate, or just cp/pst'''
|
||||||
class Model(DeclarativeBase):
|
class Model(DeclarativeBase):
|
||||||
|
|||||||
+31
-30
@@ -1,3 +1,4 @@
|
|||||||
|
import asyncio
|
||||||
from datetime import UTC, datetime, timedelta
|
from datetime import UTC, datetime, timedelta
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
@@ -21,14 +22,14 @@ class CurrentUserService:
|
|||||||
self.jwt_db_actions=JwtCrudActions()
|
self.jwt_db_actions=JwtCrudActions()
|
||||||
self.error=Errors()
|
self.error=Errors()
|
||||||
|
|
||||||
def _check(self, form_data_email:str, form_data_password:str,):
|
async def _check(self, form_data_email:str, form_data_password:str,):
|
||||||
'''check user by email'''
|
'''check user by email'''
|
||||||
user=self.crud_db_actions.get_user_by_email(form_data_email)
|
user=await self.crud_db_actions.get_user_by_email(form_data_email)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
raise self.error.credentials_error(detail="Wrong credentials")
|
raise self.error.credentials_error(detail="Wrong credentials")
|
||||||
|
|
||||||
if not self.hash.verify_password(plain_password=form_data_password, hashed_password=user.hashed_password):
|
if not await asyncio.to_thread(self.hash.verify_password, plain_password=form_data_password, hashed_password=user.hashed_password):
|
||||||
raise self.error.credentials_error(detail="Wrong credentials")
|
raise self.error.credentials_error(detail="Wrong credentials")
|
||||||
|
|
||||||
if user.status is False:
|
if user.status is False:
|
||||||
@@ -36,7 +37,7 @@ class CurrentUserService:
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def _token_record_create(self, jti:UUID,user_id:UUID,token:str, request:Request)->RefreshTokensCreate:
|
async def _token_record_create(self, jti:UUID,user_id:UUID,token:str, request:Request)->RefreshTokensCreate:
|
||||||
|
|
||||||
return RefreshTokensCreate(
|
return RefreshTokensCreate(
|
||||||
id=jti,
|
id=jti,
|
||||||
@@ -48,9 +49,9 @@ class CurrentUserService:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_current_user(self, token:str)->UserOut:
|
async def get_current_user(self, token:str)->UserOut:
|
||||||
|
|
||||||
payload=self.jwt_service.jwt_decode(token)
|
payload= await self.jwt_service.jwt_decode(token)
|
||||||
sub=payload.get("sub")
|
sub=payload.get("sub")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -61,7 +62,7 @@ class CurrentUserService:
|
|||||||
if not (payload.get("token_type")=="access"):
|
if not (payload.get("token_type")=="access"):
|
||||||
raise self.error.credentials_error(detail="Jwt token type is incorrect")
|
raise self.error.credentials_error(detail="Jwt token type is incorrect")
|
||||||
|
|
||||||
user=self.crud_db_actions.get_user_by_id(sub)
|
user=await self.crud_db_actions.get_user_by_id(sub)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise self.error.not_found_error(detail="User with this email address not found")
|
raise self.error.not_found_error(detail="User with this email address not found")
|
||||||
|
|
||||||
@@ -72,15 +73,15 @@ class CurrentUserService:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_access_token(self, user_id:UUID)->str:
|
async def create_access_token(self, user_id:UUID)->str:
|
||||||
'''create new access token if all the checks are successful'''
|
'''create new access token if all the checks are successful'''
|
||||||
return self.jwt_service.create_access_token({"sub":str(user_id)})
|
return await self.jwt_service.create_access_token({"sub":str(user_id)})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_refresh_token(self,user_id:UUID, request:Request)->str:
|
async def create_refresh_token(self,user_id:UUID, request:Request)->str:
|
||||||
|
|
||||||
token, jti=self.jwt_service.create_refresh_token({"sub":str(user_id)})
|
token, jti= await self.jwt_service.create_refresh_token({"sub":str(user_id)})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
jti=UUID(jti)
|
jti=UUID(jti)
|
||||||
@@ -88,18 +89,18 @@ class CurrentUserService:
|
|||||||
raise self.error.credentials_error(detail="Jwt token is incorrect") from e
|
raise self.error.credentials_error(detail="Jwt token is incorrect") from e
|
||||||
|
|
||||||
'''create new refresh token if all the checks are successful'''
|
'''create new refresh token if all the checks are successful'''
|
||||||
token_record=self._token_record_create(jti=jti, user_id=user_id, token=token, request=request)
|
token_record=await self._token_record_create(jti=jti, user_id=user_id, token=token, request=request)
|
||||||
|
|
||||||
|
|
||||||
self.jwt_db_actions.create_token(RefreshTokensCreate.model_dump(token_record))
|
await self.jwt_db_actions.create_token(RefreshTokensCreate.model_dump(token_record))
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
|
||||||
def refresh_token(self, refresh_token:str, request:Request)->tuple[str, str]:
|
async def refresh_token(self, refresh_token:str, request:Request)->tuple[str, str]:
|
||||||
|
|
||||||
'''decode old refresh token'''
|
'''decode old refresh token'''
|
||||||
old_refresh_token=self.jwt_service.jwt_decode(refresh_token)
|
old_refresh_token= await self.jwt_service.jwt_decode(refresh_token)
|
||||||
sub=old_refresh_token.get("sub")
|
sub=old_refresh_token.get("sub")
|
||||||
|
|
||||||
if (old_jti:=old_refresh_token.get("jti")) is None:
|
if (old_jti:=old_refresh_token.get("jti")) is None:
|
||||||
@@ -118,7 +119,7 @@ class CurrentUserService:
|
|||||||
raise self.error.credentials_error(detail="Jwt token type is incorrect")
|
raise self.error.credentials_error(detail="Jwt token type is incorrect")
|
||||||
|
|
||||||
|
|
||||||
old_record=self.jwt_db_actions.get_token_by_id(old_jti)
|
old_record=await self.jwt_db_actions.get_token_by_id(old_jti)
|
||||||
if old_record is None:
|
if old_record is None:
|
||||||
raise self.error.not_found_error(detail="Token not found")
|
raise self.error.not_found_error(detail="Token not found")
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ class CurrentUserService:
|
|||||||
raise self.error.credentials_error(detail="Token expired")
|
raise self.error.credentials_error(detail="Token expired")
|
||||||
|
|
||||||
'''user check'''
|
'''user check'''
|
||||||
user = self.crud_db_actions.get_user_by_id(sub)
|
user = await self.crud_db_actions.get_user_by_id(sub)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise self.error.not_found_error(detail="User not found")
|
raise self.error.not_found_error(detail="User not found")
|
||||||
if user.status is False:
|
if user.status is False:
|
||||||
@@ -139,8 +140,8 @@ class CurrentUserService:
|
|||||||
|
|
||||||
|
|
||||||
'''create new refresh token if all the checks are successful'''
|
'''create new refresh token if all the checks are successful'''
|
||||||
new_refresh_token, new_jti=self.jwt_service.create_refresh_token({"sub":str(sub)})
|
new_refresh_token, new_jti= await self.jwt_service.create_refresh_token({"sub":str(sub)})
|
||||||
new_access_token=self.create_access_token(user_id=sub)
|
new_access_token=await self.create_access_token(user_id=sub)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
new_jti=UUID(new_jti)
|
new_jti=UUID(new_jti)
|
||||||
@@ -149,9 +150,9 @@ class CurrentUserService:
|
|||||||
|
|
||||||
|
|
||||||
'''create database record with the new token'''
|
'''create database record with the new token'''
|
||||||
new_token_record=self._token_record_create(jti=new_jti, user_id=sub, token=new_refresh_token, request=request)
|
new_token_record=await self._token_record_create(jti=new_jti, user_id=sub, token=new_refresh_token, request=request)
|
||||||
|
|
||||||
success = self.jwt_db_actions.create_and_update_token(RefreshTokensCreate.model_dump(new_token_record), old_jti, new_jti)
|
success = await self.jwt_db_actions.create_and_update_token(RefreshTokensCreate.model_dump(new_token_record), old_jti, new_jti)
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
raise self.error.not_found_error(detail="Token not found")
|
raise self.error.not_found_error(detail="Token not found")
|
||||||
@@ -160,10 +161,10 @@ class CurrentUserService:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def logout(self, refresh_token:str)->bool:
|
async def logout(self, refresh_token:str)->bool:
|
||||||
|
|
||||||
'''decode current refresh token'''
|
'''decode current refresh token'''
|
||||||
payload=self.jwt_service.jwt_decode(refresh_token)
|
payload=await self.jwt_service.jwt_decode(refresh_token)
|
||||||
|
|
||||||
if (jti:=payload.get("jti")) is None:
|
if (jti:=payload.get("jti")) is None:
|
||||||
raise self.error.credentials_error(detail="Jwt token is incorrect")
|
raise self.error.credentials_error(detail="Jwt token is incorrect")
|
||||||
@@ -174,23 +175,23 @@ class CurrentUserService:
|
|||||||
raise self.error.credentials_error(detail="Jwt token is incorrect") from e
|
raise self.error.credentials_error(detail="Jwt token is incorrect") from e
|
||||||
|
|
||||||
'''logout by assigning revoked flag'''
|
'''logout by assigning revoked flag'''
|
||||||
if self.jwt_db_actions.logout(jti):
|
if await self.jwt_db_actions.logout(jti):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
raise self.error.not_found_error(detail="Refresh Token Not Found")
|
raise self.error.not_found_error(detail="Refresh Token Not Found")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def login(self, form_data_email:str, form_data_password:str, request:Request)->tuple[str, str]:
|
async def login(self, form_data_email:str, form_data_password:str, request:Request)->tuple[str, str]:
|
||||||
'''revoke all the old refresh tokens'''
|
'''revoke all the old refresh tokens'''
|
||||||
user = self._check(form_data_email, form_data_password)
|
user = await self._check(form_data_email, form_data_password)
|
||||||
self.jwt_db_actions.revoke_all(user_id=user.id)
|
await self.jwt_db_actions.revoke_all(user_id=user.id)
|
||||||
|
|
||||||
'''create access and refresh tokens'''
|
'''create access and refresh tokens'''
|
||||||
access_token=self.create_access_token(user_id=user.id)
|
access_token=await self.create_access_token(user_id=user.id)
|
||||||
refresh_token=self.create_refresh_token(user_id=user.id,request=request)
|
refresh_token=await self.create_refresh_token(user_id=user.id,request=request)
|
||||||
|
|
||||||
return (access_token, refresh_token)
|
return (access_token, refresh_token)
|
||||||
|
|
||||||
def auth_service()->CurrentUserService:
|
async def auth_service()->CurrentUserService:
|
||||||
return CurrentUserService()
|
return CurrentUserService()
|
||||||
@@ -31,27 +31,27 @@ class JwtService:
|
|||||||
|
|
||||||
self.error=Errors()
|
self.error=Errors()
|
||||||
|
|
||||||
def _validate_sub(self,data:dict)->None:
|
async def _validate_sub(self,data:dict)->None:
|
||||||
if not (data.get("sub")) or data.get("sub") == "":
|
if not (data.get("sub")) or data.get("sub") == "":
|
||||||
raise self.error.credentials_error(detail="Jwt token is incorrect")
|
raise self.error.credentials_error(detail="Jwt token is incorrect")
|
||||||
|
|
||||||
def create_access_token(self, data:dict)->str:
|
async def create_access_token(self, data:dict)->str:
|
||||||
|
|
||||||
user_info=data.copy()
|
user_info=data.copy()
|
||||||
|
|
||||||
self._validate_sub(user_info)
|
await self._validate_sub(user_info)
|
||||||
|
|
||||||
user_info.update({"exp": datetime.now(UTC)+timedelta(minutes=env_settings.ACCESS_TOKEN_EXPIRE_MINUTES),
|
user_info.update({"exp": datetime.now(UTC)+timedelta(minutes=env_settings.ACCESS_TOKEN_EXPIRE_MINUTES),
|
||||||
"token_type":"access"})
|
"token_type":"access"})
|
||||||
return jwt.encode(user_info, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
return jwt.encode(user_info, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||||
|
|
||||||
|
|
||||||
def create_refresh_token(self, data:dict)->tuple[str, str]:
|
async def create_refresh_token(self, data:dict)->tuple[str, str]:
|
||||||
|
|
||||||
user_info=data.copy()
|
user_info=data.copy()
|
||||||
jti=str(uuid4())
|
jti=str(uuid4())
|
||||||
|
|
||||||
self._validate_sub(user_info)
|
await self._validate_sub(user_info)
|
||||||
|
|
||||||
user_info.update({"exp":datetime.now(UTC)+timedelta(days=env_settings.REFRESH_TOKEN_EXPIRE_DAYS),
|
user_info.update({"exp":datetime.now(UTC)+timedelta(days=env_settings.REFRESH_TOKEN_EXPIRE_DAYS),
|
||||||
"token_type":"refresh",
|
"token_type":"refresh",
|
||||||
@@ -62,7 +62,7 @@ class JwtService:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def jwt_decode(self, token:str)->dict:
|
async def jwt_decode(self, token:str)->dict:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payload=jwt.decode(token, env_settings.SECRET_KEY, algorithms=[env_settings.ALGORITHM], options={"require_exp": True} )
|
payload=jwt.decode(token, env_settings.SECRET_KEY, algorithms=[env_settings.ALGORITHM], options={"require_exp": True} )
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ class CrudService:
|
|||||||
self.errors=Errors()
|
self.errors=Errors()
|
||||||
self.crud_db_actions=UsersCrudActions()
|
self.crud_db_actions=UsersCrudActions()
|
||||||
|
|
||||||
def get_user_by_email(self, email:str)->UserOut:
|
async def get_user_by_email(self, email:str)->UserOut:
|
||||||
user_entity=self.crud_db_actions.get_user_by_email(email)
|
user_entity=await self.crud_db_actions.get_user_by_email(email)
|
||||||
if not user_entity:
|
if not user_entity:
|
||||||
raise self.errors.not_found_error(detail="User wasn't found")
|
raise self.errors.not_found_error(detail="User wasn't found")
|
||||||
return UserOut.model_validate(user_entity)
|
return UserOut.model_validate(user_entity)
|
||||||
|
|
||||||
crud_service=CrudService()
|
async def crud_service()->CrudService:
|
||||||
|
return CrudService()
|
||||||
@@ -11,7 +11,7 @@ oauth2_schema=OAuth2PasswordBearer(tokenUrl="/protected/token", refreshUrl="/pro
|
|||||||
@router.post("/token")
|
@router.post("/token")
|
||||||
async def get_access_token(request: Request,response:Response,auth:CurrentUserService=Depends(auth_service), form_data:OAuth2PasswordRequestForm=Depends())->dict: # noqa: B008
|
async def get_access_token(request: Request,response:Response,auth:CurrentUserService=Depends(auth_service), form_data:OAuth2PasswordRequestForm=Depends())->dict: # noqa: B008
|
||||||
|
|
||||||
access_token, refresh_token=auth.login(form_data_email=form_data.username, form_data_password=form_data.password, request=request)
|
access_token, refresh_token=await auth.login(form_data_email=form_data.username, form_data_password=form_data.password, request=request)
|
||||||
|
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
key="refresh_token",
|
key="refresh_token",
|
||||||
@@ -27,7 +27,7 @@ async def get_access_token(request: Request,response:Response,auth:CurrentUserSe
|
|||||||
@router.post("/refresh")
|
@router.post("/refresh")
|
||||||
async def get_refresh_token(request:Request,response:Response, refresh_token: str = Cookie(), auth:CurrentUserService=Depends(auth_service))->dict: # noqa: B008
|
async def get_refresh_token(request:Request,response:Response, refresh_token: str = Cookie(), auth:CurrentUserService=Depends(auth_service))->dict: # noqa: B008
|
||||||
|
|
||||||
access_token, refresh_token= auth.refresh_token(refresh_token=refresh_token,request=request)
|
access_token, refresh_token= await auth.refresh_token(refresh_token=refresh_token,request=request)
|
||||||
|
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
key="refresh_token",
|
key="refresh_token",
|
||||||
@@ -42,13 +42,13 @@ async def get_refresh_token(request:Request,response:Response, refresh_token: st
|
|||||||
|
|
||||||
|
|
||||||
async def get_current_user(token:str = Depends(oauth2_schema), auth:CurrentUserService=Depends(auth_service)) -> UserOut: # noqa: B008
|
async def get_current_user(token:str = Depends(oauth2_schema), auth:CurrentUserService=Depends(auth_service)) -> UserOut: # noqa: B008
|
||||||
return UserOut.model_validate(auth.get_current_user(token))
|
return UserOut.model_validate(await auth.get_current_user(token))
|
||||||
|
|
||||||
|
|
||||||
@router.get("/logout")
|
@router.get("/logout")
|
||||||
async def logout(response:Response,refresh_token: str = Cookie(),auth:CurrentUserService=Depends(auth_service),current_user:UserOut=Depends(get_current_user))->bool: # noqa: B008
|
async def logout(response:Response,refresh_token: str = Cookie(),auth:CurrentUserService=Depends(auth_service),current_user:UserOut=Depends(get_current_user))->bool: # noqa: B008
|
||||||
response.delete_cookie("refresh_token")
|
response.delete_cookie("refresh_token")
|
||||||
return auth.logout(refresh_token)
|
return await auth.logout(refresh_token)
|
||||||
|
|
||||||
@router.get("")
|
@router.get("")
|
||||||
async def protected(current_user:UserOut=Depends(get_current_user))->dict: # noqa: B008
|
async def protected(current_user:UserOut=Depends(get_current_user))->dict: # noqa: B008
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from src.models.pydantic_models.model import UserOut
|
from src.models.pydantic_models.model import UserOut
|
||||||
from src.service.users_crud.users_crud import crud_service
|
from src.service.users_crud.users_crud import CrudService, crud_service
|
||||||
from src.web.protected_routes.auth_routes import get_current_user
|
from src.web.protected_routes.auth_routes import get_current_user
|
||||||
|
|
||||||
router=APIRouter(prefix="/user")
|
router=APIRouter(prefix="/user")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/get_by_email")
|
@router.get("/get_by_email")
|
||||||
async def get_current_user_by_email(email:str, current_user=Depends(get_current_user))->UserOut: # noqa: B008
|
async def get_current_user_by_email(email:str, crud:CrudService=Depends(crud_service), current_user=Depends(get_current_user))->UserOut: # noqa: B008
|
||||||
return crud_service.get_user_by_email(email)
|
return await crud.get_user_by_email(email)
|
||||||
+5
-5
@@ -1,14 +1,14 @@
|
|||||||
import pytest
|
import pytest_asyncio
|
||||||
|
|
||||||
from src.service.auth.jwt import HashService, JwtService
|
from src.service.auth.jwt import HashService, JwtService
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest_asyncio.fixture
|
||||||
def jwt_service()->JwtService:
|
async def jwt_service()->JwtService:
|
||||||
jwt_service=JwtService()
|
jwt_service=JwtService()
|
||||||
return jwt_service
|
return jwt_service
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest_asyncio.fixture
|
||||||
def hash_service()->HashService:
|
async def hash_service()->HashService:
|
||||||
hash_service=HashService()
|
hash_service=HashService()
|
||||||
return hash_service
|
return hash_service
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
import pytest
|
import pytest_asyncio
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
|
|
||||||
from src.service.auth.auth import CurrentUserService
|
from src.service.auth.auth import CurrentUserService
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest_asyncio.fixture
|
||||||
def current_user_service()->CurrentUserService:
|
async def current_user_service()->CurrentUserService:
|
||||||
current_user_service=CurrentUserService()
|
current_user_service=CurrentUserService()
|
||||||
return current_user_service
|
return current_user_service
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest_asyncio.fixture
|
||||||
def requests(mocker):
|
async def requests(mocker):
|
||||||
fake_request = mocker.MagicMock(spec=Request)
|
fake_request = mocker.MagicMock(spec=Request)
|
||||||
fake_request.headers = {"user-agent": "pytest-agent", "x-forwarded-for":"127.0.0.1"}
|
fake_request.headers = {"user-agent": "pytest-agent", "x-forwarded-for":"127.0.0.1"}
|
||||||
return fake_request
|
return fake_request
|
||||||
@@ -11,7 +11,9 @@ from pydantic import ValidationError
|
|||||||
from src.models.configs_read.env import env_settings
|
from src.models.configs_read.env import env_settings
|
||||||
from src.service.auth.auth import CurrentUserService
|
from src.service.auth.auth import CurrentUserService
|
||||||
from src.service.auth.jwt import HashService, JwtService
|
from src.service.auth.jwt import HashService, JwtService
|
||||||
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
|
current_user_service=CurrentUserService()
|
||||||
|
|
||||||
@pytest.mark.integra
|
@pytest.mark.integra
|
||||||
class TestAuth:
|
class TestAuth:
|
||||||
@@ -19,19 +21,19 @@ class TestAuth:
|
|||||||
@pytest.mark.parametrize("user_data",[
|
@pytest.mark.parametrize("user_data",[
|
||||||
pytest.param(SimpleNamespace(first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True), id="correct_data")
|
pytest.param(SimpleNamespace(first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True), id="correct_data")
|
||||||
])
|
])
|
||||||
def test_get_current_user_positive(self,current_user_service:CurrentUserService, jwt_service:JwtService, monkeypatch, user_data:SimpleNamespace)->None:
|
async def test_get_current_user_positive(self,current_user_service:CurrentUserService, jwt_service:JwtService, monkeypatch, user_data:SimpleNamespace)->None:
|
||||||
|
|
||||||
with allure.step("create token"):
|
with allure.step("create token"):
|
||||||
|
|
||||||
token=jwt_service.create_access_token({"sub":str(uuid4())})
|
token=await jwt_service.create_access_token({"sub":str(uuid4())})
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", lambda user:user_data)
|
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", AsyncMock(return_value=user_data))
|
||||||
|
|
||||||
with allure.step("test get_current_user_with_fake_token"):
|
with allure.step("test get_current_user_with_fake_token"):
|
||||||
|
|
||||||
test_result= current_user_service.get_current_user(token)
|
test_result= await current_user_service.get_current_user(token)
|
||||||
|
|
||||||
assert test_result.first_name==user_data.first_name
|
assert test_result.first_name==user_data.first_name
|
||||||
assert test_result.last_name==user_data.last_name
|
assert test_result.last_name==user_data.last_name
|
||||||
@@ -46,37 +48,37 @@ class TestAuth:
|
|||||||
pytest.param(SimpleNamespace(first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True),1234, HTTPException, id="wrong_id"),
|
pytest.param(SimpleNamespace(first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True),1234, HTTPException, id="wrong_id"),
|
||||||
pytest.param(SimpleNamespace(status=True),uuid4(), ValidationError,id="empty_model_data")
|
pytest.param(SimpleNamespace(status=True),uuid4(), ValidationError,id="empty_model_data")
|
||||||
])
|
])
|
||||||
def test_get_current_user_negative(self,current_user_service:CurrentUserService, jwt_service:JwtService, monkeypatch, user_data:SimpleNamespace, expected_exception, uuid)->None:
|
async def test_get_current_user_negative(self,current_user_service:CurrentUserService, jwt_service:JwtService, monkeypatch, user_data:SimpleNamespace, expected_exception, uuid)->None:
|
||||||
|
|
||||||
with allure.step("create token"):
|
with allure.step("create token"):
|
||||||
|
|
||||||
token=jwt_service.create_access_token({"sub":str(uuid)})
|
token=await jwt_service.create_access_token({"sub":str(uuid)})
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", lambda user:user_data)
|
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", AsyncMock(return_value=user_data))
|
||||||
|
|
||||||
with allure.step("test get_current_user_with_fake_token"), pytest.raises(expected_exception):
|
with allure.step("test get_current_user_with_fake_token"), pytest.raises(expected_exception):
|
||||||
|
|
||||||
current_user_service.get_current_user(token)
|
await current_user_service.get_current_user(token)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("user_data, form_data_email,form_data_password",[
|
@pytest.mark.parametrize("user_data, form_data_email,form_data_password",[
|
||||||
pytest.param(SimpleNamespace(id=uuid4(),hashed_password="1234", first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True), "d@d.d", "1234", id="correct_data"),
|
pytest.param(SimpleNamespace(id=uuid4(),hashed_password="1234", first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True), "d@d.d", "1234", id="correct_data"),
|
||||||
])
|
])
|
||||||
def test_login_positive(self, jwt_service:JwtService,current_user_service:CurrentUserService, monkeypatch, user_data:SimpleNamespace, hash_service:HashService, form_data_email:str, form_data_password:str, requests)->None:
|
async def test_login_positive(self, jwt_service:JwtService,current_user_service:CurrentUserService, monkeypatch, user_data:SimpleNamespace, hash_service:HashService, form_data_email:str, form_data_password:str, requests)->None:
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
user_data.hashed_password=hash_service.plain_to_hash(user_data.hashed_password)
|
user_data.hashed_password=hash_service.plain_to_hash(user_data.hashed_password)
|
||||||
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_email", lambda user:user_data)
|
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_email", AsyncMock(return_value=user_data))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", lambda user_id: True)
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", AsyncMock(return_value=True))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "create_token", lambda token: True )
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "create_token", AsyncMock(return_value=True))
|
||||||
|
|
||||||
fake_request = requests
|
fake_request = requests
|
||||||
|
|
||||||
with allure.step("test login_with_fake_data"):
|
with allure.step("test login_with_fake_data"):
|
||||||
access, refresh=current_user_service.login(form_data_email, form_data_password,fake_request)
|
access, refresh=await current_user_service.login(form_data_email, form_data_password,fake_request)
|
||||||
parts_a=access.split(".")
|
parts_a=access.split(".")
|
||||||
parts_b=refresh.split(".")
|
parts_b=refresh.split(".")
|
||||||
assert isinstance(access, str)
|
assert isinstance(access, str)
|
||||||
@@ -90,36 +92,36 @@ class TestAuth:
|
|||||||
pytest.param(SimpleNamespace(id=uuid4(),hashed_password="1234", first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=False), "d@d.d", "1234",HTTPException, id="false_status"),
|
pytest.param(SimpleNamespace(id=uuid4(),hashed_password="1234", first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=False), "d@d.d", "1234",HTTPException, id="false_status"),
|
||||||
pytest.param(SimpleNamespace(id=1234,hashed_password="1234", first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True), "d@d.d", "1234",ValidationError, id="wrong_id"),
|
pytest.param(SimpleNamespace(id=1234,hashed_password="1234", first_name="test",last_name="test",middle_name="test",email="d@d.d",direct_permissions=[],group=[],status=True), "d@d.d", "1234",ValidationError, id="wrong_id"),
|
||||||
])
|
])
|
||||||
def test_login_negative(self, current_user_service:CurrentUserService, user_data:SimpleNamespace, jwt_service:JwtService, monkeypatch, requests, hash_service:HashService, form_data_email:str, form_data_password:str, expected_exception):
|
async def test_login_negative(self, current_user_service:CurrentUserService, user_data:SimpleNamespace, jwt_service:JwtService, monkeypatch, requests, hash_service:HashService, form_data_email:str, form_data_password:str, expected_exception):
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
user_data.hashed_password=hash_service.plain_to_hash(user_data.hashed_password)
|
user_data.hashed_password=hash_service.plain_to_hash(user_data.hashed_password)
|
||||||
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_email", lambda user:user_data)
|
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_email", AsyncMock(return_value=user_data))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", lambda user_id: True)
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", AsyncMock(return_value=True))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "create_token", lambda token: True )
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "create_token", AsyncMock(return_value=True))
|
||||||
|
|
||||||
fake_request = requests
|
fake_request = requests
|
||||||
|
|
||||||
with allure.step("test login_with_fake_data"), pytest.raises(expected_exception):
|
with allure.step("test login_with_fake_data"), pytest.raises(expected_exception):
|
||||||
|
|
||||||
current_user_service.login(form_data_email, form_data_password,fake_request)
|
await current_user_service.login(form_data_email, form_data_password,fake_request)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_logout_positive(self, jwt_service:JwtService, monkeypatch, current_user_service:CurrentUserService)->None:
|
async def test_logout_positive(self, jwt_service:JwtService, monkeypatch, current_user_service:CurrentUserService)->None:
|
||||||
|
|
||||||
with allure.step("create fake refresh token"):
|
with allure.step("create fake refresh token"):
|
||||||
|
|
||||||
token=jwt_service.create_refresh_token({"sub":str(uuid4())})
|
token=await jwt_service.create_refresh_token({"sub":str(uuid4())})
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "logout", lambda jti: True )
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "logout", AsyncMock(return_value=True))
|
||||||
|
|
||||||
with allure.step("test logout with fake data"):
|
with allure.step("test logout with fake data"):
|
||||||
|
|
||||||
status=current_user_service.logout(token[0])
|
status=await current_user_service.logout(token[0])
|
||||||
assert status is True
|
assert status is True
|
||||||
|
|
||||||
@pytest.mark.parametrize("jti,db_result, expected_exception",[
|
@pytest.mark.parametrize("jti,db_result, expected_exception",[
|
||||||
@@ -127,13 +129,13 @@ class TestAuth:
|
|||||||
pytest.param(1234, True, HTTPException, id="jti_int"),
|
pytest.param(1234, True, HTTPException, id="jti_int"),
|
||||||
pytest.param(str(uuid4()), False, HTTPException, id="db_result_none"),
|
pytest.param(str(uuid4()), False, HTTPException, id="db_result_none"),
|
||||||
])
|
])
|
||||||
def test_logout_negative(self, jwt_service:JwtService, monkeypatch, current_user_service:CurrentUserService, expected_exception, jti, db_result)->None:
|
async def test_logout_negative(self, jwt_service:JwtService, monkeypatch, current_user_service:CurrentUserService, expected_exception, jti, db_result)->None:
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "logout", lambda jti: db_result )
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "logout", AsyncMock(return_value=db_result) )
|
||||||
|
|
||||||
def fake_create_refresh_token(data:dict)->str:
|
async def fake_create_refresh_token(data:dict)->str:
|
||||||
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||||
|
|
||||||
monkeypatch.setattr(jwt_service, "create_refresh_token", fake_create_refresh_token)
|
monkeypatch.setattr(jwt_service, "create_refresh_token", fake_create_refresh_token)
|
||||||
@@ -141,39 +143,39 @@ class TestAuth:
|
|||||||
|
|
||||||
with allure.step("create fake refresh token"):
|
with allure.step("create fake refresh token"):
|
||||||
|
|
||||||
token=fake_create_refresh_token({"sub":str(uuid4()), "jti":jti, "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)})
|
token=await fake_create_refresh_token({"sub":str(uuid4()), "jti":jti, "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)})
|
||||||
|
|
||||||
with allure.step("test logout with fake data"), pytest.raises(expected_exception):
|
with allure.step("test logout with fake data"), pytest.raises(expected_exception):
|
||||||
|
|
||||||
current_user_service.logout(token)
|
await current_user_service.logout(token)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("db_result_token, user_data_result_db", [
|
@pytest.mark.parametrize("db_result_token, user_data_result_db", [
|
||||||
pytest.param(SimpleNamespace(is_revoked=False, expires_at=datetime.now(UTC)+timedelta(days=15)),SimpleNamespace(status=True), id="correct_data")
|
pytest.param(SimpleNamespace(is_revoked=False, expires_at=datetime.now(UTC)+timedelta(days=15)),SimpleNamespace(status=True), id="correct_data")
|
||||||
])
|
])
|
||||||
def test_refresh_token_positive(self, monkeypatch, current_user_service:CurrentUserService, db_result_token, requests:Request, jwt_service:JwtService,user_data_result_db )->None:
|
async def test_refresh_token_positive(self, monkeypatch, current_user_service:CurrentUserService, db_result_token, requests:Request, jwt_service:JwtService,user_data_result_db )->None:
|
||||||
|
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
|
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions,"get_token_by_id", lambda jti: db_result_token)
|
monkeypatch.setattr(current_user_service.jwt_db_actions,"get_token_by_id", AsyncMock(return_value=db_result_token))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", lambda data:True)
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", AsyncMock(return_value=True))
|
||||||
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", lambda user:user_data_result_db)
|
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", AsyncMock(return_value=user_data_result_db))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions,"create_and_update_token", lambda data0, data1, data2: True)
|
monkeypatch.setattr(current_user_service.jwt_db_actions,"create_and_update_token", AsyncMock(return_value=True))
|
||||||
|
|
||||||
fake_request = requests
|
fake_request = requests
|
||||||
|
|
||||||
def fake_create_refresh_token(data:dict)->str:
|
async def fake_create_refresh_token(data:dict)->str:
|
||||||
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||||
|
|
||||||
monkeypatch.setattr(jwt_service, "create_refresh_token", fake_create_refresh_token)
|
monkeypatch.setattr(jwt_service, "create_refresh_token", fake_create_refresh_token)
|
||||||
|
|
||||||
with allure.step("create fake refresh token"):
|
with allure.step("create fake refresh token"):
|
||||||
|
|
||||||
token=fake_create_refresh_token({"sub":str(uuid4()), "jti":str(uuid4()), "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)})
|
token=await fake_create_refresh_token({"sub":str(uuid4()), "jti":str(uuid4()), "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)})
|
||||||
|
|
||||||
with allure.step("test refresh token with fake data"):
|
with allure.step("test refresh token with fake data"):
|
||||||
|
|
||||||
new_access_token, new_refresh_token = current_user_service.refresh_token(token, fake_request)
|
new_access_token, new_refresh_token = await current_user_service.refresh_token(token, fake_request)
|
||||||
parts_a=new_access_token.split(".")
|
parts_a=new_access_token.split(".")
|
||||||
parts_b=new_refresh_token.split(".")
|
parts_b=new_refresh_token.split(".")
|
||||||
assert isinstance(new_access_token, str)
|
assert isinstance(new_access_token, str)
|
||||||
@@ -192,22 +194,22 @@ class TestAuth:
|
|||||||
pytest.param(SimpleNamespace(is_revoked=False, user_id="123",expires_at=datetime.now(UTC)+timedelta(days=15)),None,True,{"sub":str(uuid4()), "jti":str(uuid4()), "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)}, HTTPException,id="user_missing"),
|
pytest.param(SimpleNamespace(is_revoked=False, user_id="123",expires_at=datetime.now(UTC)+timedelta(days=15)),None,True,{"sub":str(uuid4()), "jti":str(uuid4()), "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)}, HTTPException,id="user_missing"),
|
||||||
pytest.param(SimpleNamespace(is_revoked=False,user_id="123", expires_at=datetime.now(UTC)-timedelta(days=15)),SimpleNamespace(status=True),True,{"sub":str(uuid4()), "jti":str(uuid4()), "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)}, HTTPException,id="wrong_exp")
|
pytest.param(SimpleNamespace(is_revoked=False,user_id="123", expires_at=datetime.now(UTC)-timedelta(days=15)),SimpleNamespace(status=True),True,{"sub":str(uuid4()), "jti":str(uuid4()), "token_type":"refresh", "exp":datetime.now(UTC)+timedelta(days=45)}, HTTPException,id="wrong_exp")
|
||||||
])
|
])
|
||||||
def test_refresh_token_negative(self, monkeypatch, current_user_service:CurrentUserService, db_result_token, requests, jwt_service:JwtService,user_data_result_db, expected_exception, fake_token_data, update_result)->None:
|
async def test_refresh_token_negative(self, monkeypatch, current_user_service:CurrentUserService, db_result_token, requests, jwt_service:JwtService,user_data_result_db, expected_exception, fake_token_data, update_result)->None:
|
||||||
with allure.step("patching db call functions"):
|
with allure.step("patching db call functions"):
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions,"get_token_by_id", lambda jti: db_result_token)
|
monkeypatch.setattr(current_user_service.jwt_db_actions,"get_token_by_id", AsyncMock(return_value=db_result_token))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", lambda user_id:True)
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "revoke_all", AsyncMock(return_value=True))
|
||||||
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", lambda user:user_data_result_db)
|
monkeypatch.setattr(current_user_service.crud_db_actions, "get_user_by_id", AsyncMock(return_value=user_data_result_db))
|
||||||
monkeypatch.setattr(current_user_service.jwt_db_actions, "create_and_update_token", lambda old_jti, new_jti, new_token_record:update_result)
|
monkeypatch.setattr(current_user_service.jwt_db_actions, "create_and_update_token", AsyncMock(return_value=update_result))
|
||||||
|
|
||||||
fake_request = requests
|
fake_request = requests
|
||||||
|
|
||||||
def fake_create_refresh_token(data:dict)->str:
|
async def fake_create_refresh_token(data:dict)->str:
|
||||||
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||||
|
|
||||||
monkeypatch.setattr(jwt_service, "create_refresh_token", fake_create_refresh_token)
|
monkeypatch.setattr(jwt_service, "create_refresh_token", fake_create_refresh_token)
|
||||||
|
|
||||||
with allure.step("create fake refresh token"):
|
with allure.step("create fake refresh token"):
|
||||||
token=fake_create_refresh_token(fake_token_data)
|
token=await fake_create_refresh_token(fake_token_data)
|
||||||
|
|
||||||
with allure.step("test refresh token with fake data"), pytest.raises(expected_exception):
|
with allure.step("test refresh token with fake data"), pytest.raises(expected_exception):
|
||||||
current_user_service.refresh_token(token, fake_request)
|
await current_user_service.refresh_token(token, fake_request)
|
||||||
+24
-24
@@ -15,10 +15,10 @@ class TestJwt:
|
|||||||
@pytest.mark.parametrize("data", [
|
@pytest.mark.parametrize("data", [
|
||||||
pytest.param({"sub": "123"}, id="full_sub")
|
pytest.param({"sub": "123"}, id="full_sub")
|
||||||
])
|
])
|
||||||
def test_access_create_positive(self, jwt_service:JwtService, data:dict)->None:
|
async def test_access_create_positive(self, jwt_service:JwtService, data:dict)->None:
|
||||||
|
|
||||||
with allure.step("create correct access token"):
|
with allure.step("create correct access token"):
|
||||||
token = jwt_service.create_access_token(data)
|
token = await jwt_service.create_access_token(data)
|
||||||
parts=token.split(".")
|
parts=token.split(".")
|
||||||
assert isinstance(token, str)
|
assert isinstance(token, str)
|
||||||
assert len(parts)==3
|
assert len(parts)==3
|
||||||
@@ -30,19 +30,19 @@ class TestJwt:
|
|||||||
pytest.param({"sub":""},HTTPException, id="empty_value"),
|
pytest.param({"sub":""},HTTPException, id="empty_value"),
|
||||||
pytest.param({"":""},HTTPException, id="empty_key_value")
|
pytest.param({"":""},HTTPException, id="empty_key_value")
|
||||||
])
|
])
|
||||||
def test_access_create_negative(self, jwt_service:JwtService, data:dict, expected_exception)->None:
|
async def test_access_create_negative(self, jwt_service:JwtService, data:dict, expected_exception)->None:
|
||||||
with allure.step("create invalid access token"),pytest.raises(expected_exception):
|
with allure.step("create invalid access token"),pytest.raises(expected_exception):
|
||||||
jwt_service.create_access_token(data)
|
await jwt_service.create_access_token(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("data", [
|
@pytest.mark.parametrize("data", [
|
||||||
pytest.param({"sub": "123"}, id="full_sub")
|
pytest.param({"sub": "123"}, id="full_sub")
|
||||||
])
|
])
|
||||||
def test_refresh_create_positive(self, jwt_service:JwtService, data:dict)->None:
|
async def test_refresh_create_positive(self, jwt_service:JwtService, data:dict)->None:
|
||||||
|
|
||||||
with allure.step("create correct access token"):
|
with allure.step("create correct access token"):
|
||||||
token = jwt_service.create_refresh_token(data)
|
token = await jwt_service.create_refresh_token(data)
|
||||||
parts=token[0].split(".")
|
parts=token[0].split(".")
|
||||||
assert isinstance(token[0], str)
|
assert isinstance(token[0], str)
|
||||||
assert isinstance(token[1], str)
|
assert isinstance(token[1], str)
|
||||||
@@ -54,24 +54,24 @@ class TestJwt:
|
|||||||
pytest.param({"sub":""},HTTPException, id="empty_value"),
|
pytest.param({"sub":""},HTTPException, id="empty_value"),
|
||||||
pytest.param({"":""},HTTPException, id="empty_key_value")
|
pytest.param({"":""},HTTPException, id="empty_key_value")
|
||||||
])
|
])
|
||||||
def test_refresh_create_negative(self, jwt_service:JwtService, data, expected_exception)->None:
|
async def test_refresh_create_negative(self, jwt_service:JwtService, data, expected_exception)->None:
|
||||||
with allure.step("create invalid access token"), pytest.raises(expected_exception):
|
with allure.step("create invalid access token"), pytest.raises(expected_exception):
|
||||||
jwt_service.create_refresh_token(data)
|
await jwt_service.create_refresh_token(data)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("data", [
|
@pytest.mark.parametrize("data", [
|
||||||
pytest.param({"sub": "123", "exp":datetime.now(UTC)+timedelta(minutes=15), "token_type":"access"}, id="correct_data"),
|
pytest.param({"sub": "123", "exp":datetime.now(UTC)+timedelta(minutes=15), "token_type":"access"}, id="correct_data"),
|
||||||
])
|
])
|
||||||
def test_jwt_decode_positive(self, data:dict, monkeypatch, jwt_service:JwtService)->None:
|
async def test_jwt_decode_positive(self, data:dict, monkeypatch, jwt_service:JwtService)->None:
|
||||||
|
|
||||||
with allure.step("patch a create token function"):
|
with allure.step("patch a create token function"):
|
||||||
def fake_create_access_token(data:dict)->str:
|
async def fake_create_access_token(data:dict)->str:
|
||||||
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||||
monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token)
|
monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token)
|
||||||
|
|
||||||
with allure.step("create and decode correct token"):
|
with allure.step("create and decode correct token"):
|
||||||
fake_token = jwt_service.create_access_token(data)
|
fake_token = await jwt_service.create_access_token(data)
|
||||||
payload=jwt_service.jwt_decode(fake_token)
|
payload=await jwt_service.jwt_decode(fake_token)
|
||||||
assert payload.get("sub")
|
assert payload.get("sub")
|
||||||
assert payload.get("exp")
|
assert payload.get("exp")
|
||||||
assert payload.get("token_type")
|
assert payload.get("token_type")
|
||||||
@@ -83,15 +83,15 @@ class TestJwt:
|
|||||||
pytest.param({}, HTTPException, id="empty_data"),
|
pytest.param({}, HTTPException, id="empty_data"),
|
||||||
pytest.param("", AttributeError, id="not_dict_data")
|
pytest.param("", AttributeError, id="not_dict_data")
|
||||||
])
|
])
|
||||||
def test_jwt_decode_invalid(self,jwt_service:JwtService, expected_exception, data, monkeypatch)->None:
|
async def test_jwt_decode_invalid(self,jwt_service:JwtService, expected_exception, data, monkeypatch)->None:
|
||||||
with allure.step("patch a create token function"):
|
with allure.step("patch a create token function"):
|
||||||
def fake_create_access_token(data:dict)->str:
|
async def fake_create_access_token(data:dict)->str:
|
||||||
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
return jwt.encode(data, env_settings.SECRET_KEY, env_settings.ALGORITHM)
|
||||||
monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token)
|
monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token)
|
||||||
|
|
||||||
with allure.step("create and decode invalid token"), pytest.raises(expected_exception):
|
with allure.step("create and decode invalid token"), pytest.raises(expected_exception):
|
||||||
fake_token=jwt_service.create_access_token(data)
|
fake_token=await jwt_service.create_access_token(data)
|
||||||
jwt_service.jwt_decode(fake_token)
|
await jwt_service.jwt_decode(fake_token)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("time, key, algorithm", [
|
@pytest.mark.parametrize("time, key, algorithm", [
|
||||||
@@ -99,23 +99,23 @@ class TestJwt:
|
|||||||
pytest.param(-15, "correct_key", "HS256", id="wrong_time"),
|
pytest.param(-15, "correct_key", "HS256", id="wrong_time"),
|
||||||
pytest.param(15, "correct_key", "HS512", id="wrong_algorithm"),
|
pytest.param(15, "correct_key", "HS512", id="wrong_algorithm"),
|
||||||
])
|
])
|
||||||
def test_jwt_decode_wrong_env(self, monkeypatch, time:int, key:str, algorithm:str, jwt_service)->None:
|
async def test_jwt_decode_wrong_env(self, monkeypatch, time:int, key:str, algorithm:str, jwt_service)->None:
|
||||||
|
|
||||||
with allure.step("patch a create token function"):
|
with allure.step("patch a create token function"):
|
||||||
def fake_create_access_token(data:dict, key:str, algorithm:str)->str:
|
async def fake_create_access_token(data:dict, key:str, algorithm:str)->str:
|
||||||
data.update({"exp":datetime.now(UTC)+timedelta(minutes=time)})
|
data.update({"exp":datetime.now(UTC)+timedelta(minutes=time)})
|
||||||
return jwt.encode(data, key, algorithm)
|
return jwt.encode(data, key, algorithm)
|
||||||
monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token)
|
monkeypatch.setattr(jwt_service, "create_access_token", fake_create_access_token)
|
||||||
|
|
||||||
with allure.step("create and decode token with wrong data inside"), pytest.raises(HTTPException):
|
with allure.step("create and decode token with wrong data inside"), pytest.raises(HTTPException):
|
||||||
fake_token=jwt_service.create_access_token({"sub": "123", "token_type":"access"}, key, algorithm)
|
fake_token=await jwt_service.create_access_token({"sub": "123", "token_type":"access"}, key, algorithm)
|
||||||
jwt_service.jwt_decode(fake_token)
|
await jwt_service.jwt_decode(fake_token)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("password",[
|
@pytest.mark.parametrize("password",[
|
||||||
pytest.param("plain_password", id="correct_plain_password")
|
pytest.param("plain_password", id="correct_plain_password")
|
||||||
])
|
])
|
||||||
def test_hash_and_veryfy_positive(self, password:str, hash_service:HashService)->None:
|
async def test_hash_and_veryfy_positive(self, password:str, hash_service:HashService)->None:
|
||||||
|
|
||||||
with allure.step("encode password"):
|
with allure.step("encode password"):
|
||||||
encoded_password=hash_service.plain_to_hash(password)
|
encoded_password=hash_service.plain_to_hash(password)
|
||||||
@@ -127,7 +127,7 @@ class TestJwt:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_verify_wrong_password(self, hash_service:HashService)->None:
|
async def test_verify_wrong_password(self, hash_service:HashService)->None:
|
||||||
|
|
||||||
with allure.step("encode password"):
|
with allure.step("encode password"):
|
||||||
encoded_password=hash_service.plain_to_hash("plain_password")
|
encoded_password=hash_service.plain_to_hash("plain_password")
|
||||||
@@ -136,9 +136,9 @@ class TestJwt:
|
|||||||
assert hash_service.verify_password("wrong_password", encoded_password) is False
|
assert hash_service.verify_password("wrong_password", encoded_password) is False
|
||||||
|
|
||||||
|
|
||||||
def test_token_to_hash_determistic(self, hash_service:HashService)->None:
|
async def test_token_to_hash_determistic(self, hash_service:HashService)->None:
|
||||||
assert hash_service.token_to_hash("abc")==hash_service.token_to_hash("abc")
|
assert hash_service.token_to_hash("abc")==hash_service.token_to_hash("abc")
|
||||||
|
|
||||||
def test_token_to_hash_different_input(self, hash_service:HashService)->None:
|
async def test_token_to_hash_different_input(self, hash_service:HashService)->None:
|
||||||
assert hash_service.token_to_hash("abc")!=hash_service.token_to_hash("xyz")
|
assert hash_service.token_to_hash("abc")!=hash_service.token_to_hash("xyz")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user