merge with dev

This commit is contained in:
knst-kotov 2021-07-13 12:20:59 +03:00
commit af0211721c
21 changed files with 405 additions and 501 deletions

2
.gitignore vendored
View File

@ -129,3 +129,5 @@ dmypy.json
.pyre/ .pyre/
.idea .idea
temp.* temp.*
*.sqlite3

View File

@ -1,9 +1,12 @@
FROM python:3.9 FROM python:3.9
WORKDIR /home/ruicore/auth RUN pip3 install pipenv
COPY . /home/ruicore/auth WORKDIR /usr/src/app
RUN pip3 install --upgrade pip && pip3 install -r requirements.txt COPY Pipfile ./
COPY Pipfile.lock ./
LABEL ruicore="hrui835@gmail.com" version="v.0.0.1" RUN set -ex && pipenv install --deploy --system
COPY . .

View File

@ -1,19 +0,0 @@
up-pip:
pip install --upgrade pip
freeze:
pip freeze>requirements.txt
install-pkg:
pip install -r requirements.txt
uninstall-pkg:
pip freeze | xargs pip uninstall -y
server-up:
docker-compose up -d --remove-orphans
docker-compose ps
server-down:
docker-compose down
docker-compose ps

19
Pipfile Normal file
View File

@ -0,0 +1,19 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
aioredis = "*"
ariadne = "*"
starlette = "*"
uvicorn = "*"
pydantic = "*"
passlib = "*"
PyJWT = "*"
SQLAlchemy = "*"
[dev-packages]
[requires]
python_version = "3.9"

283
Pipfile.lock generated Normal file
View File

@ -0,0 +1,283 @@
{
"_meta": {
"hash": {
"sha256": "94d9a9de7e56cb5c5781a85d19fd688e64f5cbab46e8d12d194e58ba8d246612"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"aioredis": {
"hashes": [
"sha256:15f8af30b044c771aee6787e5ec24694c048184c7b9e54c3b60c750a4b93273a",
"sha256:b61808d7e97b7cd5a92ed574937a079c9387fdadd22bfbfa7ad2fd319ecc26e3"
],
"index": "pypi",
"version": "==1.3.1"
},
"ariadne": {
"hashes": [
"sha256:56bc3609a0512920f06e9312f8ea6db3c8e4a7cd77f31fbed388f5dba6d589c0",
"sha256:e00abd7eb5869b59a638f1e3a7743445bf387236048cf1b0eb9d7c506dcd37c5"
],
"index": "pypi",
"version": "==0.13.0"
},
"asgiref": {
"hashes": [
"sha256:05914d0fa65a21711e732adc6572edad6c8da5f1435c3f0c060689ced5e85195",
"sha256:d36fa91dd90e3aa3c81a6bd426ccc8fb20bd3d22b0cf14a12800289e9c3e2563"
],
"markers": "python_version >= '3.6'",
"version": "==3.4.0"
},
"async-timeout": {
"hashes": [
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
],
"markers": "python_full_version >= '3.5.3'",
"version": "==3.0.1"
},
"click": {
"hashes": [
"sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a",
"sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"
],
"markers": "python_version >= '3.6'",
"version": "==8.0.1"
},
"graphql-core": {
"hashes": [
"sha256:91d96ef0e86665777bb7115d3bbb6b0326f43dc7dbcdd60da5486a27a50cfb11",
"sha256:a755635d1d364a17e8d270347000722351aaa03f1ab7d280878aae82fc68b1f3"
],
"markers": "python_version >= '3.6' and python_version < '4'",
"version": "==3.1.5"
},
"greenlet": {
"hashes": [
"sha256:03f28a5ea20201e70ab70518d151116ce939b412961c33827519ce620957d44c",
"sha256:06d7ac89e6094a0a8f8dc46aa61898e9e1aec79b0f8b47b2400dd51a44dbc832",
"sha256:06ecb43b04480e6bafc45cb1b4b67c785e183ce12c079473359e04a709333b08",
"sha256:096cb0217d1505826ba3d723e8981096f2622cde1eb91af9ed89a17c10aa1f3e",
"sha256:0c557c809eeee215b87e8a7cbfb2d783fb5598a78342c29ade561440abae7d22",
"sha256:0de64d419b1cb1bfd4ea544bedea4b535ef3ae1e150b0f2609da14bbf48a4a5f",
"sha256:14927b15c953f8f2d2a8dffa224aa78d7759ef95284d4c39e1745cf36e8cdd2c",
"sha256:16183fa53bc1a037c38d75fdc59d6208181fa28024a12a7f64bb0884434c91ea",
"sha256:206295d270f702bc27dbdbd7651e8ebe42d319139e0d90217b2074309a200da8",
"sha256:22002259e5b7828b05600a762579fa2f8b33373ad95a0ee57b4d6109d0e589ad",
"sha256:2325123ff3a8ecc10ca76f062445efef13b6cf5a23389e2df3c02a4a527b89bc",
"sha256:258f9612aba0d06785143ee1cbf2d7361801c95489c0bd10c69d163ec5254a16",
"sha256:3096286a6072553b5dbd5efbefc22297e9d06a05ac14ba017233fedaed7584a8",
"sha256:3d13da093d44dee7535b91049e44dd2b5540c2a0e15df168404d3dd2626e0ec5",
"sha256:408071b64e52192869129a205e5b463abda36eff0cebb19d6e63369440e4dc99",
"sha256:598bcfd841e0b1d88e32e6a5ea48348a2c726461b05ff057c1b8692be9443c6e",
"sha256:5d928e2e3c3906e0a29b43dc26d9b3d6e36921eee276786c4e7ad9ff5665c78a",
"sha256:5f75e7f237428755d00e7460239a2482fa7e3970db56c8935bd60da3f0733e56",
"sha256:60848099b76467ef09b62b0f4512e7e6f0a2c977357a036de602b653667f5f4c",
"sha256:6b1d08f2e7f2048d77343279c4d4faa7aef168b3e36039cba1917fffb781a8ed",
"sha256:70bd1bb271e9429e2793902dfd194b653221904a07cbf207c3139e2672d17959",
"sha256:76ed710b4e953fc31c663b079d317c18f40235ba2e3d55f70ff80794f7b57922",
"sha256:7920e3eccd26b7f4c661b746002f5ec5f0928076bd738d38d894bb359ce51927",
"sha256:7db68f15486d412b8e2cfcd584bf3b3a000911d25779d081cbbae76d71bd1a7e",
"sha256:8833e27949ea32d27f7e96930fa29404dd4f2feb13cce483daf52e8842ec246a",
"sha256:944fbdd540712d5377a8795c840a97ff71e7f3221d3fddc98769a15a87b36131",
"sha256:9a6b035aa2c5fcf3dbbf0e3a8a5bc75286fc2d4e6f9cfa738788b433ec894919",
"sha256:9bdcff4b9051fb1aa4bba4fceff6a5f770c6be436408efd99b76fc827f2a9319",
"sha256:a9017ff5fc2522e45562882ff481128631bf35da444775bc2776ac5c61d8bcae",
"sha256:aa4230234d02e6f32f189fd40b59d5a968fe77e80f59c9c933384fe8ba535535",
"sha256:ad80bb338cf9f8129c049837a42a43451fc7c8b57ad56f8e6d32e7697b115505",
"sha256:adb94a28225005890d4cf73648b5131e885c7b4b17bc762779f061844aabcc11",
"sha256:b3090631fecdf7e983d183d0fad7ea72cfb12fa9212461a9b708ff7907ffff47",
"sha256:b33b51ab057f8a20b497ffafdb1e79256db0c03ef4f5e3d52e7497200e11f821",
"sha256:b97c9a144bbeec7039cca44df117efcbeed7209543f5695201cacf05ba3b5857",
"sha256:be13a18cec649ebaab835dff269e914679ef329204704869f2f167b2c163a9da",
"sha256:be9768e56f92d1d7cd94185bab5856f3c5589a50d221c166cc2ad5eb134bd1dc",
"sha256:c1580087ab493c6b43e66f2bdd165d9e3c1e86ef83f6c2c44a29f2869d2c5bd5",
"sha256:c35872b2916ab5a240d52a94314c963476c989814ba9b519bc842e5b61b464bb",
"sha256:c70c7dd733a4c56838d1f1781e769081a25fade879510c5b5f0df76956abfa05",
"sha256:c767458511a59f6f597bfb0032a1c82a52c29ae228c2c0a6865cfeaeaac4c5f5",
"sha256:c87df8ae3f01ffb4483c796fe1b15232ce2b219f0b18126948616224d3f658ee",
"sha256:ca1c4a569232c063615f9e70ff9a1e2fee8c66a6fb5caf0f5e8b21a396deec3e",
"sha256:cc407b68e0a874e7ece60f6639df46309376882152345508be94da608cc0b831",
"sha256:da862b8f7de577bc421323714f63276acb2f759ab8c5e33335509f0b89e06b8f",
"sha256:dfe7eac0d253915116ed0cd160a15a88981a1d194c1ef151e862a5c7d2f853d3",
"sha256:ed1377feed808c9c1139bdb6a61bcbf030c236dd288d6fca71ac26906ab03ba6",
"sha256:f42ad188466d946f1b3afc0a9e1a266ac8926461ee0786c06baac6bd71f8a6f3",
"sha256:f92731609d6625e1cc26ff5757db4d32b6b810d2a3363b0ff94ff573e5901f6f"
],
"markers": "python_version >= '3'",
"version": "==1.1.0"
},
"h11": {
"hashes": [
"sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6",
"sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"
],
"markers": "python_version >= '3.6'",
"version": "==0.12.0"
},
"hiredis": {
"hashes": [
"sha256:04026461eae67fdefa1949b7332e488224eac9e8f2b5c58c98b54d29af22093e",
"sha256:04927a4c651a0e9ec11c68e4427d917e44ff101f761cd3b5bc76f86aaa431d27",
"sha256:07bbf9bdcb82239f319b1f09e8ef4bdfaec50ed7d7ea51a56438f39193271163",
"sha256:09004096e953d7ebd508cded79f6b21e05dff5d7361771f59269425108e703bc",
"sha256:0adea425b764a08270820531ec2218d0508f8ae15a448568109ffcae050fee26",
"sha256:0b39ec237459922c6544d071cdcf92cbb5bc6685a30e7c6d985d8a3e3a75326e",
"sha256:0d5109337e1db373a892fdcf78eb145ffb6bbd66bb51989ec36117b9f7f9b579",
"sha256:0f41827028901814c709e744060843c77e78a3aca1e0d6875d2562372fcb405a",
"sha256:11d119507bb54e81f375e638225a2c057dda748f2b1deef05c2b1a5d42686048",
"sha256:1233e303645f468e399ec906b6b48ab7cd8391aae2d08daadbb5cad6ace4bd87",
"sha256:139705ce59d94eef2ceae9fd2ad58710b02aee91e7fa0ccb485665ca0ecbec63",
"sha256:1f03d4dadd595f7a69a75709bc81902673fa31964c75f93af74feac2f134cc54",
"sha256:240ce6dc19835971f38caf94b5738092cb1e641f8150a9ef9251b7825506cb05",
"sha256:294a6697dfa41a8cba4c365dd3715abc54d29a86a40ec6405d677ca853307cfb",
"sha256:3d55e36715ff06cdc0ab62f9591607c4324297b6b6ce5b58cb9928b3defe30ea",
"sha256:3dddf681284fe16d047d3ad37415b2e9ccdc6c8986c8062dbe51ab9a358b50a5",
"sha256:3f5f7e3a4ab824e3de1e1700f05ad76ee465f5f11f5db61c4b297ec29e692b2e",
"sha256:508999bec4422e646b05c95c598b64bdbef1edf0d2b715450a078ba21b385bcc",
"sha256:5d2a48c80cf5a338d58aae3c16872f4d452345e18350143b3bf7216d33ba7b99",
"sha256:5dc7a94bb11096bc4bffd41a3c4f2b958257085c01522aa81140c68b8bf1630a",
"sha256:65d653df249a2f95673976e4e9dd7ce10de61cfc6e64fa7eeaa6891a9559c581",
"sha256:7492af15f71f75ee93d2a618ca53fea8be85e7b625e323315169977fae752426",
"sha256:7f0055f1809b911ab347a25d786deff5e10e9cf083c3c3fd2dd04e8612e8d9db",
"sha256:807b3096205c7cec861c8803a6738e33ed86c9aae76cac0e19454245a6bbbc0a",
"sha256:81d6d8e39695f2c37954d1011c0480ef7cf444d4e3ae24bc5e89ee5de360139a",
"sha256:87c7c10d186f1743a8fd6a971ab6525d60abd5d5d200f31e073cd5e94d7e7a9d",
"sha256:8b42c0dc927b8d7c0eb59f97e6e34408e53bc489f9f90e66e568f329bff3e443",
"sha256:a00514362df15af041cc06e97aebabf2895e0a7c42c83c21894be12b84402d79",
"sha256:a39efc3ade8c1fb27c097fd112baf09d7fd70b8cb10ef1de4da6efbe066d381d",
"sha256:a4ee8000454ad4486fb9f28b0cab7fa1cd796fc36d639882d0b34109b5b3aec9",
"sha256:a7928283143a401e72a4fad43ecc85b35c27ae699cf5d54d39e1e72d97460e1d",
"sha256:adf4dd19d8875ac147bf926c727215a0faf21490b22c053db464e0bf0deb0485",
"sha256:ae8427a5e9062ba66fc2c62fb19a72276cf12c780e8db2b0956ea909c48acff5",
"sha256:b4c8b0bc5841e578d5fb32a16e0c305359b987b850a06964bd5a62739d688048",
"sha256:b84f29971f0ad4adaee391c6364e6f780d5aae7e9226d41964b26b49376071d0",
"sha256:c39c46d9e44447181cd502a35aad2bb178dbf1b1f86cf4db639d7b9614f837c6",
"sha256:cb2126603091902767d96bcb74093bd8b14982f41809f85c9b96e519c7e1dc41",
"sha256:dcef843f8de4e2ff5e35e96ec2a4abbdf403bd0f732ead127bd27e51f38ac298",
"sha256:e3447d9e074abf0e3cd85aef8131e01ab93f9f0e86654db7ac8a3f73c63706ce",
"sha256:f52010e0a44e3d8530437e7da38d11fb822acfb0d5b12e9cd5ba655509937ca0",
"sha256:f8196f739092a78e4f6b1b2172679ed3343c39c61a3e9d722ce6fcf1dac2824a"
],
"markers": "python_version >= '3.6'",
"version": "==2.0.0"
},
"passlib": {
"hashes": [
"sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1",
"sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"
],
"index": "pypi",
"version": "==1.7.4"
},
"pydantic": {
"hashes": [
"sha256:021ea0e4133e8c824775a0cfe098677acf6fa5a3cbf9206a376eed3fc09302cd",
"sha256:05ddfd37c1720c392f4e0d43c484217b7521558302e7069ce8d318438d297739",
"sha256:05ef5246a7ffd2ce12a619cbb29f3307b7c4509307b1b49f456657b43529dc6f",
"sha256:10e5622224245941efc193ad1d159887872776df7a8fd592ed746aa25d071840",
"sha256:18b5ea242dd3e62dbf89b2b0ec9ba6c7b5abaf6af85b95a97b00279f65845a23",
"sha256:234a6c19f1c14e25e362cb05c68afb7f183eb931dd3cd4605eafff055ebbf287",
"sha256:244ad78eeb388a43b0c927e74d3af78008e944074b7d0f4f696ddd5b2af43c62",
"sha256:26464e57ccaafe72b7ad156fdaa4e9b9ef051f69e175dbbb463283000c05ab7b",
"sha256:41b542c0b3c42dc17da70554bc6f38cbc30d7066d2c2815a94499b5684582ecb",
"sha256:4a03cbbe743e9c7247ceae6f0d8898f7a64bb65800a45cbdc52d65e370570820",
"sha256:4be75bebf676a5f0f87937c6ddb061fa39cbea067240d98e298508c1bda6f3f3",
"sha256:54cd5121383f4a461ff7644c7ca20c0419d58052db70d8791eacbbe31528916b",
"sha256:589eb6cd6361e8ac341db97602eb7f354551482368a37f4fd086c0733548308e",
"sha256:8621559dcf5afacf0069ed194278f35c255dc1a1385c28b32dd6c110fd6531b3",
"sha256:8b223557f9510cf0bfd8b01316bf6dd281cf41826607eada99662f5e4963f316",
"sha256:99a9fc39470010c45c161a1dc584997f1feb13f689ecf645f59bb4ba623e586b",
"sha256:a7c6002203fe2c5a1b5cbb141bb85060cbff88c2d78eccbc72d97eb7022c43e4",
"sha256:a83db7205f60c6a86f2c44a61791d993dff4b73135df1973ecd9eed5ea0bda20",
"sha256:ac8eed4ca3bd3aadc58a13c2aa93cd8a884bcf21cb019f8cfecaae3b6ce3746e",
"sha256:e710876437bc07bd414ff453ac8ec63d219e7690128d925c6e82889d674bb505",
"sha256:ea5cb40a3b23b3265f6325727ddfc45141b08ed665458be8c6285e7b85bd73a1",
"sha256:fec866a0b59f372b7e776f2d7308511784dace622e0992a0b59ea3ccee0ae833"
],
"index": "pypi",
"version": "==1.8.2"
},
"pyjwt": {
"hashes": [
"sha256:934d73fbba91b0483d3857d1aff50e96b2a892384ee2c17417ed3203f173fca1",
"sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130"
],
"index": "pypi",
"version": "==2.1.0"
},
"sqlalchemy": {
"hashes": [
"sha256:0f6d467b67a7e5048f1408e8ea60d6caa70be5b386d0eebbf1185ab49cb8c7e4",
"sha256:238d78b3110b7f7cffdb70bf9cda686e0d876a849bc78ba4d471aa7b1461f306",
"sha256:25c0e0f3a7e8c19350086b3c0fe93c4def045cec053d749ef15da710c4d54c81",
"sha256:2f60a2e599cf5cf5e5327ce60f2918b897e42ad9f405d10dd01e37869c0ce6fc",
"sha256:38ee3a266afef2978e82824650457f70c5d74ec0cadec1b10fe5ed6f038eb5d0",
"sha256:46361690f1e1c5385994a4caeb6e8126063ff593a5c635700bbc1245de793c1e",
"sha256:46b99eab618cdc1c871ea707b7c52edc23cfea6c750740cd242ba62b5c84de7f",
"sha256:4a67371752fd86d1d03a3b82d4e75404608f6f4d579b9676124079a22a40c79f",
"sha256:525dd3c2205b11a2bc6d770bf1ec63bde0253fd754b4c19c399d27ddc9dad0d3",
"sha256:6c8406c3d8c1c7d15da454de15d77f7bb48d14ede5db994f74226c348cf1050e",
"sha256:6da83225a23eaf7b3f48f3d5f53c91b2cf00fbfa48b24a7a758160112dd3e123",
"sha256:7150e5b543b466f45f668b352f7abda27998cc8035f051d1b7e9524ca9eb2f5f",
"sha256:76fbc24311a3d039d6cd147d396719f606d96d1413f3816c028a48e29367f646",
"sha256:854a7b15750e617e16f8d65dbc004f065a7963544b253b923f16109557648777",
"sha256:86c079732328f1add097b0b8079cd532b5d28e207fac93e9d6ea5f487506deef",
"sha256:8d860c62e3f51623ccd528d8fac44580501df557d4b467cc5581587fcf057719",
"sha256:9675d5bc7e4f96a7bb2b54d14e9b269a5fb6e5d36ecc7d01f0f65bb9af3185f9",
"sha256:9841762d114018c49483c089fa2d47f7e612e57666323f615913d7d7f46e9606",
"sha256:9eb25bcf9161e2fcbe9eebe8e829719b2334e849183f0e496bf4b83722bcccfa",
"sha256:aad3234a41340e9cf6184e621694e2a7233ba3f8aef9b1e6de8cba431b45ebd2",
"sha256:b502b5e2f08500cc4b8d29bfc4f51d805adcbc00f8d149e98fda8aae85ddb644",
"sha256:b86d83fefc8a8c394f3490c37e1953bc16c311a3d1d1cf91518793bfb9847fb4",
"sha256:c0eb2cd3ad4967fcbdd9e066e8cd91fe2c23c671dbae9952f0b4d3d42832cc5f",
"sha256:e0d48456e1aa4f0537f9c9af7be71e1f0659ff68bc1cd538ebc785f6b007bd0d",
"sha256:eaee5dd378f6f0d7c3ec49aeeb26564d55ac0ad73b9b4688bf29e66deabddf73",
"sha256:f14acb0fd16d404fda9370f93aace682f284340c89c3442ac747c5466ac7e2b5",
"sha256:f6fc526bd70898489d02bf52c8f0632ab377592ae954d0c0a5bb38d618dddaa9",
"sha256:fcd84e4d46a86291495d131a7824ba38d2e8278bda9425c50661a04633174319",
"sha256:ff38ecf89c69a531a7326c2dae71982edfe2f805f3c016cdc5bfd1a04ebf80cb",
"sha256:ff8bebc7a9d297dff2003460e01db2c20c63818b45fb19170f388b1a72fe5a14"
],
"index": "pypi",
"version": "==1.4.20"
},
"starlette": {
"hashes": [
"sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed",
"sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa"
],
"index": "pypi",
"version": "==0.14.2"
},
"typing-extensions": {
"hashes": [
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
"sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342",
"sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"
],
"version": "==3.10.0.0"
},
"uvicorn": {
"hashes": [
"sha256:2a76bb359171a504b3d1c853409af3adbfa5cef374a4a59e5881945a97a93eae",
"sha256:45ad7dfaaa7d55cab4cd1e85e03f27e9d60bc067ddc59db52a2b0aeca8870292"
],
"index": "pypi",
"version": "==0.14.0"
}
},
"develop": {}
}

View File

@ -1,6 +1,33 @@
# discours-backend-next # discours-backend-next
start message service: Tech stack:
pip install ariadne
pip install uvicorn - pyjwt
uvicorn message_service:app - redis
- ariadne
- starlette
# Local development
Install redis and pipenv first
```
brew install redis pipenv
brew services start redis
```
Then run API server
```
pipenv shell
python3 server.py
```
# With Docker
TODO
# How to do an authorized request
Put the header 'Auth' with token from signInQuery in requests.

View File

@ -2,7 +2,7 @@ from functools import wraps
from typing import Optional, Tuple from typing import Optional, Tuple
from graphql import GraphQLResolveInfo from graphql import GraphQLResolveInfo
from jwt import DecodeError, ExpiredSignatureError import jwt
from starlette.authentication import AuthenticationBackend from starlette.authentication import AuthenticationBackend
from starlette.requests import HTTPConnection from starlette.requests import HTTPConnection
@ -29,14 +29,14 @@ class _Authenticate:
""" """
try: try:
payload = Token.decode(token) payload = Token.decode(token)
except ExpiredSignatureError: except exceptions.ExpiredSignatureError:
payload = Token.decode(token, verify_exp=False) payload = Token.decode(token, verify_exp=False)
if not await cls.exists(payload.user_id, token): if not await cls.exists(payload.user_id, token):
raise InvalidToken("Login expired, please login again") raise InvalidToken("Login expired, please login again")
if payload.device == "mobile": # noqa if payload.device == "mobile": # noqa
"we cat set mobile token to be valid forever" "we cat set mobile token to be valid forever"
return payload return payload
except DecodeError as e: except exceptions.JWTDecodeError as e:
raise InvalidToken("token format error") from e raise InvalidToken("token format error") from e
else: else:
if not await cls.exists(payload.user_id, token): if not await cls.exists(payload.user_id, token):

View File

@ -1,15 +0,0 @@
version: '3'
services:
redis:
image: redis:5.0.3-alpine
container_name: redis
ports:
- 6379:6379
server:
image: discoursio/api:v0.0.1
container_name: api
ports:
- 8002:24579
command: ["python", "server.py"]

View File

@ -14,7 +14,7 @@ from redis import redis
from resolvers.base import resolvers from resolvers.base import resolvers
import_module('resolvers') import_module('resolvers')
schema = make_executable_schema(load_schema_from_path("schema/"), resolvers) schema = make_executable_schema(load_schema_from_path("schema.graphql"), resolvers)
middleware = [ middleware = [
Middleware(AuthenticationMiddleware, backend=JWTAuthenticate()), Middleware(AuthenticationMiddleware, backend=JWTAuthenticate()),

View File

@ -1,235 +0,0 @@
from ariadne import QueryType
from ariadne import MutationType
from ariadne import SubscriptionType
from ariadne import ScalarType
from ariadne import make_executable_schema, load_schema_from_path
from ariadne.asgi import GraphQL
from datetime import datetime
from peewee import *
import asyncio
import auth_utils
type_defs = load_schema_from_path("schema.graphql")
db = SqliteDatabase('discours.db')
class User(Model):
username = CharField()
email = CharField()
createdAt = DateTimeField(default=datetime.now)
muted = BooleanField(default=False)
rating = IntegerField(default=0)
# roles =
updatedAt = DateTimeField(default=datetime.now)
username = CharField()
userpic = CharField(default="")
userpicId = CharField(default="")
wasOnlineAt = DateTimeField(default=datetime.now)
password = CharField()
class Meta:
database = db
class Message(Model):
author = ForeignKeyField(User)
body = CharField()
createdAt = DateTimeField(default=datetime.now)
replyTo = ForeignKeyField('self', null=True)
updatedAt = DateTimeField(default=datetime.now)
class Meta:
database = db
db.connect()
db.create_tables([User, Message])
#only_user = User.create(
# username = "admin",
# email = "knst.kotov@gmail.com",
# password = auth_utils.password_to_hash("12345")
#)
only_user = User.get(User.username == "admin")
all_messages = {}
for message in Message.select():
all_messages[message.id] = message
new_message_queue = asyncio.Queue()
updated_message_queue = asyncio.Queue()
deleted_message_queue = asyncio.Queue()
datetime_scalar = ScalarType("DateTime")
@datetime_scalar.serializer
def serialize_datetime(value):
return value.isoformat()
query = QueryType()
@query.field("getMessages")
def resolve_get_messages(_, info, count, page):
return all_messages.values()
mutation = MutationType()
@mutation.field("signIn")
def resolve_sign_in(_, info, email, password):
try:
user = User.get(User.email == email)
except DoesNotExist as err:
return {
"status" : False,
"error" : "invalid username or password"
}
if auth_utils.verify_password(password, user.password) :
return {
"status" : True,
"token" : auth_utils.jwt_encode(user)
}
return {
"status" : False,
"error" : "invalid username or password"
}
@mutation.field("createMessage")
def resolve_create_message(_, info, input):
request = info.context["request"]
try:
user_id = auth_utils.authorize(request)
user = User.get(User.id == user_id)
new_message = Message.create(
author = user,
body = input["body"],
replyTo = input.get("replyTo")
)
except Exception as err:
return {
"status" : False,
"message" : err
}
all_messages[new_message.id] = new_message
new_message_queue.put_nowait(new_message)
return {
"status" : True,
"message" : new_message
}
@mutation.field("updateMessage")
def resolve_update_message(_, info, input):
request = info.context["request"]
try:
user_id = auth_utils.authorize(request)
user = User.get(User.id == user_id)
except Exception as err:
return {
"status" : False,
"message" : err
}
message_id = input["id"]
body = input["body"]
if not message_id in all_messages:
return {
"status" : False,
"error" : "invalid message id"
}
updated_message = all_messages[message_id]
if updated_message.author != user:
return {
"status" : False,
"error" : "update this message denied"
}
updated_message.body = body
#updated_message.updatedAt = datetime.now
try:
updated_message.save()
except Exception as err:
return {
"status" : false,
"message" : err
}
updated_message_queue.put_nowait(updated_message)
return {
"status" : True,
"message" : updated_message
}
@mutation.field("deleteMessage")
def resolve_delete_message(_, info, messageId):
if not messageId in all_messages:
return {
"status" : False,
"error" : "invalid message id"
}
message = all_messages[messageId]
try:
message.delete_instance()
except Exception as err:
return {
"status" : false,
"message" : err
}
del all_messages[messageId]
deleted_message_queue.put_nowait(message)
return {
"status" : True
}
subscription = SubscriptionType()
@subscription.source("messageCreated")
async def new_message_generator(obj, info):
while True:
new_message = await new_message_queue.get()
yield new_message
@subscription.source("messageUpdated")
async def updated_message_generator(obj, info):
while True:
message = await updated_message_queue.get()
yield message
@subscription.source("messageDeleted")
async def deleted_message_generator(obj, info):
while True:
message = await deleted_message_queue.get()
yield new_message
@subscription.field("messageCreated")
@subscription.field("messageUpdated")
@subscription.field("messageDeleted")
def message_resolver(message, info):
return message
schema = make_executable_schema(type_defs, query, mutation, subscription, datetime_scalar)
app = GraphQL(schema, debug=True)
db.close()

View File

@ -3,6 +3,6 @@ from orm.user import User
from orm.message import Message from orm.message import Message
from orm.base import Base, engine from orm.base import Base, engine
__all__ = ["User", "Role", "Operation", "Permission"] __all__ = ["User", "Role", "Operation", "Permission", "Message"]
Base.metadata.create_all(engine) Base.metadata.create_all(engine)

View File

@ -1,29 +1,8 @@
aioredis==1.3.1 aioredis
appdirs==1.4.4 ariadne
ariadne==0.12.0 pyjwt
async-timeout==3.0.1 starlette
cffi==1.14.3 sqlalchemy
cfgv==3.2.0 uvicorn
click==7.1.2 pydantic
cryptography==3.2 passlib
distlib==0.3.1
filelock==3.0.12
graphql-core==3.0.5
h11==0.10.0
hiredis==1.1.0
identify==1.5.5
jwt==1.0.0
nodeenv==1.5.0
passlib==1.7.2
pre-commit==2.7.1
pycparser==2.20
pydantic==1.6.1
PyJWT==1.7.1
PyYAML==5.3.1
six==1.15.0
SQLAlchemy==1.3.19
starlette==0.13.8
toml==0.10.1
typing-extensions==3.7.4.3
uvicorn==0.12.1
virtualenv==20.0.33

View File

@ -1,4 +1,14 @@
from resolvers.auth import sign_in, sign_out, register from resolvers.auth import sign_in, sign_out, register
from resolvers.inbox import create_message from resolvers.inbox import create_message, delete_message, update_message, get_messages
__all__ = ["sign_in", "sign_out", "register"] __all__ = [
"sign_in",
"sign_out",
"register",
# TODO: "reset_password_code",
# TODO: "reset_password_confirm",
"create_message",
"delete_message",
"get_messages",
"update_messages"
]

View File

@ -1,24 +0,0 @@
type User{
id: ID!
name: String!
phone: String
age: Int
}
input CreateUserInput{
password: String!
name: String!
phone: String
age: Int
}
type Query{
user(id: ID!): User!
login(id: ID!,password: String!): String!
logout(id: ID!): Boolean!
}
type Mutation{
register(create: CraeteUserInput): User!
}

View File

@ -1,5 +1,22 @@
scalar DateTime scalar DateTime
input registerUserInput {
email: String!
username: String!
password: String!
}
type signInPayload {
status: Boolean!
error: String
token: String
}
type ResultPayload {
status: Boolean!
error: String
}
type Like { type Like {
author: Int! author: Int!
id: Int! id: Int!
@ -14,11 +31,6 @@ type createMessagePayload {
message: Message message: Message
} }
type deleteMessagePayload {
status: Boolean!
error: String
}
input MessageInput { input MessageInput {
body: String! body: String!
replyTo: Int replyTo: Int
@ -43,7 +55,7 @@ type Mutation {
# message # message
createMessage(input: MessageInput!): createMessagePayload! createMessage(input: MessageInput!): createMessagePayload!
updateMessage(input: updateMessageInput!): createMessagePayload! updateMessage(input: updateMessageInput!): createMessagePayload!
deleteMessage(messageId: Int!): deleteMessagePayload! deleteMessage(messageId: Int!): ResultPayload!
# auth # auth
confirmEmail(token: String!): Token! confirmEmail(token: String!): Token!
@ -53,7 +65,8 @@ type Mutation {
requestPasswordReset(email: String!): Boolean! requestPasswordReset(email: String!): Boolean!
resetPassword(password: String!, token: String!): Token! resetPassword(password: String!, token: String!): Token!
signIn(email: String!, password: String!): Token! signIn(email: String!, password: String!): Token!
signUp(email: String!, password: String!, username: String): User! # signUp(email: String!, password: String!, username: String): User!
registerUser(input: registerUserInput!): User!
# shout # shout
createShout(body: String!, replyTo: [Int], title: String, versionOf: [Int], visibleForRoles: [Int], visibleForUsers: [Int]): Message! createShout(body: String!, replyTo: [Int], title: String, versionOf: [Int], visibleForRoles: [Int], visibleForUsers: [Int]): Message!
@ -67,14 +80,21 @@ type Mutation {
} }
type Query { type Query {
# auth / user
signIn(id: Int!, password: String!): signInPayload!
signOut: ResultPayload!
getCurrentUser: User! getCurrentUser: User!
getMessages(count: Int = 100, page: Int = 1): [Message!]!
getOnline: [User!]!
getShoutRating(shout: Int): Int!
getTokens: [Token!]! getTokens: [Token!]!
isUsernameFree(username: String!): Boolean!
getOnline: [User!]!
getUserById(id: Int!): User! getUserById(id: Int!): User!
getUserRating(shout: Int): Int! getUserRating(shout: Int): Int!
isUsernameFree(username: String!): Boolean!
# messages
getMessages(count: Int = 100, page: Int = 1): [Message!]!
# shouts
getShoutRating(shout: Int): Int!
shoutsByAuthor(author: Int): [Shout]! shoutsByAuthor(author: Int): [Shout]!
shoutsByReplyTo(shout: Int): [Shout]! shoutsByReplyTo(shout: Int): [Shout]!
shoutsByTags(tags: [String]): [Shout]! shoutsByTags(tags: [String]): [Shout]!

View File

@ -1,62 +0,0 @@
scalar DateTime
type User {
createdAt: DateTime!
email: String
emailConfirmed: Boolean
id: Int!
muted: Boolean
rating: Int
updatedAt: DateTime!
username: String
userpic: String
userpicId: String
wasOnlineAt: DateTime
}
type Message {
author: Int!
body: String!
createdAt: DateTime!
id: Int!
replyTo: Int
updatedAt: DateTime!
visibleForUsers: [Int]
}
type createMessagePayload {
status: Boolean!
error: String
message: Message
}
type deleteMessagePayload {
status: Boolean!
error: String
}
input MessageInput {
body: String!
replyTo: Int
}
input updateMessageInput {
id: Int!
body: String!
}
type Query {
getMessages(count: Int = 100, page: Int = 1): [Message!]!
}
type Mutation {
createMessage(input: MessageInput!): createMessagePayload!
updateMessage(input: updateMessageInput!): createMessagePayload!
deleteMessage(messageId: Int!): deleteMessagePayload!
}
type Subscription {
messageCreated: Message!
messageUpdated: Message!
messageDeleted: Message!
}

View File

@ -1,37 +0,0 @@
type Role {
id: Int!
name: String!
}
type User {
createdAt: DateTime!
email: String
emailConfirmed: Boolean
id: Int!
muted: Boolean
rating: Int
roles: [Role!]!
updatedAt: DateTime!
username: String
userpic: String
userpicId: String
wasOnlineAt: DateTime
}
input registerUserInput {
email: String!
username: String!
password: String!
}
type signInPayload {
status: Boolean!
error: String
token: String
}
type signOutPayload {
status: Boolean!
error: String
}

View File

@ -1,23 +0,0 @@
scalar DateTime
type Query {
signIn(id: Int!, password: String!): signInPayload!
signOut: signOutPayload!
getMessages(count: Int = 100, page: Int = 1): [Message!]!
}
type Mutation {
registerUser(input: registerUserInput!): User!
createMessage(input: MessageInput!): createMessagePayload!
updateMessage(input: updateMessageInput!): createMessagePayload!
deleteMessage(id: Int!): deleteMessagePayload!
}
type Subscription {
messageCreated: Message!
messageUpdated: Message!
messageDeleted: Message!
}

View File

@ -1,31 +0,0 @@
type Message {
author: Int!
body: String!
createdAt: DateTime!
id: Int!
replyTo: Int
updatedAt: DateTime!
visibleForUsers: [Int]
}
type createMessagePayload {
status: Boolean!
error: String
message: Message
}
type deleteMessagePayload {
status: Boolean!
error: String
}
input MessageInput {
body: String!
replyTo: Int
}
input updateMessageInput {
id: Int!
body: String!
}

View File

@ -1,4 +1,9 @@
import uvicorn import uvicorn
from settings import PORT
if __name__ == '__main__': if __name__ == '__main__':
<<<<<<< HEAD
uvicorn.run("main:app", host="0.0.0.0", port=8081, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True) uvicorn.run("main:app", host="0.0.0.0", port=8081, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True)
=======
uvicorn.run("main:app", host="0.0.0.0", port=PORT, reload=True)
>>>>>>> remotes/origin/dev

View File

@ -1,5 +1,7 @@
from pathlib import Path from pathlib import Path
PORT = 24579
SQLITE_URI = Path(__file__).parent / "database.sqlite3" SQLITE_URI = Path(__file__).parent / "database.sqlite3"
JWT_ALGORITHM = "HS256" JWT_ALGORITHM = "HS256"
JWT_SECRET_KEY = "8f1bd7696ffb482d8486dfbc6e7d16dd-secret-key" JWT_SECRET_KEY = "8f1bd7696ffb482d8486dfbc6e7d16dd-secret-key"