From bd55bc73fa01e1422c575424f7b20e6335714a00 Mon Sep 17 00:00:00 2001
From: Joshua Casey <joshua.caseyd@gmail.com>
Date: Mon, 24 Apr 2017 17:01:17 +0700
Subject: [PATCH] [#140655219] #24 #26 Changed student serializer and view set
 to grant company access and revised tests, also renamed show_resume to
 show_transcript

---
 core/lib/permissions.py                    | 28 +++++++++++++++++++
 core/migrations/0009_auto_20170424_0909.py | 20 ++++++++++++++
 core/models/accounts.py                    |  2 +-
 core/serializers/accounts.py               |  2 +-
 core/tests/test_accounts.py                |  8 ++++++
 core/tests/test_vacancies.py               | 32 ++++++++++++++++++++++
 core/views/accounts.py                     |  7 ++++-
 7 files changed, 96 insertions(+), 3 deletions(-)
 create mode 100644 core/migrations/0009_auto_20170424_0909.py

diff --git a/core/lib/permissions.py b/core/lib/permissions.py
index 7dbf5205..71e53560 100644
--- a/core/lib/permissions.py
+++ b/core/lib/permissions.py
@@ -18,6 +18,10 @@ def is_admin_or_supervisor(user):
     return user.is_superuser or hasattr(user, "supervisor")
 
 
+def is_admin_or_supervisor_or_company(user):
+    return user.is_superuser or hasattr(user, "supervisor") or hasattr(user, "company")
+
+
 class IsAdminOrSelfOrReadOnly(permissions.BasePermission):
     def has_object_permission(self, request, view, obj):
         if request.method in permissions.SAFE_METHODS:
@@ -94,3 +98,27 @@ class IsAdminOrCompany(permissions.BasePermission):
             )
 
         return hasattr(user, "company") and user.company == company
+
+
+class IsAdminOrSupervisorOrCompany(permissions.BasePermission):
+    def has_permission(self, request, view):
+        return is_admin_or_supervisor_or_company(request.user)
+
+
+class IsAdminOrSupervisorOrCompanyOrSelf(permissions.IsAuthenticated):
+    def has_object_permission(self, request, view, obj):
+        user = request.user
+        if user.is_superuser or hasattr(user, "company") or hasattr(user, "supervisor"):
+            return True
+        if hasattr(user, "student"):
+            if isinstance(obj, Student):
+                student = obj
+            elif hasattr(obj, "student"):
+                student = obj.student
+            else:
+                raise APIException(
+                    "Checking student permission on object {} not associated with Student"
+                        .format(type(obj.__name__))
+                )
+            return hasattr(user, "student") and user.student == student
+        return False
diff --git a/core/migrations/0009_auto_20170424_0909.py b/core/migrations/0009_auto_20170424_0909.py
new file mode 100644
index 00000000..151a05cf
--- /dev/null
+++ b/core/migrations/0009_auto_20170424_0909.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-04-24 09:09
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0008_auto_20170424_0725'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='student',
+            old_name='show_resume',
+            new_name='show_transcript',
+        ),
+    ]
diff --git a/core/models/accounts.py b/core/models/accounts.py
index afb37d7c..d371652d 100644
--- a/core/models/accounts.py
+++ b/core/models/accounts.py
@@ -55,7 +55,7 @@ class Student(models.Model):
     birth_date = models.DateField(blank=True, null=True)
     major = models.CharField(max_length=30, blank=True, null=True)
     batch = models.CharField(max_length=4, blank=True, null=True)
-    show_resume = models.BooleanField(default=False)
+    show_transcript = models.BooleanField(default=False)
 
     @property
     def name(self):
diff --git a/core/serializers/accounts.py b/core/serializers/accounts.py
index 986f4c4f..195855a7 100644
--- a/core/serializers/accounts.py
+++ b/core/serializers/accounts.py
@@ -16,7 +16,7 @@ class StudentSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Student
-        fields = '__all__'
+        fields = ['id', 'name', 'user', 'npm', 'resume', 'phone_number', 'birth_place', 'birth_date', 'major', 'batch', 'show_transcript']
 
 
 class CompanySerializer(serializers.ModelSerializer):
diff --git a/core/tests/test_accounts.py b/core/tests/test_accounts.py
index fe6aa42c..5fe32fb0 100644
--- a/core/tests/test_accounts.py
+++ b/core/tests/test_accounts.py
@@ -17,6 +17,14 @@ class LoginTests(APITestCase):
                 "kodeidentitas": "1234567890",
                 "nama_role": "mahasiswa"
         }, status_code=200)
+        m.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/1234567890/', json={
+                "kota_lahir": "kota_kota",
+                "tgl_lahir": "2017-12-31",
+                "program": [{
+                    "nm_org" : "Ilmu Informasi",
+                    "angkatan" : "2017"
+                }]
+        }, status_code=200)
 
         url = '/api/login/'
 
diff --git a/core/tests/test_vacancies.py b/core/tests/test_vacancies.py
index 518a0757..92ef204c 100644
--- a/core/tests/test_vacancies.py
+++ b/core/tests/test_vacancies.py
@@ -18,6 +18,14 @@ class ApplicationTests(APITestCase):
             "kodeidentitas": "1234567890",
             "nama_role": "mahasiswa"
         }, status_code=200)
+        m.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/1234567890/', json={
+            "kota_lahir": "kota_kota",
+            "tgl_lahir": "2017-12-31",
+            "program": [{
+                "nm_org": "Ilmu Informasi",
+                "angkatan": "2017"
+            }]
+        }, status_code=200)
 
         url = '/api/login/'
 
@@ -40,6 +48,14 @@ class ApplicationTests(APITestCase):
             "kodeidentitas": "1234567890",
             "nama_role": "mahasiswa"
         }, status_code=200)
+        m.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/1234567890/', json={
+            "kota_lahir": "kota_kota",
+            "tgl_lahir": "2017-12-31",
+            "program": [{
+                "nm_org": "Ilmu Informasi",
+                "angkatan": "2017"
+            }]
+        }, status_code=200)
 
         url = '/api/login/'
 
@@ -71,6 +87,14 @@ class BookmarkApplicationTests(APITestCase):
             "kodeidentitas": "1234567890",
             "nama_role": "mahasiswa"
         }, status_code=200)
+        m.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/1234567890/', json={
+            "kota_lahir": "kota_kota",
+            "tgl_lahir": "2017-12-31",
+            "program": [{
+                "nm_org": "Ilmu Informasi",
+                "angkatan": "2017"
+            }]
+        }, status_code=200)
 
         url = '/api/login/'
 
@@ -93,6 +117,14 @@ class BookmarkApplicationTests(APITestCase):
             "kodeidentitas": "1234567890",
             "nama_role": "mahasiswa"
         }, status_code=200)
+        m.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/1234567890/', json={
+            "kota_lahir": "kota_kota",
+            "tgl_lahir": "2017-12-31",
+            "program": [{
+                "nm_org": "Ilmu Informasi",
+                "angkatan": "2017"
+            }]
+        }, status_code=200)
 
         url = '/api/login/'
 
diff --git a/core/views/accounts.py b/core/views/accounts.py
index dfb24c3e..05c3f7de 100644
--- a/core/views/accounts.py
+++ b/core/views/accounts.py
@@ -9,7 +9,8 @@ from rest_framework.permissions import IsAdminUser, IsAuthenticated
 from rest_framework.response import Response
 from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_409_CONFLICT
 
-from core.lib.permissions import IsAdminOrStudent, IsAdminOrSelfOrReadOnly, IsAdminOrCompany, IsAdminOrSupervisor
+from core.lib.permissions import IsAdminOrStudent, IsAdminOrSelfOrReadOnly, IsAdminOrCompany, IsAdminOrSupervisor, \
+    IsAdminOrSupervisorOrCompany, IsAdminOrSupervisorOrCompanyOrSelf
 from core.models.accounts import Student, Company, Supervisor
 from core.serializers.accounts import UserSerializer, StudentSerializer, CompanySerializer, SupervisorSerializer, \
     LoginSerializer, RegisterSerializer
@@ -45,6 +46,10 @@ class StudentViewSet(viewsets.ModelViewSet):
     def get_permissions(self):
         if self.action == "update":
             return [IsAdminOrSelfOrReadOnly(), IsAdminOrStudent()]
+        if self.action == "list":
+            return [IsAuthenticated(), IsAdminOrSupervisorOrCompany()]
+        if self.action == "retrieve":
+            return [IsAuthenticated(), IsAdminOrSupervisorOrCompanyOrSelf()]
         return super(StudentViewSet, self).get_permissions()
 
 
-- 
GitLab