class AccountSessionView(APIView): # Create user session(Login) @method_decorator(syllable_required('username', str)) @method_decorator(syllable_required('password', str)) def post(self, request): data = request.data username = data.get('username') password = data.get('password') user = auth.authenticate(request, username=username, password=password) if user: auth.login(request, user) return Response( {'detail': 'Success', 'res': {'id': user.id}}, status=status.HTTP_201_CREATED, ) else: return Response( {'detail': 'Username or password wrong'}, status=status.HTTP_403_FORBIDDEN, ) # delete session(logout) def delete(self, request): if not request.user.is_authenticated: return Response({'detail': 'Not logged in!'}, status=status.HTTP_401_UNAUTHORIZED) auth.logout(request) return Response(status=status.HTTP_204_NO_CONTENT)
class ProblemTestdataView(APIView): @method_decorator(parameter_required('pid')) @method_decorator(view_hidden_problem_permission_check()) @method_decorator(permission_required('problem.download_testdata', raise_exception=True)) def get(self, request, pid): # Get problem testdata URL problem = get_object_or_404(Problem, pid=pid) return Response({ 'res': problem.testdata_url }, status=status.HTTP_200_OK) @method_decorator(parameter_required('pid')) @method_decorator(permission_required('problem.edit_problem', raise_exception=True)) @method_decorator(syllable_required('testdata_url', str)) def patch(self, request, pid): # Change problem testdata URL new_value = request.data['testdata_url'] problem = get_object_or_404(Problem, pid=pid) problem.testdata_url = new_value problem.testdata_last_update = timezone.now() problem.save() return Response(status=status.HTTP_204_NO_CONTENT) @method_decorator(parameter_required('pid')) @method_decorator(permission_required('problem.edit_problem', raise_exception=True)) def delete(self, request, pid): problem = get_object_or_404(Problem, pid=pid) problem.testdata_url = None problem.testdata_last_update = timezone.now() problem.save() return Response(status=status.HTTP_204_NO_CONTENT)
class AccountEmailView(APIView): @method_decorator(login_required()) def get(self, request): return Response({'res': request.user.email}) @method_decorator(login_required()) @method_decorator(captcha_required()) def post(self, request, vid=None): signer = TimestampSigner() user = request.user signature = signer.sign(user.username) signature = base64.urlsafe_b64encode(signature.encode()) signature = signature.decode() user.email_user( settings.VERIFY_EMAIL_TEMPLATE_TITLE, settings.VERIFY_EMAIL_TEMPLATE_CONTENT.format(username=user.username, signature=signature), html_message=settings.VERIFY_EMAIL_TEMPLATE_CONTENT.format(username=user.username, signature=signature), ) return Response({'detail': 'Email sent'}, status=status.HTTP_202_ACCEPTED) @method_decorator(syllable_required('email', str)) @method_decorator(email_verification_required()) @method_decorator(password_verification_required()) def patch(self, request): # change email data = request.data user = request.user user.email = data.get('email') user.email_verified = False user.save() return Response({'detail': 'Success'}, status.HTTP_204_NO_CONTENT)
class AccountPasswordView(APIView): @method_decorator(login_required()) @method_decorator(syllable_required('password', str)) @method_decorator(password_verification_required()) def patch(self, request): data = request.data user = request.user pwd = data.get('password') user.set_password(pwd) user.save() return Response({'detail': 'Success'}, status=status.HTTP_204_NO_CONTENT)
class StatusView(APIView): @method_decorator(parameter_required('sid')) def get(self, request, sid): status_element = get_object_or_404(Status, id=sid) ss = StatusSerializer(status_element) ss_data = ss.data ss_data['problem'] = status_element.problem.pid return Response({'res': ss_data}, status=status.HTTP_200_OK) @method_decorator(syllable_required('problem', int)) @method_decorator(syllable_required('code', str)) @method_decorator(syllable_required('lang', int)) @method_decorator(login_required()) def post(self, request): # Create Status(Submit Problem) data = request.data if not 1 <= data['lang'] <= 10: return Response({ 'code': 4001, 'detail': 'Unknow language', }) builder = {} builder['owner'] = request.user.id builder['lang'] = data['lang'] builder['code'] = data['code'] if data.get('lang_info') is None: builder['lang_info'] = JLang.DEFAULT_LANG_INFO[data['lang']] else: builder['lang_info'] = data.get('lang_info') builder['problem'] = get_object_or_404(Problem, pid=data['problem']).id ss = StatusSerializer(data=builder) ss.is_valid(raise_exception=True) status_element = ss.save() request.user.submit_time += 1 request.user.save() def cannot_judge(reason, state=JState.JUDGE_STATUS_CFGE): status_element.state = state status_element.additional_info = reason status_element.save() try: res = requests.post('{base_url}/api/task'.format( base_url=settings.JUDGER_PORT['base_url']), json={ 'task_id': status_element.id, 'password': settings.JUDGER_PORT.get('password'), }) res_json = res.json() except: cannot_judge('Cannot connect the Judger Port.') else: code = res_json.get('code') if code is None: cannot_judge('Judger Port response format incorrect.', JState.JUDGE_STATUS_SE) elif code == 3003 or code == 3001: cannot_judge('Judger Port refused our task.') elif code == 2001: cannot_judge('No judger connected to Judger Port.', JState.JUDGE_STATUS_SE) return Response({'id': status_element.id}, status=status.HTTP_201_CREATED)
class AccountView(APIView): # Get User Infomation Except Introduction @method_decorator(parameter_required('uid')) def get(self, request, uid): user = get_object_or_404(Account, id=uid) us = AccountSerializer(user) return Response({'res': us.data}, status=status.HTTP_200_OK) # Create New User(register an account) @method_decorator(syllable_required('username', str)) @method_decorator(syllable_required('password', str)) @method_decorator(syllable_required('email', str)) @method_decorator(captcha_required()) def post(self, request): username = request.data.get('username') password = request.data.get('password') email = request.data.get('email') if len(password) < 6: return Response({'detail': 'Password too short'}, status=status.HTTP_400_BAD_REQUEST) if not tools.isEmail(email): return Response({'detail': 'Email is not correct'}, status=status.HTTP_400_BAD_REQUEST) try: user = Account.objects.create_user(username=username, password=password, email=email) except IntegrityError: # failed, probably because username already exits return Response({'detail': 'Failed to create user.'}, status=status.HTTP_409_CONFLICT) if user: # Success user.save() # Save user return Response( {'detail': 'Success', 'res': {'id': user.id}}, status=status.HTTP_201_CREATED, ) else: # failed, probably because username already exits return Response({'detail': 'Failed to create user.'}, status=status.HTTP_409_CONFLICT) @method_decorator(parameter_required('uid')) def patch(self, request, uid): data = request.data user = get_object_or_404(Account, id=uid) if not request.user.has_perm('account.change_user'): if request.user.id != user.id: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) request_is_active = data.get('is_active') request_is_staff = data.get('is_staff') request_is_superuser = data.get('is_superuser') if request_is_active != None and request_is_active != user.is_active: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) if request_is_staff != None and request_is_staff != user.is_staff: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) if request_is_superuser != None and request_is_superuser != user.is_superuser: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) us = AccountSerializer(user, data=data, partial=True) us.is_valid(raise_exception=True) us.save() return Response(status=status.HTTP_204_NO_CONTENT)