#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved. @AUTHOR: ASJRD018 @NAME: AnsjerFormal @software: PyCharm @DATE: 2018/9/11 15:08 @Version: python3.6 @MODIFY DECORD:ansjer dev @file: UserController.py @Contact: chanjunkai@163.com """ from django.contrib import auth from django.core import serializers from django.utils.timezone import utc import traceback from django.views.decorators.csrf import csrf_exempt from django.views.generic import TemplateView, View from django.utils.decorators import method_decorator from django.core.files.storage import FileSystemStorage from django.http import HttpResponseRedirect from django.contrib.auth.hashers import make_password, check_password # 对密码加密模块 from Ansjer import settings as api_settings from Object.AWS.SesClassObject import SesClassObject from Model.models import Auth_Captcha, AuthToken_Token, Role from Controller.CheckUserData import DataValid, date_handler, RandomStr, TokenLink from Service.ModelService import ModelService from Service.MiscellService import MiscellService from django.utils import timezone from Ansjer.config import * from Service.CommonService import CommonService from Service.TemplateService import TemplateService from ratelimit.decorators import ratelimit from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject from Object.RedisObject import RedisObject from Model.models import Device_User import simplejson as json # 获取验证码 class authCodeView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(authCodeView, self).dispatch(*args, **kwargs) @ratelimit(key='ip', rate='2/m') def post(self, request, *args, **kwargs): request.encoding = 'utf-8' lang = request.POST.get('language', None) response = ResponseObject(lang) was_limited = getattr(request, 'limited', False) if was_limited is True: return response.json(5) username = request.POST.get('userName', None) useremail = request.POST.get('userEmail', None) return self.ValidationError(username, useremail, response) # @ratelimit(key='ip', rate='2/m') def get(self, request, *args, **kwargs): # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete() request.encoding = 'utf-8' lang = request.GET.get('language', None) response = ResponseObject(lang) was_limited = getattr(request, 'limited', False) if was_limited is True: return response.json(5) username = request.GET.get('userName', None) email = request.GET.get('userEmail', None) return self.ValidationError(username, email, response) def ValidationError(self, username, email, response): if username: username = username.strip() return self.phoneCode(username, response) elif email: email = email.strip() return self.emailCode(email, response) else: return response.json(800) def phoneCode(self, phone, response): dataValid = DataValid() if dataValid.mobile_validate(phone): reds = RedisObject() identifyingCode = reds.get_data(key=phone + '_identifyingCode') if identifyingCode is False: user_qs = Device_User.objects.filter(username=phone) if user_qs.exists(): return response.json(101) else: identifyingCode = RandomStr(6, True) if reds.set_data(key=phone + '_identifyingCode', val=identifyingCode, expire=600): return response.json(0, {'identifyingCode': identifyingCode}) else: return response.json(10, '生成缓存系统错误') else: return response.json(0, {'identifyingCode': identifyingCode}) else: return response.json(107) def emailCode(self, email, response): dataValid = DataValid() if dataValid.email_validate(email): reds = RedisObject() identifyingCode = reds.get_data(key=email + '_identifyingCode') if identifyingCode is False: user_qs = Device_User.objects.filter(username=email) email_qs = Device_User.objects.filter(userEmail=email) if user_qs.exists(): return response.json(103) elif email_qs.exists(): return response.json(103) else: identifyingCode = RandomStr(6, True) if reds.set_data(key=email + '_identifyingCode', val=identifyingCode, expire=AuthCode_Expire): send_data = TemplateService.email_message(type='register_code', language=response.lang) ses = SesClassObject() send_res = ses.send_email( send_address_list=[email], subject=send_data['title'], body=send_data['body'].replace("{username}", email).replace("{captcha}", str(identifyingCode)) ) if send_res: reds.set_data(key=email + '_registerCode', val=identifyingCode, expire=AuthCode_Expire) return response.json(0, {'identifyingCode': identifyingCode}) else: return response.json(44) else: return response.json(10, '生成缓存系统错误') else: return response.json(0, {'identifyingCode': identifyingCode}) else: return response.json(107) # 验证码注册 class registerView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(registerView, self).dispatch(*args, **kwargs) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST return self.validates(request_dict) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET return self.validates(request_dict) def validates(self, request_dict): username = request_dict.get('userName', None) userEmail = request_dict.get('userEmail', None) password = request_dict.get('userPwd', None) authCode = request_dict.get('identifyingCode', None) language = request_dict.get('language', None) response = ResponseObject(language) if username and password and authCode: # 过滤空格 username = username.strip() if userEmail: userEmail = userEmail.strip() return self.register(username, userEmail, password, authCode, response) else: return response.json(800) def register(self, username, userEmail, password, authCode, response): dataValid = DataValid() reds = RedisObject() identifyingCode = reds.get_data(key=username + '_identifyingCode') if identifyingCode is False: identifyingCode = reds.get_data(key=userEmail + '_identifyingCode') if identifyingCode is False: return response.json(121) else: username = userEmail if authCode != identifyingCode: return response.json(121) if dataValid.password_validate(password): if dataValid.email_validate(username): nameValid = Device_User.objects.filter(username=username) emailValid = Device_User.objects.filter(userEmail=userEmail) if emailValid: return response.json(103) elif nameValid: return response.json(101) try: create_data = { "username": username, "userEmail": userEmail, "password": make_password(password), "userID": CommonService.getUserID(μs=False, setOTAID=True), "is_active": True, "user_isValid": True, } users = Device_User.objects.create(**create_data) except Exception as e: errorInfo = traceback.format_exc() print(errorInfo) return response.json(424, repr(e)) else: if reds.del_data(key=username + '_identifyingCode'): return response.json(0, { "user": { "userID": users.userID, "username": users.username, "userEmail": users.userEmail, "NickName": users.NickName, "userIconUrl": str(users.userIconUrl), "is_superuser": users.is_superuser, "is_active": users.is_active, "data_joined": date_handler(users.data_joined), "last_login": date_handler(users.last_login), } }) else: return response.json(10, '删除缓存验证码错误') elif dataValid.mobile_validate(username): nameValid = Device_User.objects.filter(username=username) if nameValid: return response.json(101) try: create_data = { "username": username, "userEmail": userEmail, "password": make_password(password), "userID": CommonService.getUserID(μs=False, setOTAID=True), "is_active": True, "user_isValid": True, } users = Device_User.objects.create(**create_data) except Exception as e: errorInfo = traceback.format_exc() print(errorInfo) return response.json(424, repr(e)) else: if reds.del_data(key=username + '_identifyingCode'): return response.json(0, { "user": { "userID": users.userID, "username": users.username, "userEmail": users.userEmail, "NickName": users.NickName, "userIconUrl": str(users.userIconUrl), "is_superuser": users.is_superuser, "is_active": users.is_active, "data_joined": date_handler(users.data_joined), "last_login": date_handler(users.last_login), } }) else: return response.json(10, '删除缓存验证码错误') else: return response.json(107) else: return response.json(109) # 登录 class LoginView(TemplateView): @method_decorator(csrf_exempt) # @csrf_exempt def dispatch(self, *args, **kwargs): return super(LoginView, self).dispatch(*args, **kwargs) @ratelimit(key='ip', rate='5/m') def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST language = request_dict.get('language', 'en') response = ResponseObject(language) was_limited = getattr(request, 'limited', False) if was_limited is True: return response.json(5) return self.validates(request_dict, response) @ratelimit(key='ip', rate='5/m') def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET language = request_dict.get('language', 'en') response = ResponseObject(language) was_limited = getattr(request, 'limited', False) if was_limited is True: return response.json(5) return self.validates(request_dict, response) def validates(self, request_dict, response): username = request_dict.get('userName', None) password = request_dict.get('userPwd', None) mcode = request_dict.get('mobileMechanicalCode', '') if username and password: username = username.strip() password = password.strip() return self.login(username, password, mcode, response) else: return response.json(444, 'username,password') def login(self, username, password, mcode, response): dataValid = DataValid() if dataValid.mobile_validate(username): userValid = Device_User.objects.filter(username=username) if userValid: if userValid[0].user_isValid and userValid[0].is_active: c_p = check_password(password, userValid[0].password) if c_p: return self.LoginUpdate(userValid, mcode, response) else: return response.json(111) else: return response.json(110) else: return response.json(102) elif dataValid.email_validate(username): userValid = Device_User.objects.filter(userEmail=username) if userValid: if userValid[0].user_isValid and userValid[0].is_active: User = auth.authenticate(username=userValid[0].username, password=password) if User is not None: return self.LoginUpdate(userValid, mcode, response) else: return response.json(111) else: return response.json(110) else: return response.json(104) else: return response.json(104) def LoginUpdate(self, userValid, mcode, response): userID = userValid[0].userID tko = TokenObject() res = tko.generate(data={'userID': userID, 'lang': response.lang, 'mcode': mcode}) if tko.code == 0: now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc) userValid.update(last_login=now_time, online=True, machine_code=mcode, language=response.lang) role_dict = ModelService.own_role(userID=userID) res['rid'] = role_dict['rid'] res['roleName'] = role_dict['roleName'] res['permList'] = ModelService.own_permission(userID) return response.json(0, res) else: return response.json(tko.code) # 登出 class LogoutView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(LogoutView, self).dispatch(*args, **kwargs) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' token = request.POST.get('token') return self.Logout(request, token) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' token = request.GET.get('token') return self.Logout(request, token) def Logout(self, request, token): response = ResponseObject() if token: tko = TokenObject(token) tko.valid() if tko.code == 0: try: MiscellService.add_access_log(request=request, status_code=200) except Exception as e: pass is_udpate = Device_User.objects.filter(userID=tko.userID).update(online=False) if is_udpate: return response.json(0) else: return response.json(tko.code) else: return response.json(800) # 修改密码 class ChangePwdView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(ChangePwdView, self).dispatch(*args, **kwargs) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST return self.validates(request_dict) def get(self, request, *args, **kwargs): request.encoding = 'gb2312' request_dict = request.GET return self.validates(request_dict) def validates(self, request_dict): token = request_dict.get('token', None) oldPwd = request_dict.get('oldPwd', None) newPwd = request_dict.get('newPwd', None) response = ResponseObject() if token and oldPwd and newPwd: tko = TokenObject(token) tko.valid() response.lang = tko.lang if tko.code == 0: return self.updatePwd(tko.userID, oldPwd, newPwd, response) else: return response.json(tko.code) else: return response.json(800) def updatePwd(self, userID, oldPwd, newPwd, response): user_qs = Device_User.objects.filter(userID=userID) if user_qs.exists(): c_p = check_password(oldPwd, user_qs[0].password) if c_p: update = user_qs.update(password=make_password(newPwd)) if update: return response.json(0) else: return response.json(112) else: return response.json(111) else: return response.json(113) class ForgetPwdView(TemplateView): ''' 忘记密码 ''' __server_host = None @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(ForgetPwdView, self).dispatch(*args, **kwargs) @ratelimit(key='ip', rate='1/m') def get(self, request, *args, **kwargs): request.encoding = 'utf-8' self.__server_host = CommonService.req_path(request) response = ResponseObject() was_limited = getattr(request, 'limited', False) if was_limited is True: return response.json(5) userName = request.GET.get('userName', None) return self.ValidationError(userName, response) @ratelimit(key='ip', rate='1/m') def post(self, request): self.__server_host = CommonService.req_path(request) request.encoding = 'utf-8' userName = request.POST.get('userName', None) response = ResponseObject() was_limited = getattr(request, 'limited', False) if was_limited is True: return response.json(5) return self.ValidationError(userName) def ValidationError(self, userName, response): if userName != None: userName = userName.strip() return self.ForgetPwd(userName, response) else: return response.json(800) def ForgetPwd(self, userName, response): dataValid = DataValid() if dataValid.mobile_validate(userName): User = Device_User.objects.filter(username=userName) if dataValid.email_validate(userName): User = Device_User.objects.filter(username=userName) if User: email = User[0].userEmail userID = User[0].userID if email: redisObj = RedisObject() reset_pwd = redisObj.get_data(key=userID + '_email_reset_pwd') if reset_pwd is False: tko = TokenObject() rest = tko.generate(data={'userID': userID}) token = rest['access_token'].decode('utf-8') reset_pwd = CommonService.RandomStr(6) send_data = TemplateService.email_message(type='forget', language='en') reset_link = '{server_host}/accounts/email-re-pwd/?token={token}'.format( server_host=self.__server_host, token=token) send_body = send_data['body'].format(username=email, reset_pwd=reset_pwd, reset_link=reset_link) ses = SesClassObject() send_res = ses.send_email(send_address_list=[email], subject=send_data['title'], body=send_body) if send_res is True: if redisObj.set_data(key=userID + '_email_reset_pwd',val=reset_pwd): return response.json(0) else: return response.json(10, '存储验证失败') else: return response.json(89) else: return response.json(103) else: return response.json(9) class EmailResetPwdView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(EmailResetPwdView, self).dispatch(*args, **kwargs) # 查询 def get(self, request, *args, **kwargs): response = ResponseObject() request_dict = request.GET return self.validate(request_dict, response, *args, **kwargs) # 认证登录 def post(self, request, *args, **kwargs): response = ResponseObject() try: print(request.body.decode("utf-8")) json_data = json.loads(request.body.decode("utf-8")) except Exception as e: return response.json(10, repr(e)) else: request_dict = json_data return self.validate(request_dict, response, *args, **kwargs) def validate(self, request_dict, response, *args, **kwargs): token = request_dict.get('token', None) if token is not None: tko = TokenObject(token) tko.valid() if tko.code == 0: redisObj = RedisObject() userID = tko.userID reset_pwd = redisObj.get_data(key=userID + '_email_reset_pwd') if reset_pwd is not False: user_qs = Device_User.objects.filter(userID=userID) if user_qs.exists(): redisObj.del_data(key=userID + '_email_reset_pwd') is_update = user_qs.update(password=make_password(reset_pwd)) if is_update: return HttpResponseRedirect("http://www.dvema.com/web/html/paw_update_success.html?code=" + reset_pwd) else: return response.json(10) else: return response.json(9) else: return response.json(307, 'rpwd') else: return response.json(tko.code) else: return response.json(444, 'token')