From 7b5065616f5209ccd601c487c740eeb66fcf8a90 Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Thu, 1 Jul 2021 21:26:04 +0300 Subject: [PATCH] add methods for messaging --- auth/authenticate.py | 2 +- orm/__init__.py | 1 + orm/message.py | 14 +++-- resolvers/__init__.py | 1 + resolvers/inbox.py | 101 ++++++++++++++++++++++++++------- schema/schema.auth.graphql | 9 --- schema/schema.common.graphql | 21 +++++++ schema/schema.messages.graphql | 31 ++++++++++ 8 files changed, 144 insertions(+), 36 deletions(-) create mode 100644 schema/schema.messages.graphql diff --git a/auth/authenticate.py b/auth/authenticate.py index 1eea1118..a5bb0070 100644 --- a/auth/authenticate.py +++ b/auth/authenticate.py @@ -63,7 +63,7 @@ class JWTAuthenticate(AuthenticationBackend): return AuthCredentials(scopes=[], error_message=str(exc)), AuthUser(user_id=None) scopes = User.get_permission(user_id=payload.user_id) - return AuthCredentials(scopes=scopes, logged_in=True), AuthUser(user_id=payload.user_id) + return AuthCredentials(user_id=payload.user_id, scopes=scopes, logged_in=True), AuthUser(user_id=payload.user_id) def login_required(func): diff --git a/orm/__init__.py b/orm/__init__.py index 7f0bb6ba..e75104ed 100644 --- a/orm/__init__.py +++ b/orm/__init__.py @@ -1,5 +1,6 @@ from orm.rbac import Operation, Permission, Role from orm.user import User +from orm.message import Message from orm.base import Base, engine __all__ = ["User", "Role", "Operation", "Permission"] diff --git a/orm/message.py b/orm/message.py index e914e886..f2ef48e0 100644 --- a/orm/message.py +++ b/orm/message.py @@ -1,6 +1,7 @@ from typing import List +from datetime import datetime -from sqlalchemy import Column, Integer, String, ForeignKey, Datetime +from sqlalchemy import Column, Integer, String, ForeignKey, DateTime from orm import Permission from orm.base import Base @@ -9,10 +10,11 @@ from orm.base import Base class Message(Base): __tablename__ = 'message' - sender: str = Column(ForeignKey("user.id"), nullable=False, comment="Sender") + author: int = Column(ForeignKey("user.id"), nullable=False, comment="Sender") body: str = Column(String, nullable=False, comment="Body") - createdAt: str = Column(Datetime, nullable=False, comment="Created at") - updatedAt: str = Column(Datetime, nullable=True, comment="Updated at") - replyTo: str = Column(ForeignKey("message.id", nullable=True, comment="Reply to")) + createdAt = Column(DateTime, nullable=False, default = datetime.now, comment="Created at") + updatedAt = Column(DateTime, nullable=True, comment="Updated at") + replyTo: int = Column(ForeignKey("message.id"), nullable=True, comment="Reply to") + - # TODO: work in progress, udpate this code \ No newline at end of file + # TODO: work in progress, udpate this code diff --git a/resolvers/__init__.py b/resolvers/__init__.py index 0e858f2c..cd35ddbb 100644 --- a/resolvers/__init__.py +++ b/resolvers/__init__.py @@ -1,3 +1,4 @@ from resolvers.auth import sign_in, sign_out, register +from resolvers.inbox import create_message __all__ = ["sign_in", "sign_out", "register"] diff --git a/resolvers/inbox.py b/resolvers/inbox.py index 58f77944..c4b87735 100644 --- a/resolvers/inbox.py +++ b/resolvers/inbox.py @@ -1,27 +1,88 @@ -from orm import message, user +from orm import Message, User +from orm.base import global_session -from ariadne import ObjectType, convert_kwargs_to_snake_case +from resolvers.base import mutation, query -query = ObjectType("Query") +from auth.authenticate import login_required +@mutation.field("createMessage") +@login_required +async def create_message(_, info, input): + auth = info.context["request"].auth + user_id = auth.user_id + + new_message = Message.create( + author = user_id, + body = input["body"], + replyTo = input.get("replyTo") + ) + + return { + "status": True, + "message" : new_message + } -@query.field("messages") -@convert_kwargs_to_snake_case -async def resolve_messages(obj, info, user_id): - def filter_by_userid(message): - return message["sender_id"] == user_id or \ - message["recipient_id"] == user_id +@query.field("getMessages") +@login_required +async def get_messages(_, info, count, page): + auth = info.context["request"].auth + user_id = auth.user_id + + messages = global_session.query(Message).filter(Message.author == user_id) + + return messages - user_messages = filter(filter_by_userid, messages) - return { - "success": True, - "messages": user_messages - } +def check_and_get_message(message_id, user_id) : + message = global_session.query(Message).filter(Message.id == message_id).first() + + if not message : + raise Exception("invalid id") + + if message.author != user_id : + raise Exception("access denied") + + return message +@mutation.field("updateMessage") +@login_required +async def update_message(_, info, input): + auth = info.context["request"].auth + user_id = auth.user_id + message_id = input["id"] + + try: + message = check_and_get_message(message_id, user_id) + except Exception as err: + return { + "status" : False, + "error" : err + } + + message.body = input["body"] + global_session.commit() + + return { + "status" : True, + "message" : message + } -@query.field("userId") -@convert_kwargs_to_snake_case -async def resolve_user_id(obj, info, username): - user = users.get(username) - if user: - return user["user_id"] \ No newline at end of file +@mutation.field("deleteMessage") +@login_required +async def delete_message(_, info, id): + auth = info.context["request"].auth + user_id = auth.user_id + + try: + message = check_and_get_message(id, user_id) + except Exception as err: + return { + "status" : False, + "error" : err + } + + global_session.delete(message) + global_session.commit() + + return { + "status" : True + } diff --git a/schema/schema.auth.graphql b/schema/schema.auth.graphql index 0f3404ff..a41ecf8a 100644 --- a/schema/schema.auth.graphql +++ b/schema/schema.auth.graphql @@ -35,12 +35,3 @@ 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 index bada3b71..461f7be3 100644 --- a/schema/schema.common.graphql +++ b/schema/schema.common.graphql @@ -1,2 +1,23 @@ scalar DateTime + +type Query { + signIn(id: Int!, password: String!): signInPayload! + signOut: signOutPayload! + + getMessages(count: Int = 100, page: Int = 1): [Message!]! +} + +type Mutation { + registerUser(input: registerUserInput!): User! + + createMessage(input: MessageInput!): createMessagePayload! + updateMessage(input: updateMessageInput!): createMessagePayload! + deleteMessage(id: Int!): deleteMessagePayload! +} + +type Subscription { + messageCreated: Message! + messageUpdated: Message! + messageDeleted: Message! +} diff --git a/schema/schema.messages.graphql b/schema/schema.messages.graphql new file mode 100644 index 00000000..95b5a760 --- /dev/null +++ b/schema/schema.messages.graphql @@ -0,0 +1,31 @@ + +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! +}