Repository: fossasia/open-event-server

Issue:
Add seperate resourcelist class, docs, permissions for direct endpoints of tracks
parent issue: #4101


Discussion:

Resolving patch:
diff --git a/app/api/__init__.py b/app/api/__init__.py
--- a/app/api/__init__.py
+++ b/app/api/__init__.py
@@ -14,7 +14,7 @@
 from app.api.speakers import SpeakerList, SpeakerDetail, SpeakerRelationshipRequired, SpeakerRelationshipOptional
 from app.api.social_links import SocialLinkList, SocialLinkDetail, SocialLinkRelationship
 from app.api.sponsors import SponsorList, SponsorDetail, SponsorRelationship
-from app.api.tracks import TrackList, TrackDetail, TrackRelationshipOptional, TrackRelationshipRequired
+from app.api.tracks import TrackList, TrackListPost, TrackDetail, TrackRelationshipOptional, TrackRelationshipRequired
 from app.api.speakers_calls import SpeakersCallList, SpeakersCallDetail, SpeakersCallRelationship
 from app.api.event_invoices import EventInvoiceList, EventInvoiceDetail, EventInvoiceRelationshipRequired, \
     EventInvoiceRelationshipOptional
@@ -221,7 +221,8 @@
 api.route(SponsorRelationship, 'sponsor_event', '/sponsors/<int:id>/relationships/event')
 
 # tracks
-api.route(TrackList, 'track_list', '/tracks', '/events/<int:event_id>/tracks',
+api.route(TrackListPost, 'track_list_post', '/tracks')
+api.route(TrackList, 'track_list', '/events/<int:event_id>/tracks',
           '/events/<event_identifier>/tracks')
 api.route(TrackDetail, 'track_detail', '/tracks/<int:id>', '/sessions/<int:session_id>/track')
 api.route(TrackRelationshipOptional, 'track_sessions', '/tracks/<int:id>/relationships/sessions')
diff --git a/app/api/tracks.py b/app/api/tracks.py
--- a/app/api/tracks.py
+++ b/app/api/tracks.py
@@ -15,6 +15,8 @@
 from app.models.event import Event
 from app.api.helpers.db import safe_query
 from app.api.helpers.utilities import require_relationship
+from app.api.helpers.exceptions import ForbiddenException
+from app.api.helpers.permission_manager import has_access
 
 
 class TrackSchema(Schema):
@@ -64,13 +66,24 @@ def valid_color(self, data):
                             type_='session')
 
 
-class TrackList(ResourceList):
+class TrackListPost(ResourceList):
     """
     List and create Tracks
     """
     def before_post(self, args, kwargs, data):
         require_relationship(['event'], data)
+        if not has_access('is_track_organizer', event_id=data['event']):
+            raise ForbiddenException({'source': ''}, 'Track-organizer access is required.')
+
+    schema = TrackSchema
+    data_layer = {'session': db.session,
+                  'model': Track}
+
 
+class TrackList(ResourceList):
+    """
+    List and create Tracks
+    """
     def query(self, view_kwargs):
         query_ = self.session.query(Track)
         if view_kwargs.get('event_id'):
@@ -81,22 +94,13 @@ def query(self, view_kwargs):
             query_ = query_.join(Event).filter(Event.id == event.id)
         return query_
 
-    def before_create_object(self, data, view_kwargs):
-        if view_kwargs.get('event_id'):
-            event = safe_query(self, Event, 'id', view_kwargs['event_id'], 'event_id')
-            data['event_id'] = event.id
-        elif view_kwargs.get('event_identifier'):
-            event = safe_query(self, Event, 'identifier', view_kwargs['event_identifier'], 'event_identifier')
-            data['event_id'] = event.id
-
     view_kwargs = True
-    decorators = (api.has_permission('is_track_organizer', fetch='event_id', fetch_as="event_id", methods="POST"),)
+    methods = ['GET']
     schema = TrackSchema
     data_layer = {'session': db.session,
                   'model': Track,
                   'methods': {
-                      'query': query,
-                      'before_create_object': before_create_object
+                      'query': query
                   }}
 
 


Test patch:
diff --git a/tests/hook_main.py b/tests/hook_main.py
--- a/tests/hook_main.py
+++ b/tests/hook_main.py
@@ -1202,9 +1202,6 @@ def track_post(transaction):
     :param transaction:
     :return:
     """
-    # Skip until docs for direct endpoints added
-    transaction['skip'] = True
-
     with stash['app'].app_context():
         event = EventFactoryBasic()
         db.session.add(event)