|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
import time
|
|
|
|
|
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from rest_framework.generics import RetrieveAPIView, CreateAPIView
|
|
|
|
from rest_framework.response import Response
|
|
|
|
from rest_framework import status
|
|
|
|
|
|
|
|
from common.permissions import IsValidUser
|
|
|
|
from ..const import ConfirmType
|
|
|
|
from ..serializers import ConfirmSerializer
|
|
|
|
|
|
|
|
|
|
|
|
class ConfirmApi(RetrieveAPIView, CreateAPIView):
|
|
|
|
permission_classes = (IsValidUser,)
|
|
|
|
serializer_class = ConfirmSerializer
|
|
|
|
|
|
|
|
def get_confirm_backend(self, confirm_type):
|
|
|
|
backend_classes = ConfirmType.get_can_confirm_backend_classes(confirm_type)
|
|
|
|
if not backend_classes:
|
|
|
|
return
|
|
|
|
for backend_cls in backend_classes:
|
|
|
|
backend = backend_cls(self.request.user, self.request)
|
|
|
|
if not backend.check():
|
|
|
|
continue
|
|
|
|
return backend
|
|
|
|
|
|
|
|
def retrieve(self, request, *args, **kwargs):
|
|
|
|
confirm_type = request.query_params.get('confirm_type')
|
|
|
|
backend = self.get_confirm_backend(confirm_type)
|
|
|
|
if backend is None:
|
|
|
|
msg = _('This action require verify your MFA')
|
|
|
|
return Response(data={'error': msg}, status=status.HTTP_404_NOT_FOUND)
|
|
|
|
|
|
|
|
data = {
|
|
|
|
'confirm_type': backend.name,
|
|
|
|
'content': backend.content,
|
|
|
|
}
|
|
|
|
return Response(data=data)
|
|
|
|
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
|
|
serializer = self.get_serializer(data=request.data)
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
validated_data = serializer.validated_data
|
|
|
|
|
|
|
|
confirm_type = validated_data.get('confirm_type')
|
|
|
|
mfa_type = validated_data.get('mfa_type')
|
|
|
|
secret_key = validated_data.get('secret_key')
|
|
|
|
|
|
|
|
backend = self.get_confirm_backend(confirm_type)
|
|
|
|
ok, msg = backend.authenticate(secret_key, mfa_type)
|
|
|
|
if ok:
|
|
|
|
request.session['CONFIRM_LEVEL'] = ConfirmType.values.index(confirm_type) + 1
|
|
|
|
request.session['CONFIRM_TIME'] = int(time.time())
|
|
|
|
return Response('ok')
|
|
|
|
return Response({'error': msg}, status=400)
|