Fakultas Ilmu Komputer UI

accounts.py 9.24 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.decorators import list_route, detail_route
6
from rest_framework.parsers import FormParser,MultiPartParser
7
from rest_framework.permissions import AllowAny
8
from rest_framework.permissions import IsAdminUser, IsAuthenticated
9
10
from rest_framework.response import Response

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

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
58
59
60
61
62
63
64
65
66
67
68
    @detail_route(methods=['patch'], permission_classes=[IsAdminOrStudent],
                  serializer_class=StudentUpdateSerializer, parser_classes=(MultiPartParser, FormParser,))
    def profile(self, request, pk=None):
        """
        Update student {student_id}'s profile information
        ---
        """
        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)

69
70
71
72

class CompanyViewSet(viewsets.ModelViewSet):
    queryset = Company.objects.all()
    serializer_class = CompanySerializer
73
    permission_classes = [IsAdminOrSelfOrReadOnly, IsAdminOrCompany]
74
    filter_fields = ('status',)
75
76
77
78
79


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

82

83
84
class LoginViewSet(viewsets.GenericViewSet):
    permission_classes = (AllowAny, )
85
    serializer_class = UserSerializer
86
87
88
89
    queryset = User.objects.all()

    def create(self, request):
        """
90
        Authentication for user by means of logging in
91
92
        ---
        parameters:
93
94
95
96
97
            - 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
        """
        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,
116
117
118
119
120
                    defaults={
                        'email' : username + "@ui.ac.id",
                        'first_name' : first_name,
                        'last_name' : last_name
                    }
121
122
123
124
125
126
                )
                user.set_password(password)
                user.save()
                login(request, user)
                if created:
                    if resp.get('nama_role') == "mahasiswa":
127
128
                        student_detail = requests.get('https://api.cs.ui.ac.id/siakngcs/mahasiswa/{}/'.format(resp.get("kodeidentitas")))
                        resp_student_detail = student_detail.json()
129
130
131
                        student = Student.objects.create(
                            user=user,
                            npm=resp.get("kodeidentitas"),
132
133
134
135
                            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')
136
137
138
139
140
141
142
143
                        )
                        student.save()
                    else:
                        supervisor = Supervisor.objects.create(
                            user=user,
                            nip=resp.get("kodeidentitas")
                        )
                        supervisor.save()
144
                    serializer = UserSerializer(user, context={'request': request})
145
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
146
                serializer = UserSerializer(user, context={'request': request})
147
                return Response(serializer.data, status=status.HTTP_200_OK)
148
149
            else:
                return Response(status=status.HTTP_401_UNAUTHORIZED)
150
        elif login_type == "company":
151
152
153
            user = authenticate(username = username, password = password)
            if user is not None:
                login(request, user)
154
                serializer = UserSerializer(user, context={'request': request})
155
                return Response(serializer.data, status=status.HTTP_200_OK)
156
157
            else:
                return Response(status=status.HTTP_401_UNAUTHORIZED)
158
159
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST)
160
161
162
163
164
165
166
167
168


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

    def create(self, request):
169
170
171
172
173
174
175
176
177
        """
        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
178
              description: password of the new account
179
180
181
              required: true
              type: string
            - name: email
Zamil Majdy's avatar
Zamil Majdy committed
182
              description: email address of the new account
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
              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
198
              description: address of the new account
199
200
201
              required: false
              type: string
        """
202
203
204
205
        data = {}
        for attr in ['password', 'email', 'name', 'description', 'logo', 'address']:
            data[attr] = request.data.get(attr)
            if data[attr] is None:
206
                return Response({'error': attr+' is required'}, status=status.HTTP_400_BAD_REQUEST)
207
208
209
210
211
212
213
214
215
216
217
218
219
220

        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']
221
            )
222
223
224
            user.save()
            company.save()
            serializer = self.serializer_class(user, context={'request': request})
225
            login(request, user)
226
227
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
228
            return Response({'error': 'Company with email '+data['email']+' already exist'}, status=status.HTTP_409_CONFLICT)