From 7746d1992fdc229d41f2e853c53c5165275c3d27 Mon Sep 17 00:00:00 2001 From: Untone Date: Mon, 5 Feb 2024 12:47:26 +0300 Subject: [PATCH] fmt --- resolvers/editor.py | 7 +++-- resolvers/reaction.py | 63 ++++++++++++++++++++++--------------------- services/auth.py | 17 +++++++----- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/resolvers/editor.py b/resolvers/editor.py index 59d313c8..29d01a4a 100644 --- a/resolvers/editor.py +++ b/resolvers/editor.py @@ -32,6 +32,7 @@ async def get_shouts_drafts(_, info): joinedload(Shout.topics), ) .filter(and_(Shout.deleted_at.is_(None), Shout.created_by == author.id)) + .filter(Shout.published_at.is_(None)) .group_by(Shout.id) ) shouts = [shout for [shout] in session.execute(q).unique()] @@ -161,6 +162,7 @@ def patch_topics(session, shout, topics_input): @login_required async def update_shout(_, info, shout_id, shout_input=None, publish=False): user_id = info.context['user_id'] + roles = info.context['roles'] if not shout_input: shout_input = {} with local_session() as session: @@ -178,7 +180,7 @@ async def update_shout(_, info, shout_id, shout_input=None, publish=False): ) if not shout: return {'error': 'shout not found'} - if shout.created_by is not author.id and author.id not in shout.authors: + if shout.created_by is not author.id and author.id not in shout.authors and 'editor' not in roles: return {'error': 'access denied'} # topics patch @@ -215,13 +217,14 @@ async def update_shout(_, info, shout_id, shout_input=None, publish=False): @login_required async def delete_shout(_, info, shout_id): user_id = info.context['user_id'] + roles = info.context['roles'] with local_session() as session: author = session.query(Author).filter(Author.user == user_id).first() shout = session.query(Shout).filter(Shout.id == shout_id).first() if not shout: return {'error': 'invalid shout id'} if author and shout: - if shout.created_by is not author.id and author.id not in shout.authors: + if shout.created_by is not author.id and author.id not in shout.authors and 'editor' not in roles: return {'error': 'access denied'} for author_id in shout.authors: diff --git a/resolvers/reaction.py b/resolvers/reaction.py index 53952214..bfd85d84 100644 --- a/resolvers/reaction.py +++ b/resolvers/reaction.py @@ -212,40 +212,42 @@ async def create_reaction(_, info, reaction): @login_required async def update_reaction(_, info, rid, reaction): user_id = info.context['user_id'] - with local_session() as session: - q = select(Reaction).filter(Reaction.id == rid) - aliased_reaction = aliased(Reaction) - q = add_stat_columns(q, aliased_reaction) - q = q.group_by(Reaction.id) + roles = info.context['roles'] + if user_id and roles: + with local_session() as session: + q = select(Reaction).filter(Reaction.id == rid) + aliased_reaction = aliased(Reaction) + q = add_stat_columns(q, aliased_reaction) + q = q.group_by(Reaction.id) - [r, reacted_stat, commented_stat, likes_stat, dislikes_stat, _l] = session.execute(q).unique().first() + [r, reacted_stat, commented_stat, likes_stat, dislikes_stat, _l] = session.execute(q).unique().first() - if not r: - return {'error': 'invalid reaction id'} - author = session.query(Author).filter(Author.user == user_id).first() - if author: - if r.created_by != author.id: - return {'error': 'access denied'} - body = reaction.get('body') - if body: - r.body = body - r.updated_at = int(time.time()) - if r.kind != reaction['kind']: - # TODO: change mind detection can be here - pass + if not r: + return {'error': 'invalid reaction id'} + author = session.query(Author).filter(Author.user == user_id).first() + if author: + if r.created_by != author.id and 'editor' not in roles: + return {'error': 'access denied'} + body = reaction.get('body') + if body: + r.body = body + r.updated_at = int(time.time()) + if r.kind != reaction['kind']: + # TODO: change mind detection can be here + pass - session.commit() - r.stat = { - 'reacted': reacted_stat, - 'commented': commented_stat, - 'rating': int(likes_stat or 0) - int(dislikes_stat or 0), - } + session.commit() + r.stat = { + 'reacted': reacted_stat, + 'commented': commented_stat, + 'rating': int(likes_stat or 0) - int(dislikes_stat or 0), + } - await notify_reaction(r.dict(), 'update') + await notify_reaction(r.dict(), 'update') - return {'reaction': r} - else: - return {'error': 'not authorized'} + return {'reaction': r} + else: + return {'error': 'not authorized'} return {'error': 'cannot create reaction'} @@ -253,13 +255,14 @@ async def update_reaction(_, info, rid, reaction): @login_required async def delete_reaction(_, info, reaction_id): user_id = info.context['user_id'] + roles = info.context['roles'] with local_session() as session: r = session.query(Reaction).filter(Reaction.id == reaction_id).first() if not r: return {'error': 'invalid reaction id'} author = session.query(Author).filter(Author.user == user_id).first() if author: - if r.created_by is author.id: + if r.created_by is author.id and 'editor' not in roles: return {'error': 'access denied'} if r.kind in [ReactionKind.LIKE.value, ReactionKind.DISLIKE.value]: diff --git a/services/auth.py b/services/auth.py index 8783c08d..2ea05478 100644 --- a/services/auth.py +++ b/services/auth.py @@ -31,7 +31,7 @@ async def request_data(gql, headers=None): return None -async def check_auth(req) -> str | None: +async def check_auth(req): token = req.headers.get('Authorization') user_id = '' if token: @@ -55,8 +55,10 @@ async def check_auth(req) -> str | None: } data = await request_data(gql) if data: - user_id = data.get('data', {}).get(query_name, {}).get('claims', {}).get('sub') - return user_id + user_data = data.get('data', {}).get(query_name, {}).get('claims', {}) + user_id = user_data.get('sub') + user_roles = user_data.get('allowed_roles') + return [user_id, user_roles] if not user_id: raise HTTPException(status_code=401, detail='Unauthorized') @@ -88,9 +90,11 @@ def login_required(f): info = args[1] context = info.context req = context.get('request') - user_id = await check_auth(req) - if user_id: + [user_id, user_roles] = (await check_auth(req)) or [] + if user_id and user_roles: + logger.info(f' got {user_id} roles: {user_roles}') context['user_id'] = user_id.strip() + context['roles'] = user_roles return await f(*args, **kwargs) return decorated_function @@ -100,9 +104,10 @@ def auth_request(f): @wraps(f) async def decorated_function(*args, **kwargs): req = args[0] - user_id = await check_auth(req) + [user_id, user_roles] = (await check_auth(req)) or [] if user_id: req['user_id'] = user_id.strip() + req['roles'] = user_roles return await f(*args, **kwargs) return decorated_function