Repository: Cloud-CV/EvalAI

Issue:
Use Decorator to check permission in Disable Challenge API
Currently for the disable challenge API, there is an explicit condition added to check if the user is creator of the challenge or not (https://github.com/Cloud-CV/EvalAI/blob/master/apps/challenges/views.py#L160). This has to be removed and the `isChallengeCreator` decorator has to be added to this view. 

The decorator can be found here https://github.com/Cloud-CV/EvalAI/blob/master/apps/challenges/permissions.py#L6


Discussion:
I'll work on this.
Yeah, please go ahead. I cannot assign you right now since you are not a contributor yet. I will add you once you have made small contributions. :) 

Please let me know if you need some help. 

Resolving patch:
diff --git a/apps/challenges/permissions.py b/apps/challenges/permissions.py
--- a/apps/challenges/permissions.py
+++ b/apps/challenges/permissions.py
@@ -13,8 +13,12 @@ def has_permission(self, request, view):
 
         if request.method in permissions.SAFE_METHODS:
             return True
-        elif request.method in ['DELETE', 'PATCH', 'PUT']:
-            challenge = Challenge.objects.get(pk=request.parser_context['kwargs']['pk'])
+        elif request.method in ['DELETE', 'PATCH', 'PUT', 'POST']:
+            try:
+                challenge = Challenge.objects.get(pk=request.parser_context['kwargs']['pk'])
+            except Challenge.DoesNotExist:
+                return False
+
             if request.user.id == challenge.creator.created_by.id:
                 return True
             else:
diff --git a/apps/challenges/views.py b/apps/challenges/views.py
--- a/apps/challenges/views.py
+++ b/apps/challenges/views.py
@@ -145,26 +145,18 @@ def add_participant_team_to_challenge(request, challenge_pk, participant_team_pk
 
 @throttle_classes([UserRateThrottle])
 @api_view(['POST'])
-@permission_classes((permissions.IsAuthenticated, HasVerifiedEmail))
+@permission_classes((permissions.IsAuthenticated, HasVerifiedEmail, IsChallengeCreator))
 @authentication_classes((ExpiringTokenAuthentication,))
 def disable_challenge(request, pk):
-
     try:
         challenge = Challenge.objects.get(pk=pk)
     except Challenge.DoesNotExist:
         response_data = {'error': 'Challenge does not exist'}
         return Response(response_data, status=status.HTTP_406_NOT_ACCEPTABLE)
 
-    challenge_host_team = challenge.creator
-
-    if challenge_host_team.created_by == request.user:
-        challenge.is_disabled = True
-        challenge.save()
-        return Response(status=status.HTTP_204_NO_CONTENT)
-    else:
-        response_data = {
-            'error': 'Sorry, you do not have permission to disable this challenge'}
-        return Response(response_data, status=status.HTTP_401_UNAUTHORIZED)
+    challenge.is_disabled = True
+    challenge.save()
+    return Response(status=status.HTTP_204_NO_CONTENT)
 
 
 @throttle_classes([AnonRateThrottle])


Test patch:
diff --git a/tests/unit/challenges/test_views.py b/tests/unit/challenges/test_views.py
--- a/tests/unit/challenges/test_views.py
+++ b/tests/unit/challenges/test_views.py
@@ -443,17 +443,34 @@ def test_particular_challenge_for_disable_does_not_exist(self):
         self.url = reverse_lazy('challenges:disable_challenge',
                                 kwargs={'pk': self.challenge.pk + 2})
         response = self.client.post(self.url, {})
-        self.assertEqual(response.status_code, status.HTTP_406_NOT_ACCEPTABLE)
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 
     def test_when_user_does_not_have_permission_to_disable_particular_challenge(self):
         self.url = reverse_lazy('challenges:disable_challenge',
                                 kwargs={'pk': self.challenge2.pk})
         expected = {
-            'error': 'Sorry, you do not have permission to disable this challenge'
+            'error': 'Sorry, you are not allowed to perform this operation!'
         }
         response = self.client.post(self.url, {})
-        self.assertEqual(response.data, expected)
-        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
+        self.assertEqual(response.data.values()[0], expected['error'])
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
+
+    def test_disable_challenge_when_user_is_not_creator(self):
+        self.url = reverse_lazy('challenges:disable_challenge',
+                                kwargs={'pk': self.challenge2.pk})
+        # Now allot self.user as also a host of self.challenge_host_team1
+        self.challenge_host = ChallengeHost.objects.create(
+            user=self.user,
+            team_name=self.challenge_host_team1,
+            status=ChallengeHost.ACCEPTED,
+            permissions=ChallengeHost.ADMIN)
+
+        expected = {
+            'error': 'Sorry, you are not allowed to perform this operation!'
+        }
+        response = self.client.post(self.url, {})
+        self.assertEqual(response.data.values()[0], expected['error'])
+        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 
 
 class GetAllChallengesTest(BaseAPITestClass):