Fakultas Ilmu Komputer UI

accounts.py 9.21 KB
Newer Older
1
import requests
2
from django.contrib.auth import authenticate, login
3
from django.contrib.auth.models import User
4
from rest_framework import viewsets, status
5
from rest_framework.generics import get_object_or_404
6
from rest_framework.decorators import list_route
7
from rest_framework.parsers import FormParser,MultiPartParser
8
from rest_framework.permissions import AllowAny
9
from rest_framework.permissions import IsAdminUser, IsAuthenticated
10
11
from rest_framework.response import Response

12
from core.lib.permissions import IsAdminOrStudent, IsAdminOrSelfOrReadOnly, IsAdminOrCompany, IsAdminOrSupervisor, \
13
    IsAdminOrSupervisorOrCompanyOrSelf
14
from core.models.accounts import Student, Company, Supervisor
15
16
from core.serializers.accounts import BasicUserSerializer, UserSerializer, StudentSerializer, CompanySerializer, \
    SupervisorSerializer, RegisterSerializer, StudentUpdateSerializer
17

18
19
20
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
21
    permission_classes = [IsAdminUser]
22

23
    @list_route(methods=['get'], permission_classes=[IsAuthenticated])
24
    def me(self, request):
25
26
27
        """
        Get current user's details
        """
28
        user = self.request.user
29
        serializer = BasicUserSerializer(user, context={"request": request})
30
31
        return Response(serializer.data)

32
33
34
35
36
37
38
    def get_permissions(self):
        if self.action == "update":
            return [IsAdminOrSelfOrReadOnly(), IsAuthenticated()]
        if self.action == "create":
            return [AllowAny()]
        return super(UserViewSet, self).get_permissions()

39

40
41
42
class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
43
44
45
46
47
    permission_classes = [IsAdminUser]

    def get_permissions(self):
        if self.action == "update":
            return [IsAdminOrSelfOrReadOnly(), IsAdminOrStudent()]
48
        if self.action == "list":
49
            return [IsAuthenticated(), IsAdminOrSupervisor()]
50
51
        if self.action == "retrieve":
            return [IsAuthenticated(), IsAdminOrSupervisorOrCompanyOrSelf()]
52
        return super(StudentViewSet, self).get_permissions()
53

54
55
56
57

class CompanyViewSet(viewsets.ModelViewSet):
    queryset = Company.objects.all()
    serializer_class = CompanySerializer
58
    permission_classes = [IsAdminOrSelfOrReadOnly, IsAdminOrCompany]
59
60
61
62
63


class SupervisorViewSet(viewsets.ModelViewSet):
    queryset = Supervisor.objects.all()
    serializer_class = SupervisorSerializer
64
    permission_classes = [IsAdminOrSelfOrReadOnly, IsAdminOrSupervisor]
65

66

67
68
class LoginViewSet(viewsets.GenericViewSet):
    permission_classes = (AllowAny, )
69
    serializer_class = UserSerializer
70
71
72
73
    queryset = User.objects.all()

    def create(self, request):
        """
74
        Authentication for user by means of logging in
75
76
        ---
        parameters:
77
78
79
80
81
            - name: body
              description: JSON object containing three strings: username, password and login-type. login-type should be either 'sso-ui' or 'company'.
              required: true
              type: string
              paramType: body
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
        """
        username = request.data.get('username')
        password = request.data.get('password')
        login_type = request.data.get('login-type')
        if username is None or password is None or login_type is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        if login_type == "sso-ui":
            r = requests.post('https://api.cs.ui.ac.id/authentication/ldap/v2/',
                              json={"username": username, "password": password})
            resp = r.json()
            if resp.get('state') != 0:
                # create user
                name = resp.get('nama').split(" ")
                first_name = name[0]
                name.pop(0)
                last_name = " ".join(name)
                user, created = User.objects.get_or_create(
                    username=username,
100
101
102
103
104
                    defaults={
                        'email' : username + "@ui.ac.id",
                        'first_name' : first_name,
                        'last_name' : last_name
                    }
105
106
107
108
109
110
                )
                user.set_password(password)
                user.save()
                login(request, user)
                if created:
                    if resp.get('nama_role') == "mahasiswa":
111
112
                        student_detail = requests.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/{}/'.format(resp.get("kodeidentitas")))
                        resp_student_detail = student_detail.json()
113
114
115
                        student = Student.objects.create(
                            user=user,
                            npm=resp.get("kodeidentitas"),
116
117
118
119
                            birth_place=resp_student_detail.get('kota_lahir'),
                            birth_date=resp_student_detail.get('tgl_lahir'),
                            major=resp_student_detail.get('program')[0].get('nm_org'),
                            batch=resp_student_detail.get('program')[0].get('angkatan')
120
121
122
123
124
125
126
127
                        )
                        student.save()
                    else:
                        supervisor = Supervisor.objects.create(
                            user=user,
                            nip=resp.get("kodeidentitas")
                        )
                        supervisor.save()
128
                    serializer = UserSerializer(user, context={'request': request})
129
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
130
                serializer = UserSerializer(user, context={'request': request})
131
                return Response(serializer.data, status=status.HTTP_200_OK)
132
133
            else:
                return Response(status=status.HTTP_401_UNAUTHORIZED)
134
        elif login_type == "company":
135
136
137
            user = authenticate(username = username, password = password)
            if user is not None:
                login(request, user)
138
                serializer = UserSerializer(user, context={'request': request})
139
                return Response(serializer.data, status=status.HTTP_200_OK)
140
141
            else:
                return Response(status=status.HTTP_401_UNAUTHORIZED)
142
143
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)
144
145
146
147
148
149
150
151
152


class CompanyRegisterViewSet(viewsets.GenericViewSet):
    permission_classes = (AllowAny,)
    serializer_class = RegisterSerializer
    queryset = Company.objects.all()
    parser_classes = (MultiPartParser, FormParser,)

    def create(self, request):
153
154
155
156
157
158
159
160
161
        """
        Create a new company user
        ---
        parameters:
            - name: username
              description: username of the new account 
              required: true
              type: string
            - name: password
Zamil Majdy's avatar
Zamil Majdy committed
162
              description: password of the new account
163
164
165
              required: true
              type: string
            - name: email
Zamil Majdy's avatar
Zamil Majdy committed
166
              description: email address of the new account
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
              required: true
              type: string
            - name: name
              description: the new company's name
              required: true
              type: string
            - name: description
              description: description of the new company
              required: true
              type: string
            - name: logo
              description: logo of the new company
              required: false
              type: image
            - name: address
Zamil Majdy's avatar
Zamil Majdy committed
182
              description: address of the new account
183
184
185
              required: false
              type: string
        """
186
187
188
189
        data = {}
        for attr in ['password', 'email', 'name', 'description', 'logo', 'address']:
            data[attr] = request.data.get(attr)
            if data[attr] is None:
190
                return Response({'error': attr+' is required'}, status=status.HTTP_400_BAD_REQUEST)
191
192
193
194
195
196
197
198
199
200
201
202
203
204

        user, created = User.objects.get_or_create(
            username=data['email'],
            email=data['email'],
            first_name=data['name'],
            last_name=""
        )
        if created:
            user.set_password(data['password'])
            company = Company.objects.create(
                user=user,
                description=data['description'],
                logo=data['logo'],
                address=data['address']
205
            )
206
207
208
            user.save()
            company.save()
            serializer = self.serializer_class(user, context={'request': request})
209
            login(request, user)
210
211
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
            return Response({'error': 'Company with email '+data['email']+' already exist'}, status=status.HTTP_409_CONFLICT)


class StudentProfileViewSet(viewsets.GenericViewSet):
    queryset = Student.objects.all()
    permission_classes = [IsAdminOrStudent]
    serializer_class = StudentUpdateSerializer
    parser_classes = (MultiPartParser, FormParser,)

    def partial_update(self, request, pk=None):
        user = self.get_object()
        serializer = self.serializer_class(user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)