From baf61913b7e7f5b4d629ab38eb7c128bd6ecef0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D0=BE=D1=84=D0=B5=D0=B5=D0=B2=20=D0=9D?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BB=D0=B5=D0=BA=D1=81?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 10 Feb 2025 20:57:39 +0000 Subject: [PATCH 1/5] add userid check --- rating_api/routes/comment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index ee58be5..ee7fb8f 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -160,7 +160,7 @@ async def get_comments( user_id: int | None = None, order_by: list[Literal["create_ts"]] = Query(default=[]), unreviewed: bool = False, - user=Depends(UnionAuth(scopes=['rating.comment.review'], auto_error=False, allow_none=True)), + user=Depends(UnionAuth(auto_error=False, allow_none=True)), ) -> CommentGetAll: """ Scopes: `["rating.comment.review"]` @@ -193,7 +193,7 @@ async def get_comments( if unreviewed: if not user: raise ForbiddenAction(Comment) - if "rating.comment.review" in [scope['name'] for scope in user.get('session_scopes')]: + if "rating.comment.review" in [scope['name'] for scope in user.get('session_scopes')] or user.get('id') == user_id: result.comments = [comment for comment in result.comments if comment.review_status is ReviewStatus.PENDING] else: raise ForbiddenAction(Comment) From b79fb046fb9b79438caa9b5da71f80a7a1681b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D0=BE=D1=84=D0=B5=D0=B5=D0=B2=20=D0=9D?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BB=D0=B5=D0=BA=D1=81?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 10 Feb 2025 21:03:41 +0000 Subject: [PATCH 2/5] lint --- rating_api/routes/comment.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index ee7fb8f..bdbcbb9 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -193,7 +193,10 @@ async def get_comments( if unreviewed: if not user: raise ForbiddenAction(Comment) - if "rating.comment.review" in [scope['name'] for scope in user.get('session_scopes')] or user.get('id') == user_id: + if ( + "rating.comment.review" in [scope['name'] for scope in user.get('session_scopes')] + or user.get('id') == user_id + ): result.comments = [comment for comment in result.comments if comment.review_status is ReviewStatus.PENDING] else: raise ForbiddenAction(Comment) From 3d95779e119e8bfee858bced11a8c25d0af38012 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 3 Mar 2025 23:42:35 +0300 Subject: [PATCH 3/5] rework --- rating_api/routes/comment.py | 32 +++++++++++++++++++++++-------- rating_api/schemas/models.py | 23 ++++++++++++++++++++++ tests/test_routes/test_comment.py | 2 +- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index bdbcbb9..a245d86 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -1,5 +1,5 @@ import datetime -from typing import Literal +from typing import Literal, Union from uuid import UUID import aiohttp @@ -10,7 +10,14 @@ from rating_api.exceptions import ForbiddenAction, ObjectNotFound, TooManyCommentRequests, TooManyCommentsToLecturer from rating_api.models import Comment, Lecturer, LecturerUserComment, ReviewStatus from rating_api.schemas.base import StatusResponseModel -from rating_api.schemas.models import CommentGet, CommentGetAll, CommentImportAll, CommentPost +from rating_api.schemas.models import ( + CommentGet, + CommentGetAll, + CommentGetAllWithStatus, + CommentGetWithStatus, + CommentImportAll, + CommentPost, +) from rating_api.settings import Settings, get_settings @@ -152,7 +159,7 @@ async def get_comment(uuid: UUID) -> CommentGet: return CommentGet.model_validate(comment) -@comment.get("", response_model=CommentGetAll) +@comment.get("", response_model=Union[CommentGetAll, CommentGetAllWithStatus]) async def get_comments( limit: int = 10, offset: int = 0, @@ -160,10 +167,10 @@ async def get_comments( user_id: int | None = None, order_by: list[Literal["create_ts"]] = Query(default=[]), unreviewed: bool = False, - user=Depends(UnionAuth(auto_error=False, allow_none=True)), + user=Depends(UnionAuth(scopes=["rating.comment.user"], auto_error=False, allow_none=True)), ) -> CommentGetAll: """ - Scopes: `["rating.comment.review"]` + Scopes: `["rating.comment.user"]` `limit` - максимальное количество возвращаемых комментариев @@ -182,7 +189,12 @@ async def get_comments( comments = Comment.query(session=db.session).all() if not comments: raise ObjectNotFound(Comment, 'all') - result = CommentGetAll(limit=limit, offset=offset, total=len(comments)) + if "rating.comment.user" in [scope['name'] for scope in user.get('session_scopes')] or user.get('id') == user_id: + result = CommentGetAllWithStatus(limit=limit, offset=offset, total=len(comments)) + comment_validator = CommentGetWithStatus + else: + result = CommentGetAll(limit=limit, offset=offset, total=len(comments)) + comment_validator = CommentGet result.comments = comments if user_id is not None: result.comments = [comment for comment in result.comments if comment.user_id == user_id] @@ -197,7 +209,11 @@ async def get_comments( "rating.comment.review" in [scope['name'] for scope in user.get('session_scopes')] or user.get('id') == user_id ): - result.comments = [comment for comment in result.comments if comment.review_status is ReviewStatus.PENDING] + result.comments = [ + comment + for comment in result.comments + if comment.review_status is ReviewStatus.PENDING or ReviewStatus.DISMISSED + ] else: raise ForbiddenAction(Comment) else: @@ -208,7 +224,7 @@ async def get_comments( if "create_ts" in order_by: result.comments.sort(key=lambda comment: comment.create_ts, reverse=True) result.total = len(result.comments) - result.comments = [CommentGet.model_validate(comment) for comment in result.comments] + result.comments = [comment_validator.model_validate(comment) for comment in result.comments] result.comments.sort(key=lambda comment: comment.create_ts, reverse=True) return result diff --git a/rating_api/schemas/models.py b/rating_api/schemas/models.py index 4cfa074..da57b2e 100644 --- a/rating_api/schemas/models.py +++ b/rating_api/schemas/models.py @@ -4,6 +4,7 @@ from pydantic import field_validator from rating_api.exceptions import WrongMark +from rating_api.models import ReviewStatus from rating_api.schemas.base import Base @@ -21,6 +22,21 @@ class CommentGet(Base): lecturer_id: int +class CommentGetWithStatus(Base): + uuid: UUID + user_id: int | None = None + create_ts: datetime.datetime + update_ts: datetime.datetime + subject: str | None = None + text: str + mark_kindness: int + mark_freebie: int + mark_clarity: int + mark_general: float + lecturer_id: int + review_status: ReviewStatus + + class CommentPost(Base): subject: str text: str @@ -55,6 +71,13 @@ class CommentGetAll(Base): total: int +class CommentGetAllWithStatus(Base): + comments: list[CommentGetWithStatus] = [] + limit: int + offset: int + total: int + + class LecturerUserCommentPost(Base): lecturer_id: int user_id: int diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index c891640..36db41a 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -193,7 +193,6 @@ def test_comments_by_user_id(client, lecturers_with_comments, user_id, response_ ] ) - @pytest.mark.parametrize( 'review_status, response_status,is_reviewed', [ @@ -227,3 +226,4 @@ def test_delete_comment(client, dbsession, comment): assert comment.is_deleted response = client.get(f'{url}/{comment.uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND + From 624f9099903ebbae636c9c72ad083369d25836f3 Mon Sep 17 00:00:00 2001 From: Nick Date: Sun, 9 Mar 2025 03:15:44 +0300 Subject: [PATCH 4/5] lint --- rating_api/routes/comment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rating_api/routes/comment.py b/rating_api/routes/comment.py index fe919fc..d501142 100644 --- a/rating_api/routes/comment.py +++ b/rating_api/routes/comment.py @@ -1,6 +1,6 @@ import datetime -from typing import Literal, Union import re +from typing import Literal, Union from uuid import UUID import aiohttp From 3298f720bb9d3dd3c81424a68fc30d8b0183330b Mon Sep 17 00:00:00 2001 From: Nick Date: Sun, 9 Mar 2025 03:18:50 +0300 Subject: [PATCH 5/5] lint 2 --- tests/test_routes/test_comment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_routes/test_comment.py b/tests/test_routes/test_comment.py index d45acb5..69292a4 100644 --- a/tests/test_routes/test_comment.py +++ b/tests/test_routes/test_comment.py @@ -241,6 +241,7 @@ def test_comments_by_user_id(client, lecturers_with_comments, user_id, response_ ] ) + @pytest.mark.parametrize( 'review_status, response_status,is_reviewed', [ @@ -352,4 +353,3 @@ def test_delete_comment(client, dbsession, comment): assert comment.is_deleted response = client.get(f'{url}/{comment.uuid}') assert response.status_code == status.HTTP_404_NOT_FOUND -