From c53b7a4c6c623070b1a77cfb4d14042243aa43db Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 28 Nov 2023 12:05:39 +0300 Subject: [PATCH] author-id-fix --- CHANGELOG.txt | 4 +++ resolvers/chats.py | 8 +++--- resolvers/load.py | 4 +-- resolvers/messages.py | 4 +-- services/auth.py | 24 ++++++------------ services/core.py | 58 ++++++++++++++++++++++++++++++++----------- services/presence.py | 2 +- 7 files changed, 64 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3bf6427..5b1dc93 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,7 @@ +[0.2.16] +- resolvers: snake case queries and mutations +- resolvers: fix auth context usage with string user_id + [0.2.15] - chore: schema service removed diff --git a/resolvers/chats.py b/resolvers/chats.py index 99cd828..2bd96a7 100644 --- a/resolvers/chats.py +++ b/resolvers/chats.py @@ -1,6 +1,6 @@ import json import uuid -from datetime import datetime, timezone +import time from services.auth import login_required from services.rediscache import redis @@ -32,7 +32,7 @@ async def update_chat(_, info, chat_new: ChatUpdate): { "title": chat_new.get("title", chat["title"]), "description": chat_new.get("description", chat["description"]), - "updated_at": int(datetime.now(tz=timezone.utc).timestamp()), + "updated_at": int(time.time()), "admins": chat_new.get("admins", chat.get("admins") or []), "members": chat_new.get("members", chat["members"]), } @@ -75,8 +75,8 @@ async def create_chat(_, info, title="", members=None): "title": title, "description": "", "created_by": author_id, - "created_at": int(datetime.now(tz=timezone.utc).timestamp()), - "updated_at": int(datetime.now(tz=timezone.utc).timestamp()), + "created_at": int(time.time()), + "updated_at": int(time.time()), "admins": members if (len(members) == 2 and title == "") else [], } diff --git a/resolvers/load.py b/resolvers/load.py index 78facee..70d8fb9 100644 --- a/resolvers/load.py +++ b/resolvers/load.py @@ -11,8 +11,8 @@ from models.member import ChatMember from resolvers.chats import create_chat -async def get_unread_counter(chat_id: str, author_id: int) -> int: - unread = await redis.execute("LLEN", f"chats/{chat_id}/unread/{author_id}") +async def get_unread_counter(chat_id: str, member_id: int) -> int: + unread = await redis.execute("LLEN", f"chats/{chat_id}/unread/{member_id}") return unread or 0 diff --git a/resolvers/messages.py b/resolvers/messages.py index e2542e1..555b060 100644 --- a/resolvers/messages.py +++ b/resolvers/messages.py @@ -101,7 +101,7 @@ async def update_message(_, info, message): if body: message["body"] = body - message["updated_at"] = int(datetime.now(tz=timezone.utc).timestamp()) + message["updated_at"] = int(time.time()) await redis.execute("SET", f"chats/{chat_id}/messages/{message_id}", json.dumps(message)) @@ -114,7 +114,7 @@ async def update_message(_, info, message): return {"message": message, "error": "cannot update, no message_id"} -@mutation.field("deleteMessage") +@mutation.field("delete_message") @login_required async def delete_message(_, info, chat_id: str, message_id: int): author_id = info.context["author_id"] diff --git a/services/auth.py b/services/auth.py index eb7a820..0a8fee0 100644 --- a/services/auth.py +++ b/services/auth.py @@ -1,5 +1,7 @@ from functools import wraps -from httpx import AsyncClient, HTTPError +from httpx import AsyncClient + +from services.core import get_author from settings import AUTH_URL @@ -42,23 +44,13 @@ def login_required(f): raise Exception("You are not logged in") else: # Добавляем author_id в контекст - context["author_id"] = user_id + author = await get_author(user_id) + if author: + context["author_id"] = author.id + elif user_id: + context["user_id"] = user_id # Если пользователь аутентифицирован, выполняем резолвер return await f(*args, **kwargs) return decorated_function - - -def auth_request(f): - @wraps(f) - async def decorated_function(*args, **kwargs): - req = args[0] - is_authenticated, user_id = await check_auth(req) - if not is_authenticated: - raise HTTPError("please, login first") - else: - req["author_id"] = user_id - return await f(*args, **kwargs) - - return decorated_function diff --git a/services/core.py b/services/core.py index 8737739..6114ae2 100644 --- a/services/core.py +++ b/services/core.py @@ -1,11 +1,30 @@ from httpx import AsyncClient from settings import API_BASE -from typing import List +from typing import List, Any from models.member import ChatMember + headers = {"Content-Type": "application/json"} +async def _request_endpoint(query_name, body) -> Any: + async with AsyncClient() as client: + try: + response = await client.post(API_BASE, headers=headers, json=body) + print(f"[services.core] {query_name}: [{response.status_code}] {len(response.text)} bytes") + if response.status_code != 200: + return [] + r = response.json() + if r: + return r.get("data", {}).get(query_name, {}) + else: + raise Exception("json response error") + except Exception: + import traceback + + traceback.print_exc() + + async def get_all_authors() -> List[ChatMember]: query_name = "authorsAll" query_type = "query" @@ -18,20 +37,7 @@ async def get_all_authors() -> List[ChatMember]: "variables": None, } - async with AsyncClient() as client: - try: - response = await client.post(API_BASE, headers=headers, json=gql) - print(f"[services.core] {query_name}: [{response.status_code}] {len(response.text)} bytes") - if response.status_code != 200: - return [] - r = response.json() - if r: - return r.get("data", {}).get(query_name, []) - except Exception: - import traceback - - traceback.print_exc() - return [] + return _request_endpoint(query_name, gql) async def get_my_followed() -> List[ChatMember]: @@ -60,3 +66,25 @@ async def get_my_followed() -> List[ChatMember]: traceback.print_exc() return [] + + +async def get_author(author_id: int = None, slug: str = "", user: str = ""): + query_name = "get_author(author_id: $author_id, slug: $slug, user: $user)" + query_type = "query" + operation = "GetAuthor($author_id: Int, $slug: String, $user: String)" + query_fields = "id slug pic name" + vars = {} + if author_id: + vars["author_id"] = author_id + elif slug: + vars["slug"] = slug + elif user: + vars["user"] = user + + gql = { + "query": query_type + " " + operation + " { " + query_name + " { " + query_fields + "} " + " }", + "operationName": operation, + "variables": None if vars == {} else vars, + } + + return await _request_endpoint(query_name, gql) diff --git a/services/presence.py b/services/presence.py index 5ee6427..99b5915 100644 --- a/services/presence.py +++ b/services/presence.py @@ -14,7 +14,7 @@ async def notify_message(message: Message, action="create"): print(f"Failed to publish to channel {channel_name}: {e}") -async def notify_chat(chat: ChatUpdate, member_id, action="create"): +async def notify_chat(chat: ChatUpdate, member_id: int, action="create"): channel_name = f"chat:{member_id}" data = {"payload": chat, "action": action} try: