Fakultas Ilmu Komputer UI

accounts.py 8.53 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
6
from rest_framework.parsers import FormParser,MultiPartParser
7
from rest_framework.permissions import AllowAny
8
from rest_framework.permissions import IsAdminUser, IsAuthenticated
9
from rest_framework.response import Response
10
from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_409_CONFLICT
11

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

18

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

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

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

40

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

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

55
56
57
58

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


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

67

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

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


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

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

        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']
204
            )
205
206
207
            user.save()
            company.save()
            serializer = self.serializer_class(user, context={'request': request})
208
            login(request, user)
209
210
211
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response({'error': 'Company with email '+data['email']+' already exist'}, status=HTTP_409_CONFLICT)