From d304362684d388edfd57312e6efbfed1afa4eea0 Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Wed, 14 Jul 2021 14:45:31 +0000 Subject: [PATCH 01/11] auth fixes --- auth/authenticate.py | 7 +++---- auth/identity.py | 14 ++++++++++++-- auth/oauth.py | 2 +- resolvers/auth.py | 23 +++++++++++++++++------ schema.graphql | 9 +++++---- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/auth/authenticate.py b/auth/authenticate.py index 2637d302..60f9d6ef 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 -import jwt +from jwt import DecodeError, ExpiredSignatureError from starlette.authentication import AuthenticationBackend from starlette.requests import HTTPConnection @@ -29,14 +29,14 @@ class _Authenticate: """ try: payload = Token.decode(token) - except exceptions.ExpiredSignatureError: + except 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 exceptions.JWTDecodeError as e: + except DecodeError as e: raise InvalidToken("token format error") from e else: if not await cls.exists(payload.user_id, token): @@ -73,5 +73,4 @@ def login_required(func): if not auth.logged_in: raise OperationNotAllowed(auth.error_message or "Please login") return await func(parent, info, *args, **kwargs) - return wrap diff --git a/auth/identity.py b/auth/identity.py index 1eefe773..cfb4093a 100644 --- a/auth/identity.py +++ b/auth/identity.py @@ -4,6 +4,8 @@ from orm import User as OrmUser from orm.base import global_session from auth.validations import User +from sqlalchemy import or_ + class Identity: @staticmethod @@ -12,14 +14,22 @@ class Identity: if not user: raise ObjectNotExist("User does not exist") user = User(**user.dict()) + if user.password is None: + raise InvalidPassword("Wrong user password") if not Password.verify(password, user.password): raise InvalidPassword("Wrong user password") return user @staticmethod - def identity_oauth(oauth_id, input) -> User: - user = global_session.query(OrmUser).filter_by(oauth_id=oauth_id).first() + def identity_oauth(input) -> User: + user = global_session.query(OrmUser).filter( + or_(OrmUser.oauth_id == input["oauth_id"], OrmUser.email == input["email"]) + ).first() if not user: user = OrmUser.create(**input) + if not user.oauth_id: + user.oauth_id = input["oauth_id"] + global_session.commit() + user = User(**user.dict()) return user diff --git a/auth/oauth.py b/auth/oauth.py index 8fc6ade7..8bad3dbc 100644 --- a/auth/oauth.py +++ b/auth/oauth.py @@ -63,6 +63,6 @@ async def oauth_authorize(request): "email" : profile["email"], "username" : profile["name"] } - user = Identity.identity_oauth(oauth_id=oauth_id, input=user_input) + user = Identity.identity_oauth(user_input) token = await Authorize.authorize(user, device="pc", auto_delete=False) return PlainTextResponse(token) diff --git a/resolvers/auth.py b/resolvers/auth.py index cfc7f1a1..3745ddfe 100644 --- a/resolvers/auth.py +++ b/resolvers/auth.py @@ -19,13 +19,17 @@ async def register(*_, input: dict = None) -> User: @query.field("signIn") -async def sign_in(_, info: GraphQLResolveInfo, id: int, password: str): +async def sign_in(_, info: GraphQLResolveInfo, email: str, password: str): + orm_user = global_session.query(User).filter(User.email == email).first() + if orm_user is None: + return {"status" : False, "error" : "invalid email"} + try: device = info.context["request"].headers['device'] except KeyError: device = "pc" auto_delete = False if device == "mobile" else True - user = Identity.identity(user_id=id, password=password) + user = Identity.identity(user_id=orm_user.id, password=password) token = await Authorize.authorize(user, device=device, auto_delete=auto_delete) return {"status" : True, "token" : token} @@ -38,9 +42,16 @@ async def sign_out(_, info: GraphQLResolveInfo): return {"status" : status} -#@query.field("getUser") -#@login_required -async def get_user(*_, id: int): - return global_session.query(User).filter(User.id == id).first() +@query.field("getCurrentUser") +@login_required +async def get_user(_, info): + auth = info.context["request"].auth + user_id = auth.user_id + return global_session.query(User).filter(User.id == user_id).first() + +@query.field("isEmailFree") +async def is_email_free(_, info, email): + user = global_session.query(User).filter(User.email == email).first() + return user is None diff --git a/schema.graphql b/schema.graphql index 73e10313..dc562f4e 100644 --- a/schema.graphql +++ b/schema.graphql @@ -79,11 +79,12 @@ type Mutation { type Query { # auth / user - signIn(id: Int!, password: String!): signInPayload! + signIn(email: String!, password: String!): signInPayload! signOut: ResultPayload! - getCurrentUser: User! - getTokens: [Token!]! - isUsernameFree(username: String!): Boolean! + getCurrentUser: User! + + isEmailFree(email: String!): Boolean! + getOnline: [User!]! getUserById(id: Int!): User! getUserRating(shout: Int): Int! From 9648870f39f030251215f30c1f333141862595a3 Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Mon, 26 Jul 2021 07:05:08 +0000 Subject: [PATCH 02/11] prepare for deploy --- Dockerfile | 8 +- Pipfile | 41 +-- Pipfile.lock | 700 ++++++++++++++++++++++++++++++-------------------- auth/oauth.py | 14 +- create_crt.sh | 2 +- server.py | 8 +- settings.py | 13 +- 7 files changed, 471 insertions(+), 315 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1bb28e4a..72f5067f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,6 @@ -FROM python:3.9 +FROM python:3.8 + +EXPOSE 80 RUN pip3 install pipenv @@ -9,4 +11,6 @@ COPY Pipfile.lock ./ RUN set -ex && pipenv install --deploy --system -COPY . . \ No newline at end of file +COPY . . + +CMD ["python", "server.py"] diff --git a/Pipfile b/Pipfile index 8362e750..f1e49972 100644 --- a/Pipfile +++ b/Pipfile @@ -1,19 +1,22 @@ -[[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" +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +aioredis = "*" +ariadne = "*" +starlette = "*" +uvicorn = "*" +pydantic = "*" +passlib = "*" +PyJWT = "*" +SQLAlchemy = "*" +itsdangerous = "*" +authlib = "*" +httpx = "*" + +[dev-packages] + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock index 51cf8457..a309eb0a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,283 +1,417 @@ -{ - "_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": {} -} +{ + "_meta": { + "hash": { + "sha256": "6ca6b02d3e09088dc3222522eca7541395222607b1972f986791dcb3bf1259aa" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aioredis": { + "hashes": [ + "sha256:15f8af30b044c771aee6787e5ec24694c048184c7b9e54c3b60c750a4b93273a", + "sha256:b61808d7e97b7cd5a92ed574937a079c9387fdadd22bfbfa7ad2fd319ecc26e3" + ], + "index": "pypi", + "version": "==1.3.1" + }, + "anyio": { + "hashes": [ + "sha256:929a6852074397afe1d989002aa96d457e3e1e5441357c60d03e7eea0e65e1b0", + "sha256:ae57a67583e5ff8b4af47666ff5651c3732d45fd26c929253748e796af860374" + ], + "version": "==3.3.0" + }, + "ariadne": { + "hashes": [ + "sha256:56bc3609a0512920f06e9312f8ea6db3c8e4a7cd77f31fbed388f5dba6d589c0", + "sha256:e00abd7eb5869b59a638f1e3a7743445bf387236048cf1b0eb9d7c506dcd37c5" + ], + "index": "pypi", + "version": "==0.13.0" + }, + "asgiref": { + "hashes": [ + "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9", + "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214" + ], + "version": "==3.4.1" + }, + "async-timeout": { + "hashes": [ + "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", + "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" + ], + "version": "==3.0.1" + }, + "authlib": { + "hashes": [ + "sha256:37df3a2554bc6fe0da3cc6848c44fac2ae40634a7f8fc72543947f4330b26464", + "sha256:d9fe5edb59801b16583faa86f88d798d99d952979b9616d5c735b9170b41ae2c" + ], + "index": "pypi", + "version": "==0.15.4" + }, + "certifi": { + "hashes": [ + "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee", + "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8" + ], + "version": "==2021.5.30" + }, + "cffi": { + "hashes": [ + "sha256:06c54a68935738d206570b20da5ef2b6b6d92b38ef3ec45c5422c0ebaf338d4d", + "sha256:0c0591bee64e438883b0c92a7bed78f6290d40bf02e54c5bf0978eaf36061771", + "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872", + "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c", + "sha256:26bb2549b72708c833f5abe62b756176022a7b9a7f689b571e74c8478ead51dc", + "sha256:33791e8a2dc2953f28b8d8d300dde42dd929ac28f974c4b4c6272cb2955cb762", + "sha256:3c8d896becff2fa653dc4438b54a5a25a971d1f4110b32bd3068db3722c80202", + "sha256:4373612d59c404baeb7cbd788a18b2b2a8331abcc84c3ba40051fcd18b17a4d5", + "sha256:487d63e1454627c8e47dd230025780e91869cfba4c753a74fda196a1f6ad6548", + "sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a", + "sha256:4922cd707b25e623b902c86188aca466d3620892db76c0bdd7b99a3d5e61d35f", + "sha256:55af55e32ae468e9946f741a5d51f9896da6b9bf0bbdd326843fec05c730eb20", + "sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218", + "sha256:5d4b68e216fc65e9fe4f524c177b54964af043dde734807586cf5435af84045c", + "sha256:64fda793737bc4037521d4899be780534b9aea552eb673b9833b01f945904c2e", + "sha256:6d6169cb3c6c2ad50db5b868db6491a790300ade1ed5d1da29289d73bbe40b56", + "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224", + "sha256:80b06212075346b5546b0417b9f2bf467fea3bfe7352f781ffc05a8ab24ba14a", + "sha256:818014c754cd3dba7229c0f5884396264d51ffb87ec86e927ef0be140bfdb0d2", + "sha256:8eb687582ed7cd8c4bdbff3df6c0da443eb89c3c72e6e5dcdd9c81729712791a", + "sha256:99f27fefe34c37ba9875f224a8f36e31d744d8083e00f520f133cab79ad5e819", + "sha256:9f3e33c28cd39d1b655ed1ba7247133b6f7fc16fa16887b120c0c670e35ce346", + "sha256:a8661b2ce9694ca01c529bfa204dbb144b275a31685a075ce123f12331be790b", + "sha256:a9da7010cec5a12193d1af9872a00888f396aba3dc79186604a09ea3ee7c029e", + "sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534", + "sha256:b315d709717a99f4b27b59b021e6207c64620790ca3e0bde636a6c7f14618abb", + "sha256:ba6f2b3f452e150945d58f4badd92310449876c4c954836cfb1803bdd7b422f0", + "sha256:c33d18eb6e6bc36f09d793c0dc58b0211fccc6ae5149b808da4a62660678b156", + "sha256:c9a875ce9d7fe32887784274dd533c57909b7b1dcadcc128a2ac21331a9765dd", + "sha256:c9e005e9bd57bc987764c32a1bee4364c44fdc11a3cc20a40b93b444984f2b87", + "sha256:d2ad4d668a5c0645d281dcd17aff2be3212bc109b33814bbb15c4939f44181cc", + "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195", + "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33", + "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f", + "sha256:e9dc245e3ac69c92ee4c167fbdd7428ec1956d4e754223124991ef29eb57a09d", + "sha256:eb687a11f0a7a1839719edd80f41e459cc5366857ecbed383ff376c4e3cc6afd", + "sha256:eb9e2a346c5238a30a746893f23a9535e700f8192a68c07c0258e7ece6ff3728", + "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7", + "sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca", + "sha256:f0c5d1acbfca6ebdd6b1e3eded8d261affb6ddcf2186205518f1428b8569bb99", + "sha256:f10afb1004f102c7868ebfe91c28f4a712227fe4cb24974350ace1f90e1febbf", + "sha256:f174135f5609428cc6e1b9090f9268f5c8935fddb1b25ccb8255a2d50de6789e", + "sha256:f3ebe6e73c319340830a9b2825d32eb6d8475c1dac020b4f0aa774ee3b898d1c", + "sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5", + "sha256:fd4305f86f53dfd8cd3522269ed7fc34856a8ee3709a5e28b2836b2db9d4cd69" + ], + "version": "==1.14.6" + }, + "click": { + "hashes": [ + "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a", + "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6" + ], + "version": "==8.0.1" + }, + "cryptography": { + "hashes": [ + "sha256:0f1212a66329c80d68aeeb39b8a16d54ef57071bf22ff4e521657b27372e327d", + "sha256:1e056c28420c072c5e3cb36e2b23ee55e260cb04eee08f702e0edfec3fb51959", + "sha256:240f5c21aef0b73f40bb9f78d2caff73186700bf1bc6b94285699aff98cc16c6", + "sha256:26965837447f9c82f1855e0bc8bc4fb910240b6e0d16a664bb722df3b5b06873", + "sha256:37340614f8a5d2fb9aeea67fd159bfe4f5f4ed535b1090ce8ec428b2f15a11f2", + "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713", + "sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1", + "sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177", + "sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250", + "sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca", + "sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d", + "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9" + ], + "version": "==3.4.7" + }, + "graphql-core": { + "hashes": [ + "sha256:91d96ef0e86665777bb7115d3bbb6b0326f43dc7dbcdd60da5486a27a50cfb11", + "sha256:a755635d1d364a17e8d270347000722351aaa03f1ab7d280878aae82fc68b1f3" + ], + "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" + ], + "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" + ], + "version": "==2.0.0" + }, + "httpcore": { + "hashes": [ + "sha256:b0d16f0012ec88d8cc848f5a55f8a03158405f4bca02ee49bc4ca2c1fda49f3e", + "sha256:db4c0dcb8323494d01b8c6d812d80091a31e520033e7b0120883d6f52da649ff" + ], + "version": "==0.13.6" + }, + "httpx": { + "hashes": [ + "sha256:979afafecb7d22a1d10340bafb403cf2cb75aff214426ff206521fc79d26408c", + "sha256:9f99c15d33642d38bce8405df088c1c4cfd940284b4290cacbfb02e64f4877c6" + ], + "index": "pypi", + "version": "==0.18.2" + }, + "idna": { + "hashes": [ + "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", + "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3" + ], + "version": "==3.2" + }, + "itsdangerous": { + "hashes": [ + "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c", + "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" + ], + "index": "pypi", + "version": "==2.0.1" + }, + "passlib": { + "hashes": [ + "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1", + "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04" + ], + "index": "pypi", + "version": "==1.7.4" + }, + "pycparser": { + "hashes": [ + "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", + "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" + ], + "version": "==2.20" + }, + "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" + }, + "rfc3986": { + "hashes": [ + "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", + "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97" + ], + "version": "==1.5.0" + }, + "sniffio": { + "hashes": [ + "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663", + "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de" + ], + "version": "==1.2.0" + }, + "sqlalchemy": { + "hashes": [ + "sha256:09dbb4bc01a734ccddbf188deb2a69aede4b3c153a72b6d5c6900be7fb2945b1", + "sha256:12bac5fa1a6ea870bdccb96fe01610641dd44ebe001ed91ef7fcd980e9702db5", + "sha256:1fdae7d980a2fa617d119d0dc13ecb5c23cc63a8b04ffcb5298f2c59d86851e9", + "sha256:26daa429f039e29b1e523bf763bfab17490556b974c77b5ca7acb545b9230e9a", + "sha256:36a089dc604032d41343d86290ce85d4e6886012eea73faa88001260abf5ff81", + "sha256:39b5d36ab71f73c068cdcf70c38075511de73616e6c7fdd112d6268c2704d9f5", + "sha256:4014978de28163cd8027434916a92d0f5bb1a3a38dff5e8bf8bff4d9372a9117", + "sha256:44d23ea797a5e0be71bc5454b9ae99158ea0edc79e2393c6e9a2354de88329c0", + "sha256:488608953385d6c127d2dcbc4b11f8d7f2f30b89f6bd27c01b042253d985cc2f", + "sha256:5102b9face693e8b2db3b2539c7e1a5d9a5b4dc0d79967670626ffd2f710d6e6", + "sha256:5908ea6c652a050d768580d01219c98c071e71910ab8e7b42c02af4010608397", + "sha256:5d856cc50fd26fc8dd04892ed5a5a3d7eeb914fea2c2e484183e2d84c14926e0", + "sha256:68393d3fd31469845b6ba11f5b4209edbea0b58506be0e077aafbf9aa2e21e11", + "sha256:6a16c7c4452293da5143afa3056680db2d187b380b3ef4d470d4e29885720de3", + "sha256:756f5d2f5b92d27450167247fb574b09c4cd192a3f8c2e493b3e518a204ee543", + "sha256:891927a49b2363a4199763a9d436d97b0b42c65922a4ea09025600b81a00d17e", + "sha256:9bfe882d5a1bbde0245dca0bd48da0976bd6634cf2041d2fdf0417c5463e40e5", + "sha256:9fcbb4b4756b250ed19adc5e28c005b8ed56fdb5c21efa24c6822c0575b4964d", + "sha256:a00d9c6d3a8afe1d1681cd8a5266d2f0ed684b0b44bada2ca82403b9e8b25d39", + "sha256:a5e14cb0c0a4ac095395f24575a0e7ab5d1be27f5f9347f1762f21505e3ba9f1", + "sha256:b48148ceedfb55f764562e04c00539bb9ea72bf07820ca15a594a9a049ff6b0e", + "sha256:b7fb937c720847879c7402fe300cfdb2aeff22349fa4ea3651bca4e2d6555939", + "sha256:bc34a007e604091ca3a4a057525efc4cefd2b7fe970f44d20b9cfa109ab1bddb", + "sha256:c9373ef67a127799027091fa53449125351a8c943ddaa97bec4e99271dbb21f4", + "sha256:d09a760b0a045b4d799102ae7965b5491ccf102123f14b2a8cc6c01d1021a2d9", + "sha256:ec1be26cdccd60d180359a527d5980d959a26269a2c7b1b327a1eea0cab37ed8", + "sha256:eedd76f135461cf237534a6dc0d1e0f6bb88a1dc193678fab48a11d223462da5", + "sha256:f028ef6a1d828bc754852a022b2160e036202ac8658a6c7d34875aafd14a9a15", + "sha256:f814d80844969b0d22ea63663da4de5ca1c434cfbae226188901e5d368792c17", + "sha256:fd2102a8f8a659522719ed73865dff3d3cc76eb0833039dc473e0ad3041d04be" + ], + "index": "pypi", + "version": "==1.4.22" + }, + "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/auth/oauth.py b/auth/oauth.py index 8bad3dbc..20df1303 100644 --- a/auth/oauth.py +++ b/auth/oauth.py @@ -4,14 +4,14 @@ from starlette.responses import PlainTextResponse from auth.authorize import Authorize from auth.identity import Identity -from sensitive_settings import CLIENT_ID, CLIENT_SECRET +from settings import OAUTH_CLIENTS oauth = OAuth() oauth.register( name='facebook', - client_id=CLIENT_ID["FACEBOOK"], - client_secret=CLIENT_SECRET["FACEBOOK"], + client_id=OAUTH_CLIENTS["FACEBOOK"]["id"], + client_secret=OAUTH_CLIENTS["FACEBOOK"]["key"], access_token_url='https://graph.facebook.com/v11.0/oauth/access_token', access_token_params=None, authorize_url='https://www.facebook.com/v11.0/dialog/oauth', @@ -22,8 +22,8 @@ oauth.register( oauth.register( name='github', - client_id=CLIENT_ID["GITHUB"], - client_secret=CLIENT_SECRET["GITHUB"], + client_id=OAUTH_CLIENTS["GITHUB"]["id"], + client_secret=OAUTH_CLIENTS["GITHUB"]["key"], access_token_url='https://github.com/login/oauth/access_token', access_token_params=None, authorize_url='https://github.com/login/oauth/authorize', @@ -34,8 +34,8 @@ oauth.register( oauth.register( name='google', - client_id=CLIENT_ID["GOOGLE"], - client_secret=CLIENT_SECRET["GOOGLE"], + client_id=OAUTH_CLIENTS["GOOGLE"]["id"], + client_secret=OAUTH_CLIENTS["GOOGLE"]["key"], access_token_url='https://oauth2.googleapis.com/token', access_token_params=None, authorize_url='https://accounts.google.com/o/oauth2/v2/auth', diff --git a/create_crt.sh b/create_crt.sh index ee5b19a8..d36eec87 100644 --- a/create_crt.sh +++ b/create_crt.sh @@ -7,4 +7,4 @@ openssl req -newkey rsa:4096 \ -nodes \ -out discours.crt \ -keyout discours.key \ - -subj "/C=RU/ST=Moscow/L=Moscow/O=Discours/OU=Site/CN=10.0.0.187" + -subj "/C=RU/ST=Moscow/L=Moscow/O=Discours/OU=Site/CN=test-api.discours.io" diff --git a/server.py b/server.py index 969330cb..8ff87e58 100644 --- a/server.py +++ b/server.py @@ -1,5 +1,11 @@ import uvicorn from settings import PORT +import sys + if __name__ == '__main__': - uvicorn.run("main:app", host="0.0.0.0", port=PORT, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True) + dev_mode = len(sys.argv) > 1 and sys.argv[1] == "dev" + if dev_mode : + uvicorn.run("main:app", host="0.0.0.0", port=8080, ssl_keyfile="discours.key", ssl_certfile="discours.crt", reload=True) + else : + uvicorn.run("main:app", host="0.0.0.0", port=PORT) diff --git a/settings.py b/settings.py index 84bd4eaa..911f9ace 100644 --- a/settings.py +++ b/settings.py @@ -1,10 +1,19 @@ from pathlib import Path +from os import environ -PORT = 8081 +PORT = 80 SQLITE_URI = Path(__file__).parent / "database.sqlite3" JWT_ALGORITHM = "HS256" JWT_SECRET_KEY = "8f1bd7696ffb482d8486dfbc6e7d16dd-secret-key" JWT_LIFE_SPAN = 24 * 60 * 60 # seconds JWT_AUTH_HEADER = "Auth" -REDIS_URL = "redis://127.0.0.1" +REDIS_URL = environ.get("REDIS_URL") or "redis://127.0.0.1" + +OAUTH_PROVIDERS = ("GITHUB", "FACEBOOK", "GOOGLE") +OAUTH_CLIENTS = {} +for provider in OAUTH_PROVIDERS: + OAUTH_CLIENTS[provider] = { + "id" : environ.get(provider + "_OAUTH_ID"), + "key" : environ.get(provider + "_OAUTH_KEY") + } From a872ebdf31ca3b9b7667481ac01b087142ff6983 Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Mon, 26 Jul 2021 08:50:33 +0000 Subject: [PATCH 03/11] use postgresql --- Pipfile | 1 + Pipfile.lock | 17 ++++++++++++++++- auth/token.py | 2 +- orm/base.py | 4 ++-- settings.py | 2 +- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Pipfile b/Pipfile index f1e49972..649f7eb8 100644 --- a/Pipfile +++ b/Pipfile @@ -15,6 +15,7 @@ SQLAlchemy = "*" itsdangerous = "*" authlib = "*" httpx = "*" +psycopg2 = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index a309eb0a..a45eacdc 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "6ca6b02d3e09088dc3222522eca7541395222607b1972f986791dcb3bf1259aa" + "sha256": "0e2f744e18603585f1999ed3b99d09c11bd0cfff59618c506edb2dad1c91314e" }, "pipfile-spec": 6, "requires": { @@ -295,6 +295,21 @@ "index": "pypi", "version": "==1.7.4" }, + "psycopg2": { + "hashes": [ + "sha256:079d97fc22de90da1d370c90583659a9f9a6ee4007355f5825e5f1c70dffc1fa", + "sha256:2087013c159a73e09713294a44d0c8008204d06326006b7f652bef5ace66eebb", + "sha256:2c992196719fadda59f72d44603ee1a2fdcc67de097eea38d41c7ad9ad246e62", + "sha256:7640e1e4d72444ef012e275e7b53204d7fab341fb22bc76057ede22fe6860b25", + "sha256:7f91312f065df517187134cce8e395ab37f5b601a42446bdc0f0d51773621854", + "sha256:830c8e8dddab6b6716a4bf73a09910c7954a92f40cf1d1e702fb93c8a919cc56", + "sha256:89409d369f4882c47f7ea20c42c5046879ce22c1e4ea20ef3b00a4dfc0a7f188", + "sha256:bf35a25f1aaa8a3781195595577fcbb59934856ee46b4f252f56ad12b8043bcf", + "sha256:de5303a6f1d0a7a34b9d40e4d3bef684ccc44a49bbe3eb85e3c0bffb4a131b7c" + ], + "index": "pypi", + "version": "==2.9.1" + }, "pycparser": { "hashes": [ "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", diff --git a/auth/token.py b/auth/token.py index d3fa5715..74b9b38e 100644 --- a/auth/token.py +++ b/auth/token.py @@ -10,7 +10,7 @@ class Token: @staticmethod def encode(user: User, exp: datetime, device: str = "pc") -> str: payload = {"user_id": user.id, "device": device, "exp": exp, "iat": datetime.utcnow()} - return jwt.encode(payload, JWT_SECRET_KEY, JWT_ALGORITHM).decode("UTF-8") + return jwt.encode(payload, JWT_SECRET_KEY, JWT_ALGORITHM) @staticmethod def decode(token: str, verify_exp: bool = True) -> PayLoad: diff --git a/orm/base.py b/orm/base.py index cf5ec589..e3c89c6d 100644 --- a/orm/base.py +++ b/orm/base.py @@ -5,9 +5,9 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.sql.schema import Table -from settings import SQLITE_URI +from settings import DB_URI -engine = create_engine(f'sqlite:///{SQLITE_URI}', convert_unicode=True, echo=False) +engine = create_engine(DB_URI, convert_unicode=True, echo=False) Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) global_session = Session() diff --git a/settings.py b/settings.py index 911f9ace..1cb3a9a0 100644 --- a/settings.py +++ b/settings.py @@ -3,7 +3,7 @@ from os import environ PORT = 80 -SQLITE_URI = Path(__file__).parent / "database.sqlite3" +DB_URI = environ.get("DB_URI") or "postgresql://postgres:postgres@localhost/discours" JWT_ALGORITHM = "HS256" JWT_SECRET_KEY = "8f1bd7696ffb482d8486dfbc6e7d16dd-secret-key" JWT_LIFE_SPAN = 24 * 60 * 60 # seconds From f132b09e4f0506718afbb851dd9780dca1521a1b Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Mon, 26 Jul 2021 09:17:22 +0000 Subject: [PATCH 04/11] DB_URI to DB_URL --- orm/base.py | 4 ++-- settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/orm/base.py b/orm/base.py index e3c89c6d..de6be0b3 100644 --- a/orm/base.py +++ b/orm/base.py @@ -5,9 +5,9 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy.sql.schema import Table -from settings import DB_URI +from settings import DB_URL -engine = create_engine(DB_URI, convert_unicode=True, echo=False) +engine = create_engine(DB_URL, convert_unicode=True, echo=False) Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) global_session = Session() diff --git a/settings.py b/settings.py index 1cb3a9a0..bd7b2277 100644 --- a/settings.py +++ b/settings.py @@ -3,7 +3,7 @@ from os import environ PORT = 80 -DB_URI = environ.get("DB_URI") or "postgresql://postgres:postgres@localhost/discours" +DB_URL = environ.get("DB_URL") or "postgresql://postgres:postgres@localhost/discours" JWT_ALGORITHM = "HS256" JWT_SECRET_KEY = "8f1bd7696ffb482d8486dfbc6e7d16dd-secret-key" JWT_LIFE_SPAN = 24 * 60 * 60 # seconds From c604114c278b8023047a5016bfc4929475efafbb Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 27 Jul 2021 07:28:44 +0300 Subject: [PATCH 05/11] ignore certs --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b39cd2b5..f73ce680 100644 --- a/.gitignore +++ b/.gitignore @@ -130,4 +130,7 @@ dmypy.json .idea temp.* -*.sqlite3 \ No newline at end of file +*.sqlite3 + +discours.key +discours.crt \ No newline at end of file From 0517dfc7441d9a2d0e175c37a506eaebbeeef4cc Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 27 Jul 2021 07:51:16 +0300 Subject: [PATCH 06/11] scheme review, topic type added --- schema.graphql | 166 +++++++++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 69 deletions(-) diff --git a/schema.graphql b/schema.graphql index dc562f4e..2e53b117 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1,36 +1,13 @@ scalar DateTime +################################### Inputs + 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! - shout: Int - user: Int - value: Int! -} - -type createMessagePayload { - status: Boolean! - error: String - message: Message -} - input MessageInput { body: String! replyTo: Int @@ -41,16 +18,27 @@ input updateMessageInput { body: String! } -type Message { - author: Int! - body: String! - createdAt: DateTime! - id: Int! - replyTo: Int - updatedAt: DateTime! - visibleForUsers: [Int] +################################### Payloads + +type signInPayload { + status: Boolean! + error: String + token: String } +type ResultPayload { + status: Boolean! + error: String +} + +type createMessagePayload { + status: Boolean! + error: String + message: Message +} + +################################### Mutation + type Mutation { # message createMessage(input: MessageInput!): createMessagePayload! @@ -77,6 +65,8 @@ type Mutation { updateUsername(username: String!): User! } +################################### Query + type Query { # auth / user signIn(email: String!, password: String!): signInPayload! @@ -102,36 +92,7 @@ type Query { topShouts: [Shout]! } -type Role { - id: Int! - name: String! -} - -type Shout { - author: Int! - body: String! - createdAt: DateTime! - deletedAt: DateTime - deletedBy: Int - id: Int! - rating: Int - published: DateTime! # if there is no published field - it is not published - replyTo: Int # another shout - tags: [String] - title: String - updatedAt: DateTime! - versionOf: Int - visibleForRoles: [Role]! - visibleForUsers: [Int] -} - -type Proposal { - body: String! - shout: Int! - range: String # full / 0:2340 - author: Int! - createdAt: DateTime! -} +############################################ Subscription type Subscription { messageCreated: Message! @@ -143,13 +104,11 @@ type Subscription { userUpdated: User! } -type Token { - createdAt: DateTime! - expiresAt: DateTime +############################################ Entities + +type Role { id: Int! - ownerId: Int! - usedAt: DateTime - value: String! + name: String! } type User { @@ -166,3 +125,72 @@ type User { userpicId: String wasOnlineAt: DateTime } + +type Message { + author: Int! + body: String! + createdAt: DateTime! + id: Int! + replyTo: Int + updatedAt: DateTime! + visibleForUsers: [Int] +} + + +# is publication +type Shout { + id: Int! # TODO: replace with string? slugs-like-this + slug: String + author: Int! + body: String! + createdAt: DateTime! + deletedAt: DateTime + deletedBy: Int + rating: Int + published: DateTime! # if there is no published field - it is not published + replyTo: Int # another shout + tags: [String] # actual values + topics: [String] # topics-slugs + title: String + updatedAt: DateTime! + versionOf: Int + visibleForRoles: [Role]! + visibleForUsers: [Int] +} + +type Topic { + slug: String + original: String + parents: [String] # NOTE: topic can have parent topics + children: [String] # and children + createdBy: User! + createdAt: DateTime! +} + +# TODO: resolvers to add/remove topics from publication + + +type Proposal { + body: String! + shout: Int! + range: String # full / 0:2340 + author: Int! + createdAt: DateTime! +} + +type Token { + createdAt: DateTime! + expiresAt: DateTime + id: Int! + ownerId: Int! + usedAt: DateTime + value: String! +} + +type Like { + author: Int! + id: Int! + shout: Int + user: Int + value: Int! +} From ea06b61d3f1ddc067dc068f52b1879a841529393 Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 27 Jul 2021 07:58:06 +0300 Subject: [PATCH 07/11] shout related todos, schema update --- resolvers/zine.py | 26 ++++++++++++++++++++++++++ schema.graphql | 10 ++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 resolvers/zine.py diff --git a/resolvers/zine.py b/resolvers/zine.py new file mode 100644 index 00000000..32af9291 --- /dev/null +++ b/resolvers/zine.py @@ -0,0 +1,26 @@ +from orm import Shout, User +from orm.base import global_session + +from resolvers.base import mutation, query, subscription + +# TODO: debug me +@mutation.field("createShout") +@login_required +async def create_post(_, info, input): + auth = info.context["request"].auth + user_id = auth.user_id + + new_shout = Shout.create( + author = user_id, + body = input["body"], # TODO: add createShoutInput in scheme.graphql + title = input.get("title") + # TODO: generate slug + ) + + return { + "status": True, + "shout" : new_shout + } + + +# TODO: paginate, get, update, delete \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index 2e53b117..d34a3aee 100644 --- a/schema.graphql +++ b/schema.graphql @@ -37,6 +37,12 @@ type createMessagePayload { message: Message } +type createShoutPayload { + status: Boolean! + error: String + shout: Shout +} + ################################### Mutation type Mutation { @@ -55,8 +61,8 @@ type Mutation { registerUser(input: registerUserInput!): User! # shout - createShout(body: String!, replyTo: [Int], title: String, versionOf: [Int], visibleForRoles: [Int], visibleForUsers: [Int]): Message! - deleteShout(shoutId: Int!): Message! + createShout(): Shout! + deleteShout(shoutId: Int!): Boolean! rateShout(value: Int!): Boolean! # profile From d5ed469ed5de000678d4f7d61d7b78e0090270c4 Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 27 Jul 2021 08:41:45 +0300 Subject: [PATCH 08/11] tops --- resolvers/zine.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/resolvers/zine.py b/resolvers/zine.py index 32af9291..5c669443 100644 --- a/resolvers/zine.py +++ b/resolvers/zine.py @@ -3,6 +3,18 @@ from orm.base import global_session from resolvers.base import mutation, query, subscription +@query.field("topShouts") +async def top_shouts(_, info: GraphQLResolveInfo): + # TODO: implement top shouts + pass + + +@query.field("topAuthors") +async def top_shouts(_, info: GraphQLResolveInfo): + # TODO: implement top authors + pass + + # TODO: debug me @mutation.field("createShout") @login_required From 2f85df3c012309e961c0a7e661dfdde07f6f3148 Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 27 Jul 2021 09:50:52 +0300 Subject: [PATCH 09/11] topic schema fix --- schema.graphql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schema.graphql b/schema.graphql index d34a3aee..3aaba6dc 100644 --- a/schema.graphql +++ b/schema.graphql @@ -165,11 +165,11 @@ type Shout { } type Topic { - slug: String + slug: String! # ID + createdBy: Int! # User original: String parents: [String] # NOTE: topic can have parent topics children: [String] # and children - createdBy: User! createdAt: DateTime! } From 437be2229bfb6a4e84662b9b6922eaa2bb468b05 Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 28 Jul 2021 20:29:51 +0300 Subject: [PATCH 10/11] schema updated --- schema.graphql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/schema.graphql b/schema.graphql index 3aaba6dc..c0553e8a 100644 --- a/schema.graphql +++ b/schema.graphql @@ -113,8 +113,8 @@ type Subscription { ############################################ Entities type Role { - id: Int! name: String! + desc: String } type User { @@ -142,25 +142,25 @@ type Message { visibleForUsers: [Int] } - # is publication type Shout { - id: Int! # TODO: replace with string? slugs-like-this - slug: String + id: Int! + org: String! + slug: String! author: Int! body: String! createdAt: DateTime! + updatedAt: DateTime! deletedAt: DateTime deletedBy: Int rating: Int - published: DateTime! # if there is no published field - it is not published + published: DateTime # if there is no published field - it is not published replyTo: Int # another shout tags: [String] # actual values - topics: [String] # topics-slugs + topics: [String] # topic-slugs title: String - updatedAt: DateTime! versionOf: Int - visibleForRoles: [Role]! + visibleForRoles: [String]! # role ids are strings visibleForUsers: [Int] } From fb779217bcf6208bf97690f3a822ca43ba033ec3 Mon Sep 17 00:00:00 2001 From: Untone Date: Thu, 29 Jul 2021 20:26:15 +0300 Subject: [PATCH 11/11] schema update --- auth/validations.py | 2 +- orm/user.py | 6 +++--- schema.graphql | 15 +++++++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/auth/validations.py b/auth/validations.py index e63a5e14..38a2f620 100644 --- a/auth/validations.py +++ b/auth/validations.py @@ -21,7 +21,7 @@ class PayLoad(BaseModel): class CreateUser(BaseModel): email: Text - username: Text + username: Optional[Text] # age: Optional[int] # phone: Optional[Text] password: Optional[Text] diff --git a/orm/user.py b/orm/user.py index 4cf99f4b..98822eef 100644 --- a/orm/user.py +++ b/orm/user.py @@ -1,6 +1,6 @@ from typing import List -from sqlalchemy import Column, Integer, String, ForeignKey +from sqlalchemy import Column, Integer, String, relationship from orm import Permission from orm.base import Base @@ -13,8 +13,8 @@ class User(Base): username: str = Column(String, nullable=False, comment="Name") password: str = Column(String, nullable=True, comment="Password") - role_id: int = Column(ForeignKey("role.id"), nullable=True, comment="Role") - + # role_id: list = Column(ForeignKey("role.id"), nullable=True, comment="Roles") + # roles = relationship("Role") TODO: one to many, see schema.graphql oauth_id: str = Column(String, nullable=True) @classmethod diff --git a/schema.graphql b/schema.graphql index c0553e8a..d6bb2883 100644 --- a/schema.graphql +++ b/schema.graphql @@ -4,7 +4,7 @@ scalar DateTime input registerUserInput { email: String! - username: String! + username: String password: String! } @@ -113,7 +113,10 @@ type Subscription { ############################################ Entities type Role { + id: Int! name: String! + org: String! + level: Int! # 1-8 desc: String } @@ -139,7 +142,7 @@ type Message { id: Int! replyTo: Int updatedAt: DateTime! - visibleForUsers: [Int] + visibleForUsers: [Int]! } # is publication @@ -160,17 +163,17 @@ type Shout { topics: [String] # topic-slugs title: String versionOf: Int - visibleForRoles: [String]! # role ids are strings + visibleForRoles: [String] # role ids are strings visibleForUsers: [Int] } type Topic { slug: String! # ID createdBy: Int! # User - original: String + createdAt: DateTime! + value: String parents: [String] # NOTE: topic can have parent topics children: [String] # and children - createdAt: DateTime! } # TODO: resolvers to add/remove topics from publication @@ -196,7 +199,7 @@ type Token { type Like { author: Int! id: Int! + value: Int! shout: Int user: Int - value: Int! }