factory/apps/auth1/views.py

220 lines
6.3 KiB
Python
Executable File

from rest_framework.exceptions import ParseError
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import authenticate, login, logout
from rest_framework.generics import CreateAPIView
from rest_framework.permissions import IsAuthenticated
from apps.auth1.errors import USERNAME_OR_PASSWORD_WRONG
from rest_framework.exceptions import ParseError
import requests
import json
from django.conf import settings
from rest_framework_simplejwt.tokens import RefreshToken
from django.core.cache import cache
from apps.auth1.services import check_phone_code
from apps.utils.sms import send_sms
from apps.utils.tools import rannum
from apps.utils.wxmp import wxmpClient
from apps.utils.wx import wxClient
from django.contrib.auth.hashers import make_password
from django.db.models import Q
from apps.auth1.serializers import CodeLoginSerializer, LoginSerializer, PwResetSerializer, SecretLoginSerializer, SendCodeSerializer, WxCodeSerializer
from apps.system.models import User
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
# Create your views here.
def get_tokens_for_user(user: User):
refresh = RefreshToken.for_user(user)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
class TokenBlackView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
"""
Token拉黑
Token拉黑
"""
return Response(status=status.HTTP_200_OK)
class LoginView(CreateAPIView):
"""
Session登录
账户密码Session登录
"""
authentication_classes = []
permission_classes = []
serializer_class = LoginSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
user = authenticate(username=vdata.get('username'),
password=vdata.get('password'))
if user is not None:
login(request, user)
return Response(status=201)
raise ParseError(**USERNAME_OR_PASSWORD_WRONG)
class LogoutView(APIView):
authentication_classes = []
permission_classes = []
def post(self, request, *args, **kwargs):
"""
退出登录
退出登录
"""
logout(request)
return Response()
class WxmpLogin(CreateAPIView):
"""微信小程序自动登录
微信小程序自动登录
"""
authentication_classes = []
permission_classes = []
serializer_class = WxCodeSerializer
def post(self, request):
code = request.data['code']
info = wxmpClient.get_basic_info(code=code)
openid = info['openid']
session_key = info['session_key']
try:
user = User.objects.get(wxmp_openid=openid, is_active=True)
ret = get_tokens_for_user(user)
ret['wxmp_session_key'] = session_key
ret['wxmp_openid'] = openid
cache.set(code, ret, 60*5)
return Response(ret)
except Exception:
return Response({'wxmp_openid': openid, 'wxmp_session_key': session_key}, status=400)
class WxLogin(CreateAPIView):
"""微信公众号授权登录
微信公众号授权登录
"""
authentication_classes = []
permission_classes = []
serializer_class = WxCodeSerializer
def post(self, request):
code = request.data['code']
info = wxClient.get_basic_info(code=code)
openid = info['openid']
access = info['access_token']
try:
user = User.objects.get(wx_openid=openid, is_active=True)
ret = get_tokens_for_user(user)
ret['wx_token'] = access
ret['wx_openid'] = openid
cache.set(code, ret, 60*5)
return Response(ret)
except Exception:
return Response({'wx_openid': openid, 'wx_token': access}, status=400)
class SendCode(CreateAPIView):
authentication_classes = []
permission_classes = []
serializer_class = SendCodeSerializer
def post(self, request):
"""短信验证码发送
短信验证码发送
"""
phone = request.data['phone']
code = rannum(6)
is_ok, _ = send_sms(phone, 505, {'code': code})
cache.set(phone, code, 60*5)
if is_ok:
return Response()
raise ParseError('短信发送失败,请确认手机号')
class CodeLogin(CreateAPIView):
"""手机验证码登录
手机验证码登录
"""
authentication_classes = []
permission_classes = []
serializer_class = CodeLoginSerializer
def post(self, request):
phone = request.data['phone']
code = request.data['code']
check_phone_code(phone, code)
user = User.objects.filter(phone=phone).first()
if user:
ret = get_tokens_for_user(user)
return Response(ret)
raise ParseError('账户不存在或已禁用')
class SecretLogin(CreateAPIView):
"""App端密钥登录
App端密钥登录
"""
authentication_classes = []
permission_classes = []
serializer_class = SecretLoginSerializer
def post(self, request):
username = request.data['username']
secret = request.data['secret']
user = User.objects.filter(Q(username=username) | Q(phone=username) | Q(
employee__id_number=username)).filter(secret=secret).first()
if user:
ret = get_tokens_for_user(user)
return Response(ret)
raise ParseError('登录失败')
class PwResetView(CreateAPIView):
"""重置密码
重置密码
"""
authentication_classes = []
permission_classes = []
serializer_class = PwResetSerializer
def post(self, request):
sr = PwResetSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
check_phone_code(vdata['phone'], vdata['code'])
user = User.objects.filter(phone=vdata['phone']).first()
if user:
user.password = make_password(vdata['password'])
user.save()
return Response()
raise ParseError('账户不存在或已禁用')