From 1bb9074c982d1a079056b10b8aba1916cd71cdb6 Mon Sep 17 00:00:00 2001
From: "robinwilliam.hundt" <robinwilliam.hundt@stud.uni-goettingen.de>
Date: Sat, 4 Nov 2017 17:36:00 +0100
Subject: [PATCH] Simple Serializer for Student, Submssion and Feedback

---
 backend/core/custom_annotations.py |  2 +-
 backend/core/permissions.py        | 18 +++++++
 backend/core/serializers.py        | 87 +++++-------------------------
 backend/core/urls.py               |  8 ++-
 backend/core/views/__init__.py     |  1 +
 backend/core/views/api.py          | 24 +++++++++
 backend/grady/settings/default.py  |  7 +++
 backend/grady/urls.py              |  5 ++
 8 files changed, 76 insertions(+), 76 deletions(-)
 create mode 100644 backend/core/permissions.py
 create mode 100644 backend/core/views/api.py

diff --git a/backend/core/custom_annotations.py b/backend/core/custom_annotations.py
index 5296b703..0b1463a5 100644
--- a/backend/core/custom_annotations.py
+++ b/backend/core/custom_annotations.py
@@ -10,7 +10,7 @@ Currently the following options are available
 
 
 def in_groups(user, group_list):
-    return bool(user.groups.filter(name__in=group_list)) or user.is_superuser
+    return bool(user.groups.filter(name__in=group_list))  # or user.is_superuser
 
 
 def group_required(*group_names):
diff --git a/backend/core/permissions.py b/backend/core/permissions.py
new file mode 100644
index 00000000..78a03977
--- /dev/null
+++ b/backend/core/permissions.py
@@ -0,0 +1,18 @@
+from rest_framework import permissions
+from core.custom_annotations import in_groups
+
+from core.models import Student, Submission, Feedback
+
+
+class StudentRequestOwnData(permissions.BasePermission):
+    def has_object_permission(self, request, view, obj):
+        if in_groups(request.user, ['Students']):
+            student = request.user.student
+            if isinstance(obj, Student):
+                return student == obj
+            elif isinstance(obj, Submission):
+                return student == obj.student
+            elif isinstance(obj, Feedback):
+                return student == obj.of_submission.student
+
+        return False
diff --git a/backend/core/serializers.py b/backend/core/serializers.py
index 8ff9df31..40e6f2c4 100644
--- a/backend/core/serializers.py
+++ b/backend/core/serializers.py
@@ -1,91 +1,30 @@
-
-import hashlib
-
 from django.contrib.auth.models import User
-from rest_framework import serializers
-
-from core.models import Feedback, Student, Submission, SubmissionType
-
-
-class SubmissionTypeSerializer(serializers.ModelSerializer):
-
-    def create(self, validated_data):
-        return SubmissionType(**validated_data)
-
-    class Meta:
-        model = SubmissionType
-        exclude = ('slug',)
 
+from rest_framework import serializers
+from core.models import Student, Submission, Feedback
 
-class CreateStudentSerializer(serializers.ModelSerializer):
 
-    username = serializers.CharField(source='user.username')
-    email    = serializers.CharField(source='user.email')
-    password = serializers.CharField(source='user.password')
+class StudentSerializer(serializers.ModelSerializer):
+    user = serializers.ReadOnlyField(source='user.username')
 
     class Meta:
         model = Student
-        fields = ('username', 'name', 'email', 'matrikel_no', 'password')
-        extra_kwargs = {'password': {'write_only': True}}
-
-    def to_representation(self, obj):
-        return {
-            'username'      : obj.user.username,
-            'name'          : obj.name,
-            'matrikel_no'   : obj.matrikel_no,
-        }
+        fields = ('name', 'user', 'exam', 'submissions')
 
-    def create(self, validated_data):
-        user = User(
-            email=validated_data['email'],
-            username=validated_data['username']
-        )
-        user.set_password(validated_data['password'])
-
-        return Student.objects.create(
-            name=validated_data['name'],
-            matrikel_no=validated_data['matrikel_no'],
-            user=user,
-        )
-
-
-class CreateSubmissionSerializer(serializers.ModelSerializer):
-
-    type = serializers.SlugRelatedField(
-        queryset=SubmissionType.objects.all(),
-        slug_field='name'
-    )
-
-    student = serializers.SlugRelatedField(
-        queryset=User.objects.all(),
-        slug_field='username'
-    )
 
+class SubmissionSerializer(serializers.ModelSerializer):
     class Meta:
         model = Submission
-        fields = ('type', 'text', 'pre_corrections', 'student')
+        fields = ('seen_by_student', 'text', 'type', 'student', 'feedback')
 
-    def create(self, validated_data):
-        validated_data['student'] = validated_data['student'].student
-        return Submission.objects.create(**validated_data)
 
+class FeedbackSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Feedback
+        fields = ('text', 'score')
 
-class AnonymousFeedbackSerializer(serializers.ModelSerializer):
-
-    def to_representation(self, obj):
-        return {
-            'feedback'  : obj.text,
-            'score'     : obj.score,
-            'tutor'     : obj.of_tutor.username,
-            'student'   : hashlib.sha256(
-                obj.of_submission.student.matrikel_no.encode() +
-                obj.of_submission.student.name.encode()).hexdigest(),
-            'code'      : obj.of_submission.text
-        }
-
-    def create(self, validated_data):
-        return NotImplemented
 
+class UserSerializer(serializers.ModelSerializer):
     class Meta:
-        model = Feedback
+        model = User
         fields = ()
diff --git a/backend/core/urls.py b/backend/core/urls.py
index b79a568e..8dab3821 100644
--- a/backend/core/urls.py
+++ b/backend/core/urls.py
@@ -3,6 +3,8 @@ from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 
 from core import views
 
+
+
 urlpatterns = [
     url(r'^$', views.IndexView.as_view(), name='index'),
     url(r'^login/$', views.Login.as_view(), name='login'),
@@ -22,7 +24,11 @@ urlpatterns = [
 
     url(r'^s/submission/view/(?P<slug>\w+)/$', views.StudentSubmissionView.as_view(), name='StudentSubmissionView'),
 
-    url(r'^csv/$', views.export_csv, name='export')
+    url(r'^csv/$', views.export_csv, name='export'),
+
+    url(r'^api/student/(?P<pk>[0-9]+)$', views.StudentApiView.as_view()),
+    url(r'^api/submission/(?P<pk>[0-9]+)$', views.SubmissionApiView.as_view()),
+    url(r'^api/feedback/(?P<pk>[0-9]+)$', views.FeedbackApiView.as_view()),
 ]
 
 urlpatterns += staticfiles_urlpatterns()
diff --git a/backend/core/views/__init__.py b/backend/core/views/__init__.py
index 67868d83..a38f0ce2 100644
--- a/backend/core/views/__init__.py
+++ b/backend/core/views/__init__.py
@@ -7,3 +7,4 @@ from .user_startpages import *
 from .index import *
 from .export_csv import *
 
+from .api import *
diff --git a/backend/core/views/api.py b/backend/core/views/api.py
new file mode 100644
index 00000000..7722ebc4
--- /dev/null
+++ b/backend/core/views/api.py
@@ -0,0 +1,24 @@
+
+from core.models import Student, Submission, Feedback
+from core.serializers import SubmissionSerializer, StudentSerializer, FeedbackSerializer
+from core.permissions import StudentRequestOwnData
+from rest_framework.generics import RetrieveAPIView
+
+
+class StudentApiView(RetrieveAPIView):
+    permission_classes = (StudentRequestOwnData, )
+    queryset = Student.objects.all()
+    serializer_class = StudentSerializer
+
+
+class SubmissionApiView(RetrieveAPIView):
+    permission_classes = (StudentRequestOwnData, )
+    queryset = Submission.objects.all()
+    serializer_class = SubmissionSerializer
+
+
+class FeedbackApiView(RetrieveAPIView):
+    permission_classes = (StudentRequestOwnData, )
+    queryset = Feedback.objects.all()
+    serializer_class = FeedbackSerializer
+
diff --git a/backend/grady/settings/default.py b/backend/grady/settings/default.py
index d9b710ae..c7b4c1a5 100644
--- a/backend/grady/settings/default.py
+++ b/backend/grady/settings/default.py
@@ -40,6 +40,7 @@ INSTALLED_APPS = [
     'django.contrib.staticfiles',
     'django_extensions',
     'core',
+    'rest_framework',
 ]
 
 MIDDLEWARE = [
@@ -70,6 +71,12 @@ TEMPLATES = [
     },
 ]
 
+REST_FRAMEWORK = {
+    'DEFAULT_PERMISSION_CLASSES': (
+        'rest_framework.permissions.IsAuthenticated',
+    )
+}
+
 WSGI_APPLICATION = 'grady.wsgi.application'
 
 
diff --git a/backend/grady/urls.py b/backend/grady/urls.py
index ff39cb40..9acdd9b0 100644
--- a/backend/grady/urls.py
+++ b/backend/grady/urls.py
@@ -20,3 +20,8 @@ urlpatterns = [
     url(r'^admin/', admin.site.urls),
     url(r'^', include('core.urls'))
 ]
+
+urlpatterns += [
+    url(r'^api-auth/', include('rest_framework.urls',
+                               namespace='rest_framework')),
+]
-- 
GitLab