diff --git a/app/api/feedbacks.py b/app/api/feedbacks.py index 233d1f4d75..a0c6c2ee3e 100644 --- a/app/api/feedbacks.py +++ b/app/api/feedbacks.py @@ -1,9 +1,10 @@ from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship from flask_rest_jsonapi.exceptions import ObjectNotFound +from flask_jwt import current_identity as current_user from app.api.bootstrap import api from app.api.helpers.db import safe_query -from app.api.helpers.exceptions import UnprocessableEntity +from app.api.helpers.exceptions import UnprocessableEntity, ForbiddenException from app.api.helpers.permission_manager import has_access from app.api.helpers.permissions import jwt_required from app.api.helpers.query import event_query @@ -12,6 +13,7 @@ from app.models import db from app.models.feedback import Feedback from app.models.event import Event +from app.models.session import Session class FeedbackListPost(ResourceList): @@ -38,11 +40,24 @@ def before_post(self, args, kwargs, data): raise UnprocessableEntity({'pointer': ''}, "A valid relationship with event and session is required") + def before_create_object(self, data, view_kwargs): + """ + before create object method for FeedbackListPost Class + :param data: + :param view_kwargs: + :return: + """ + if data.get('session', None): + session = Session.query.filter_by(id=data['session']).first() + if session and not has_access('is_coorganizer', event_id=session.event_id): + raise ForbiddenException({'source': ''}, + "Event co-organizer access required") + schema = FeedbackSchema methods = ['POST', ] data_layer = {'session': db.session, - 'model': Feedback - } + 'model': Feedback, + 'methods': {'before_create_object': before_create_object}} class FeedbackList(ResourceList): @@ -91,11 +106,29 @@ def before_get_object(self, view_kwargs): feedback = safe_query(self, Feedback, 'event_id', event.id, 'event_id') view_kwargs['id'] = feedback.id + def before_update_object(self, feedback, data, view_kwargs): + """ + before update object method of feedback details + :param feedback: + :param data: + :param view_kwargs: + :return: + """ + if feedback and feedback.session_id: + session = Session.query.filter_by(id=feedback.session_id).first() + if session and not current_user.id == feedback.user_id: + raise ForbiddenException({'source': ''}, + "Feedback can be updated only by user himself") + if session and not has_access('is_coorganizer', event_id=session.event_id): + raise ForbiddenException({'source': ''}, + "Event co-organizer access required") + decorators = (api.has_permission('is_user_itself', fetch='user_id', fetch_as="user_id", model=Feedback, methods="PATCH,DELETE"),) schema = FeedbackSchema data_layer = {'session': db.session, - 'model': Feedback} + 'model': Feedback, + 'methods': {'before_update_object': before_update_object}} class FeedbackRelationship(ResourceRelationship): diff --git a/app/api/schema/feedbacks.py b/app/api/schema/feedbacks.py index 35179231ba..b63cc4c343 100644 --- a/app/api/schema/feedbacks.py +++ b/app/api/schema/feedbacks.py @@ -37,7 +37,7 @@ class Meta: self_view_kwargs={'id': ''}, related_view='v1.session_detail', related_view_kwargs={'feedback_id': ''}, - schema='SessionsSchema', + schema='SessionSchema', type_='session') user = Relationship(attribute='user', self_view='v1.feedback_user', diff --git a/app/factories/feedback.py b/app/factories/feedback.py index 79049c8eee..0baa84f4db 100644 --- a/app/factories/feedback.py +++ b/app/factories/feedback.py @@ -1,6 +1,6 @@ import factory -from app.factories.event import EventFactoryBasic +from app.factories.session import SessionFactory from app.factories.user import UserFactory from app.models.feedback import db, Feedback @@ -11,9 +11,9 @@ class Meta: model = Feedback sqlalchemy_session = db.session - event = factory.RelatedFactory(EventFactoryBasic) + session = factory.RelatedFactory(SessionFactory) user = factory.RelatedFactory(UserFactory) rating = "4" - comment = "Awesome event." - event_id = 1 - user_id = 2 + comment = "Awesome session." + session_id = 1 + user_id = 1 diff --git a/docs/api/api_blueprint.apib b/docs/api/api_blueprint.apib index ee792d3188..02ad4f332d 100644 --- a/docs/api/api_blueprint.apib +++ b/docs/api/api_blueprint.apib @@ -21351,26 +21351,26 @@ Create a new feedback with event_id. { "data": { - "type": "feedback", "relationships": { - "event": { - "data": { - "type": "event", - "id": "1" - } - }, - "user": { - "data": { - "type": "user", - "id": "1" - } - } - }, - "attributes": { - "rating": "4", - "comment": "Awesome event." + "session": { + "data": { + "type": "session", + "id": "1" } - } + }, + "user": { + "data": { + "type": "user", + "id": "1" + } + } + }, + "attributes": { + "rating": 4, + "comment": "Awesome session." + }, + "type": "feedback" + } } @@ -21379,9 +21379,9 @@ Create a new feedback with event_id. { "data": { "relationships": { - "event": { + "session": { "links": { - "self": "/v1/feedbacks/1/relationships/event", + "self": "/v1/feedbacks/1/relationships/session", "related": "/v1/feedbacks/1/event" } }, @@ -21390,12 +21390,18 @@ Create a new feedback with event_id. "self": "/v1/feedbacks/1/relationships/user", "related": "/v1/feedbacks/1/user" } + }, + "event": { + "links": { + "self": "/v1/feedbacks/1/relationships/event", + "related": "/v1/feedbacks/1/event" + } } }, "attributes": { - "rating": "4", + "rating": 4.0, "deleted-at": null, - "comment": "Awesome event" + "comment": "Awesome session." }, "type": "feedback", "id": 1, @@ -21480,7 +21486,7 @@ Update a single feedback with `id`. "type": "feedback", "attributes": { "rating": "5", - "comment": "Awesome event" + "comment": "Awesome session" }, "id": "1" } diff --git a/tests/hook_main.py b/tests/hook_main.py index 09fbab8a10..66575afc31 100644 --- a/tests/hook_main.py +++ b/tests/hook_main.py @@ -734,8 +734,8 @@ def feedback_post(transaction): :return: """ with stash['app'].app_context(): - event = EventFactoryBasic() - db.session.add(event) + session = SessionFactory() + db.session.add(session) db.session.commit()