diff --git a/.gitignore b/.gitignore index 73fb09c5..7cfc211a 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,5 @@ dmypy.json .pyre/ .idea temp.* + +*.sqlite3 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7d6f09ae..fb8de3e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ 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" \ No newline at end of file +RUN set -ex && pipenv install --deploy --system + +COPY . . \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index fafc7c12..00000000 --- a/Makefile +++ /dev/null @@ -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 diff --git a/Pipfile b/Pipfile new file mode 100644 index 00000000..c3c459b4 --- /dev/null +++ b/Pipfile @@ -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" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 00000000..a1a7eca6 --- /dev/null +++ b/Pipfile.lock @@ -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": {} +} diff --git a/README.md b/README.md index bdd1126e..c3bdad55 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,33 @@ # discours-backend-next -start message service: -pip install ariadne -pip install uvicorn -uvicorn message_service:app +Tech stack: + + - pyjwt + - redis + - ariadne + - starlette + +# Local development + +Install redis first, then start + +''' +brew install redis +brew services start redis +''' + +Then run API server + +''' +pip3 install -r requirements.txt +python3 server.py +''' + +# With Docker + +TODO + + +# How to do an authorized request + +Put the header 'Auth' with token from signInQuery in requests. \ No newline at end of file diff --git a/auth/authenticate.py b/auth/authenticate.py index 1eea1118..67ed3b41 100644 --- a/auth/authenticate.py +++ b/auth/authenticate.py @@ -2,7 +2,7 @@ from functools import wraps from typing import Optional, Tuple from graphql import GraphQLResolveInfo -from jwt import DecodeError, ExpiredSignatureError +import jwt from starlette.authentication import AuthenticationBackend from starlette.requests import HTTPConnection @@ -29,14 +29,14 @@ class _Authenticate: """ try: payload = Token.decode(token) - except ExpiredSignatureError: + except exceptions.ExpiredSignatureError: payload = Token.decode(token, verify_exp=False) if not await cls.exists(payload.user_id, token): raise InvalidToken("Login expired, please login again") if payload.device == "mobile": # noqa "we cat set mobile token to be valid forever" return payload - except DecodeError as e: + except exceptions.JWTDecodeError as e: raise InvalidToken("token format error") from e else: if not await cls.exists(payload.user_id, token): diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index bd7da9ee..00000000 --- a/docker-compose.yml +++ /dev/null @@ -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"] diff --git a/main.py b/main.py index 2b94f25e..b044f248 100644 --- a/main.py +++ b/main.py @@ -11,7 +11,7 @@ from redis import redis from resolvers.base import 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(AuthenticationMiddleware, backend=JWTAuthenticate())] diff --git a/message_service.py b/message_service.py deleted file mode 100644 index 5a1698f3..00000000 --- a/message_service.py +++ /dev/null @@ -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() diff --git a/requirements.txt b/requirements.txt index ef859210..be76a4e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,29 +1,8 @@ -aioredis==1.3.1 -appdirs==1.4.4 -ariadne==0.12.0 -async-timeout==3.0.1 -cffi==1.14.3 -cfgv==3.2.0 -click==7.1.2 -cryptography==3.2 -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 +aioredis +ariadne +pyjwt +starlette +sqlalchemy +uvicorn +pydantic +passlib \ No newline at end of file diff --git a/schema.auth.graphql b/schema.auth.graphql deleted file mode 100644 index e51641e0..00000000 --- a/schema.auth.graphql +++ /dev/null @@ -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! -} \ No newline at end of file diff --git a/schema.prototype.graphql b/schema.graphql similarity index 85% rename from schema.prototype.graphql rename to schema.graphql index 92f995de..0dc7093e 100644 --- a/schema.prototype.graphql +++ b/schema.graphql @@ -1,5 +1,22 @@ 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 { author: Int! id: Int! @@ -14,11 +31,6 @@ type createMessagePayload { message: Message } -type deleteMessagePayload { - status: Boolean! - error: String -} - input MessageInput { body: String! replyTo: Int @@ -43,7 +55,7 @@ type Mutation { # message createMessage(input: MessageInput!): createMessagePayload! updateMessage(input: updateMessageInput!): createMessagePayload! - deleteMessage(messageId: Int!): deleteMessagePayload! + deleteMessage(messageId: Int!): ResultPayload! # auth confirmEmail(token: String!): Token! @@ -53,7 +65,8 @@ type Mutation { requestPasswordReset(email: String!): Boolean! resetPassword(password: String!, token: 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 createShout(body: String!, replyTo: [Int], title: String, versionOf: [Int], visibleForRoles: [Int], visibleForUsers: [Int]): Message! @@ -67,14 +80,21 @@ type Mutation { } type Query { + # auth / user + signIn(id: Int!, password: String!): signInPayload! + signOut: ResultPayload! getCurrentUser: User! - getMessages(count: Int = 100, page: Int = 1): [Message!]! - getOnline: [User!]! - getShoutRating(shout: Int): Int! getTokens: [Token!]! + isUsernameFree(username: String!): Boolean! + getOnline: [User!]! getUserById(id: Int!): User! 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]! shoutsByReplyTo(shout: Int): [Shout]! shoutsByTags(tags: [String]): [Shout]! diff --git a/schema.messages.graphql b/schema.messages.graphql deleted file mode 100644 index 21d18c53..00000000 --- a/schema.messages.graphql +++ /dev/null @@ -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! -} diff --git a/schema/schema.auth.graphql b/schema/schema.auth.graphql deleted file mode 100644 index 0f3404ff..00000000 --- a/schema/schema.auth.graphql +++ /dev/null @@ -1,46 +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 -} - -type Query{ - signIn(id: Int!, password: String!): signInPayload! - signOut: signOutPayload! -} - -type Mutation{ - registerUser(input: registerUserInput!): User! -} diff --git a/schema/schema.common.graphql b/schema/schema.common.graphql deleted file mode 100644 index bada3b71..00000000 --- a/schema/schema.common.graphql +++ /dev/null @@ -1,2 +0,0 @@ - -scalar DateTime diff --git a/server.py b/server.py index c1a38b88..fcee596f 100644 --- a/server.py +++ b/server.py @@ -1,4 +1,5 @@ import uvicorn +from settings import PORT if __name__ == '__main__': - uvicorn.run("main:app", host="0.0.0.0", port=24579, reload=True) + uvicorn.run("main:app", host="0.0.0.0", port=PORT, reload=True) diff --git a/settings.py b/settings.py index be78aa0f..54eef00f 100644 --- a/settings.py +++ b/settings.py @@ -1,5 +1,7 @@ from pathlib import Path +PORT = 24579 + SQLITE_URI = Path(__file__).parent / "database.sqlite3" JWT_ALGORITHM = "HS256" JWT_SECRET_KEY = "8f1bd7696ffb482d8486dfbc6e7d16dd-secret-key"