Merge branch 'prepare-comments' of github.com:Discours/discours-backend into prepare-comments
This commit is contained in:
commit
5c803afa39
|
@ -28,6 +28,7 @@ class SessionToken:
|
||||||
token is of specified type
|
token is of specified type
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
print('[auth.authenticate] session token verify')
|
||||||
payload = JWTCodec.decode(token)
|
payload = JWTCodec.decode(token)
|
||||||
except ExpiredSignatureError:
|
except ExpiredSignatureError:
|
||||||
payload = JWTCodec.decode(token, verify_exp=False)
|
payload = JWTCodec.decode(token, verify_exp=False)
|
||||||
|
@ -58,6 +59,8 @@ class JWTAuthenticate(AuthenticationBackend):
|
||||||
try:
|
try:
|
||||||
payload = await SessionToken.verify(token)
|
payload = await SessionToken.verify(token)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
print("[auth.authenticate] session token verify error")
|
||||||
|
print(exc)
|
||||||
return AuthCredentials(scopes=[], error_message=str(exc)), AuthUser(
|
return AuthCredentials(scopes=[], error_message=str(exc)), AuthUser(
|
||||||
user_id=None
|
user_id=None
|
||||||
)
|
)
|
||||||
|
|
|
@ -81,6 +81,7 @@ class Identity:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def onetime(token: str) -> User:
|
async def onetime(token: str) -> User:
|
||||||
try:
|
try:
|
||||||
|
print('[auth.identity] using one time token')
|
||||||
payload = JWTCodec.decode(token)
|
payload = JWTCodec.decode(token)
|
||||||
if not await TokenStorage.exist(f"{payload.user_id}-{token}"):
|
if not await TokenStorage.exist(f"{payload.user_id}-{token}"):
|
||||||
raise InvalidToken("Login token has expired, please login again")
|
raise InvalidToken("Login token has expired, please login again")
|
||||||
|
|
|
@ -36,11 +36,13 @@ class TokenStorage:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def revoke(token: str) -> bool:
|
async def revoke(token: str) -> bool:
|
||||||
|
payload = None
|
||||||
try:
|
try:
|
||||||
|
print("[auth.tokenstorage] revoke token")
|
||||||
payload = JWTCodec.decode(token)
|
payload = JWTCodec.decode(token)
|
||||||
except: # noqa
|
except: # noqa
|
||||||
pass
|
pass
|
||||||
else:
|
finally:
|
||||||
await redis.execute("DEL", f"{payload.user_id}-{token}")
|
await redis.execute("DEL", f"{payload.user_id}-{token}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from aioredis import from_url
|
from aioredis import from_url
|
||||||
|
from asyncio import sleep
|
||||||
from settings import REDIS_URL
|
from settings import REDIS_URL
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,12 @@ class RedisCache:
|
||||||
self._instance = None
|
self._instance = None
|
||||||
|
|
||||||
async def execute(self, command, *args, **kwargs):
|
async def execute(self, command, *args, **kwargs):
|
||||||
return await self._instance.execute_command(command, *args, **kwargs)
|
while not self._instance:
|
||||||
|
await sleep(1)
|
||||||
|
try:
|
||||||
|
await self._instance.execute_command(command, *args, **kwargs)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
async def lrange(self, key, start, stop):
|
async def lrange(self, key, start, stop):
|
||||||
return await self._instance.lrange(key, start, stop)
|
return await self._instance.lrange(key, start, stop)
|
||||||
|
|
|
@ -42,6 +42,7 @@ async def get_current_user(_, info):
|
||||||
async def confirm_email(_, info, token):
|
async def confirm_email(_, info, token):
|
||||||
"""confirm owning email address"""
|
"""confirm owning email address"""
|
||||||
try:
|
try:
|
||||||
|
print('[resolvers.auth] confirm email by token')
|
||||||
payload = JWTCodec.decode(token)
|
payload = JWTCodec.decode(token)
|
||||||
user_id = payload.user_id
|
user_id = payload.user_id
|
||||||
await TokenStorage.get(f"{user_id}-{token}")
|
await TokenStorage.get(f"{user_id}-{token}")
|
||||||
|
@ -175,7 +176,7 @@ async def login(_, info, email: str, password: str = "", lang: str = "ru"):
|
||||||
}
|
}
|
||||||
except InvalidPassword:
|
except InvalidPassword:
|
||||||
print(f"[auth] {email}: invalid password")
|
print(f"[auth] {email}: invalid password")
|
||||||
raise InvalidPassword("invalid passoword") # contains webserver status
|
raise InvalidPassword("invalid password") # contains webserver status
|
||||||
# return {"error": "invalid password"}
|
# return {"error": "invalid password"}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,18 +33,24 @@ async def load_messages(chatId: str, limit: int, offset: int):
|
||||||
async def load_chats(_, info, limit: int, offset: int):
|
async def load_chats(_, info, limit: int, offset: int):
|
||||||
""" load :limit chats of current user with :offset """
|
""" load :limit chats of current user with :offset """
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
chats = await redis.execute("GET", f"chats_by_user/{user.slug}")
|
if user:
|
||||||
if chats:
|
chats = await redis.execute("GET", f"chats_by_user/{user.slug}")
|
||||||
chats = list(json.loads(chats))[offset:offset + limit]
|
if chats:
|
||||||
if not chats:
|
chats = list(json.loads(chats))[offset:offset + limit]
|
||||||
chats = []
|
if not chats:
|
||||||
for c in chats:
|
chats = []
|
||||||
c['messages'] = await load_messages(c['id'], limit, offset)
|
for c in chats:
|
||||||
c['unread'] = await get_unread_counter(c['id'], user.slug)
|
c['messages'] = await load_messages(c['id'], limit, offset)
|
||||||
return {
|
c['unread'] = await get_unread_counter(c['id'], user.slug)
|
||||||
"chats": chats,
|
return {
|
||||||
"error": None
|
"chats": chats,
|
||||||
}
|
"error": None
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
"error": "please login",
|
||||||
|
"chats": []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@query.field("loadMessagesBy")
|
@query.field("loadMessagesBy")
|
||||||
|
|
|
@ -31,6 +31,7 @@ def apply_filters(q, filters, user=None):
|
||||||
q = q.filter(Shout.createdAt > before)
|
q = q.filter(Shout.createdAt > before)
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
|
||||||
@query.field("loadShout")
|
@query.field("loadShout")
|
||||||
async def load_shout(_, info, slug):
|
async def load_shout(_, info, slug):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from sqlalchemy import and_, asc, desc, select, text, func, column
|
from sqlalchemy import and_, asc, desc, select, text, func
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
from auth.authenticate import login_required
|
from auth.authenticate import login_required
|
||||||
|
@ -23,12 +23,10 @@ async def get_reaction_stat(reaction_id):
|
||||||
def reactions_follow(user: User, slug: str, auto=False):
|
def reactions_follow(user: User, slug: str, auto=False):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
following = (
|
following = (
|
||||||
session.query(ShoutReactionsFollower)
|
session.query(ShoutReactionsFollower).where(and_(
|
||||||
.where(and_(
|
|
||||||
ShoutReactionsFollower.follower == user.slug,
|
ShoutReactionsFollower.follower == user.slug,
|
||||||
ShoutReactionsFollower.shout == slug
|
ShoutReactionsFollower.shout == slug
|
||||||
))
|
)).first()
|
||||||
.first()
|
|
||||||
)
|
)
|
||||||
if not following:
|
if not following:
|
||||||
following = ShoutReactionsFollower.create(
|
following = ShoutReactionsFollower.create(
|
||||||
|
@ -43,12 +41,10 @@ def reactions_follow(user: User, slug: str, auto=False):
|
||||||
def reactions_unfollow(user, slug):
|
def reactions_unfollow(user, slug):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
following = (
|
following = (
|
||||||
session.query(ShoutReactionsFollower)
|
session.query(ShoutReactionsFollower).where(and_(
|
||||||
.where(and_(
|
|
||||||
ShoutReactionsFollower.follower == user.slug,
|
ShoutReactionsFollower.follower == user.slug,
|
||||||
ShoutReactionsFollower.shout == slug
|
ShoutReactionsFollower.shout == slug
|
||||||
))
|
)).first()
|
||||||
.first()
|
|
||||||
)
|
)
|
||||||
if following:
|
if following:
|
||||||
session.delete(following)
|
session.delete(following)
|
||||||
|
@ -199,6 +195,7 @@ async def delete_reaction(_, info, rid):
|
||||||
session.commit()
|
session.commit()
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def map_result_item(result_item):
|
def map_result_item(result_item):
|
||||||
reaction = result_item[0]
|
reaction = result_item[0]
|
||||||
user = result_item[1]
|
user = result_item[1]
|
||||||
|
|
|
@ -23,10 +23,12 @@ class UserStorage:
|
||||||
async def get_user(id):
|
async def get_user(id):
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
user = (
|
user = (
|
||||||
session.query(User)
|
session.query(User).options(
|
||||||
.options(selectinload(User.roles), selectinload(User.ratings))
|
selectinload(User.roles),
|
||||||
.filter(User.id == id)
|
selectinload(User.ratings)
|
||||||
.one()
|
).filter(
|
||||||
|
User.id == id
|
||||||
|
).one()
|
||||||
)
|
)
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
|
@ -35,8 +35,10 @@ class ReactedStorage:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_shout_stat(slug):
|
async def get_shout_stat(slug):
|
||||||
|
viewed = int(await ViewedStorage.get_shout(slug))
|
||||||
|
print(viewed)
|
||||||
return {
|
return {
|
||||||
"viewed": await ViewedStorage.get_shout(slug),
|
"viewed": viewed,
|
||||||
"reacted": len(await ReactedStorage.get_shout(slug)),
|
"reacted": len(await ReactedStorage.get_shout(slug)),
|
||||||
"commented": len(await ReactedStorage.get_comments(slug)),
|
"commented": len(await ReactedStorage.get_comments(slug)),
|
||||||
"rating": await ReactedStorage.get_rating(slug),
|
"rating": await ReactedStorage.get_rating(slug),
|
||||||
|
|
|
@ -3,7 +3,7 @@ from datetime import timedelta, timezone, datetime
|
||||||
from gql import Client, gql
|
from gql import Client, gql
|
||||||
from gql.transport.aiohttp import AIOHTTPTransport
|
from gql.transport.aiohttp import AIOHTTPTransport
|
||||||
from base.orm import local_session
|
from base.orm import local_session
|
||||||
from sqlalchemy import func, select
|
from sqlalchemy import func
|
||||||
from orm.shout import ShoutTopic
|
from orm.shout import ShoutTopic
|
||||||
from orm.viewed import ViewedEntry
|
from orm.viewed import ViewedEntry
|
||||||
from ssl import create_default_context
|
from ssl import create_default_context
|
||||||
|
@ -119,12 +119,14 @@ class ViewedStorage:
|
||||||
if not shout_views:
|
if not shout_views:
|
||||||
shout_views = 0
|
shout_views = 0
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
shout_views_q = select(func.sum(ViewedEntry.amount)).where(
|
try:
|
||||||
ViewedEntry.shout == shout_slug
|
shout_views = session.query(func.sum(ViewedEntry.amount)).where(
|
||||||
)
|
ViewedEntry.shout == shout_slug
|
||||||
shout_views = session.execute(shout_views_q)
|
).all()[0][0]
|
||||||
self.by_shouts[shout_slug] = shout_views
|
self.by_shouts[shout_slug] = shout_views
|
||||||
self.update_topics(session, shout_slug)
|
self.update_topics(session, shout_slug)
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
|
||||||
return shout_views
|
return shout_views
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user