Repository: fossasia/open-event-server

Issue:
Social-links: Add seperate resourcelist class, docs, permissions for direct endpoints
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
@@ -15,7 +15,7 @@
     SessionRelationshipOptional
 from app.api.speakers import SpeakerList, SpeakerListPost, SpeakerDetail, SpeakerRelationshipRequired,\
     SpeakerRelationshipOptional
-from app.api.social_links import SocialLinkList, SocialLinkDetail, SocialLinkRelationship
+from app.api.social_links import SocialLinkList, SocialLinkListPost, SocialLinkDetail, SocialLinkRelationship
 from app.api.sponsors import SponsorList, SponsorListPost, SponsorDetail, SponsorRelationship
 from app.api.tracks import TrackList, TrackListPost, TrackDetail, TrackRelationshipOptional, TrackRelationshipRequired
 from app.api.speakers_calls import SpeakersCallList, SpeakersCallDetail, SpeakersCallRelationship
@@ -208,7 +208,8 @@
           '/sessions/<int:id>/relationships/speakers')
 
 # social_links
-api.route(SocialLinkList, 'social_link_list', '/social-links', '/events/<int:event_id>/social-links',
+api.route(SocialLinkListPost, 'social_link_list_post', '/social-links')
+api.route(SocialLinkList, 'social_link_list', '/events/<int:event_id>/social-links',
           '/events/<event_identifier>/social-links')
 api.route(SocialLinkDetail, 'social_link_detail', '/social-links/<int:id>')
 api.route(SocialLinkRelationship, 'social_link_event',
diff --git a/app/api/social_links.py b/app/api/social_links.py
--- a/app/api/social_links.py
+++ b/app/api/social_links.py
@@ -1,6 +1,8 @@
 from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
 from marshmallow_jsonapi.flask import Schema, Relationship
 from marshmallow_jsonapi import fields
+from flask_rest_jsonapi.exceptions import ObjectNotFound
+from flask import request
 
 from app.api.helpers.utilities import dasherize
 from app.api.helpers.permissions import jwt_required
@@ -10,6 +12,7 @@
 from app.api.bootstrap import api
 from app.api.helpers.db import safe_query
 from app.api.helpers.utilities import require_relationship
+from app.api.helpers.permission_manager import has_access
 
 
 class SocialLinkSchema(Schema):
@@ -37,13 +40,23 @@ class Meta:
                          type_='event')
 
 
-class SocialLinkList(ResourceList):
+class SocialLinkListPost(ResourceList):
     """
     List and Create Social Links for an event
     """
     def before_post(self, args, kwargs, data):
         require_relationship(['event'], data)
 
+    methods = ['POST']
+    schema = SocialLinkSchema
+    data_layer = {'session': db.session,
+                  'model': SocialLink}
+
+
+class SocialLinkList(ResourceList):
+    """
+    List and Create Social Links for an event
+    """
     def query(self, view_kwargs):
         """
         query method for social link
@@ -53,36 +66,33 @@ def query(self, view_kwargs):
         query_ = self.session.query(SocialLink)
         if view_kwargs.get('event_id'):
             event = safe_query(self, Event, 'id', view_kwargs['event_id'], 'event_id')
-            query_ = query_.join(Event).filter(Event.id == event.id)
-        elif view_kwargs.get('event_identifier'):
-            event = safe_query(self, Event, 'identifier', view_kwargs['event_identifier'], 'identifier')
-            query_ = query_.join(Event).filter(Event.id == event.id)
-        return query_
-
-    def before_create_object(self, data, view_kwargs):
-        """
-        method to create object before post
-        :param data:
-        :param view_kwargs:
-        :return:
-        """
-        event = None
-        if view_kwargs.get('event_id'):
-            event = safe_query(self, Event, 'id', view_kwargs['event_id'], 'event_id')
+            if event.state != 'published':
+                if 'Authorization' in request.headers and has_access('is_coorganizer', event_id=event.id):
+                    query_ = query_.join(Event).filter(Event.id == event.id)
+                else:
+                    raise ObjectNotFound({'parameter': 'event_id'},
+                                         "Event: {} not found".format(view_kwargs['event_identifier']))
+            else:
+                query_ = query_.join(Event).filter(Event.id == event.id)
         elif view_kwargs.get('event_identifier'):
             event = safe_query(self, Event, 'identifier', view_kwargs['event_identifier'], 'event_identifier')
-        if event:
-            data['event_id'] = event.id
+            if event.state != 'published':
+                if 'Authorization' in request.headers and has_access('is_coorganizer', event_id=event.id):
+                    query_ = query_.join(Event).filter(Event.id == event.id)
+                else:
+                    raise ObjectNotFound({'parameter': 'event_identifier'},
+                                         "Event: {} not found".format(view_kwargs['event_identifier']))
+            else:
+                query_ = query_.join(Event).filter(Event.id == event.id)
+        return query_
 
     view_kwargs = True
-    decorators = (api.has_permission('is_coorganizer', fetch='event_id', fetch_as="event_id", methods="POST",
-                                     check=lambda a: a.get('event_id') or a.get('event_identifier')),)
+    methods = ['GET']
     schema = SocialLinkSchema
     data_layer = {'session': db.session,
                   'model': SocialLink,
                   '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
@@ -669,7 +669,7 @@ def user_speakers(transaction):
 
 
 # ------------------------- Social Links -------------------------
-@hooks.before("Social Links > Social Links Collection > List All Social Links")
+@hooks.before("Social Links > Social Links Get Collection > List All Social Links")
 def social_link_get_list(transaction):
     """
     GET /events/1/social-links
@@ -682,16 +682,13 @@ def social_link_get_list(transaction):
         db.session.commit()
 
 
-@hooks.before("Social Links > Social Links Collection > Create Social Link")
+@hooks.before("Social Links > Social Links Post Collection > Create Social Link")
 def social_link_post(transaction):
     """
     POST /events/1/social-links
     :param transaction:
     :return:
     """
-    # Skip until docs for direct endpoints added
-    transaction['skip'] = True
-
     with stash['app'].app_context():
         event = EventFactoryBasic()
         db.session.add(event)