# -*- coding: utf-8 -*- from random import Random # 用于生成随机码 from wsgiref.util import FileWrapper from django.utils.timezone import utc from django.views.decorators.csrf import csrf_exempt from django.views.generic import TemplateView from django.utils.decorators import method_decorator from django.contrib.auth.hashers import make_password from itsdangerous import URLSafeTimedSerializer as utsr # itsdangerous序列化 import re, base64, json, traceback, random, string from qcloudsms_py.httpclient import HTTPError from qcloudsms_py import SmsSingleSender from qcloudsms_py import SmsVoiceVerifyCodeSender, SmsVoicePromptSender from Model.models import Auth_Captcha,Device_User from Ansjer.settings import BASE_DIR from Object.ResponseObject import ResponseObject import datetime,os from Ansjer.config import TX_PHONE_APP_KEY,TX_PHONE_APP_ID from django.http import HttpResponse #生成随机字符串 def RandomStr(randomlength = 8, number = False): str = '' if number == False: characterSet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsT' \ 'tUuVvWwXxYyZz0123456789' else: characterSet = '0123456789' length = len(characterSet) - 1 random = Random() for index in range(randomlength): str += characterSet[random.randint(0, length)] return str class MobiletoResetPwdView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(MobiletoResetPwdView, self).dispatch(*args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'gb2312' userName = request.POST.get('userName', None) authCode = request.POST.get('identifyingCode', None) newPwd = request.POST.get('newPwd', None) return self.ValidationError(userName, newPwd, authCode) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' userName = request.GET.get('userName', None) authCode = request.GET.get('identifyingCode', None) newPwd = request.GET.get('newPwd', None) return self.ValidationError(userName, newPwd, authCode) def ValidationError(self, userName, newPwd, authCode): response = ResponseObject() if userName != None and authCode != None and newPwd != None: return self.MobiletoResetPwd(userName, authCode, newPwd, response) else: return response.json(800) def MobiletoResetPwd(self, userName, authCode, newPwd,response): UserValid = Device_User.objects.filter(username = userName).order_by('-data_joined') if UserValid: Users = Auth_Captcha.objects.filter(username = userName).order_by('-sendtime') if Users: for User in Users: if User.authcaptca == authCode and User.sendtype == 'forget': now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc) timeValid = (now_time - User.sendtime).total_seconds() if timeValid < 300: is_flag = UserValid.update(password=make_password(newPwd)) if is_flag: return (0) else: return response.json(405) else: return response.json(120) else: return response.json(102) def date_handler(obj): return obj.isoformat() class TokenLink: ''' 1. security_key就是settings.py中设置的SECRET_KEY 2. generate_validate_token函数通过URLSafeTimedSerializer 在用户注册时生成一个令牌。用户名在令牌中被编了码。生成令牌之后, 会将带有token的验证链接发送到注册邮箱。 3.在confirm_validate_token函数中,只要令牌没过期, 那它就会返回一个用户名,过期时间为3600秒 ''' def __init__(self, security_key): self.security_key = security_key self.salt = base64.encodestring(security_key.encode()) def generate_validate_token(self, token): serializer = utsr(self.security_key) return serializer.dumps(token, self.salt) def confirm_validate_token(self, token, expiration=3600): serializer = utsr(self.security_key) return serializer.loads(token, salt=self.salt, max_age=expiration) def remove_validate_token(self, token): serializer = utsr(self.security_key) return serializer.loads(token, salt=self.salt) class getRandom: def __init__(self): self.__seed = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGH' \ 'IJKLMNOPQRSTUVWXYZ!@#$%^&*()_+=-' def getSalt (self, strlen = 8): sa = [] for index in range (strlen): sa.append(random.choice(self.__seed)) salt = ''.join(sa) return salt def getSaltStr(self, strlen = 8): salt = ''.join(random.sample(string.ascii_letters + string.digits, strlen)) return salt class ModifyPwdView(TemplateView): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): return super(ModifyPwdView, self).dispatch(*args, **kwargs) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' userEmail = request.POST.get('userEmail', None) oldPwd = request.POST.get('oldPwd', None) newPwd = request.POST.get('newPwd', None) return self.ValidationError(userEmail, oldPwd, newPwd) def get(self, request, *args, **kwargs): request.encoding = 'gb2312' userEmail = request.GET.get('userEmail', None) oldPwd = request.GET.get('oldPwd', None) newPwd = request.GET.get('newPwd', None) return self.ValidationError(userEmail, oldPwd, newPwd) def ValidationError(self, userEmail, oldPwd, newPwd): response = ResponseObject() dataValid = DataValid() if dataValid.password_validate(newPwd): if oldPwd != newPwd: return response.json(118) try: User = Device_User.objects.get(userEmail = userEmail) User.userPwd = make_password(newPwd) User.save() except Exception as e: errorInfo = traceback.format_exc() print('更新密码到数据库: %s' % errorInfo) return response.json(501,{'msg':repr(e)}) else: return response.json(0) else: return response.json(109) class DataValid: def __init__(self): # 用户名正则 # self.re_name = re.compile(r'^[A-Za-z0-9\u4e00-\u9fa5\.\_]{1,16}$') self.re_name = re.compile(r'^[A-Za-z0-9\u4e00-\u9fa5\.\_\-\@]{4,40}$') # 密码强度正则 self.re_password = re.compile(r'^\w{1,16}$') # 手机号码正则 self.re_mobile = re.compile(r'^\d{1,16}$') # 邮箱地址正则 self.re_email = re.compile(r'^[A-Za-z0-9\u4e00-\u9fa5\.\_\-]+@[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)+$') def name_validate(self, value): if self.re_name.match(value): return True else: return False def password_validate(self, value): if self.re_password.match(value): return True else: return False def email_validate(self, value): if self.re_email.match(value): return True else: return False def mobile_validate(self, value): if self.re_mobile.match(value): return True else: return False def sms(phoneNumbers, sendModel, msg, sendType = 'register', template_id = 7839): appid = TX_PHONE_APP_ID appkey = TX_PHONE_APP_KEY print(phoneNumbers, msg, sendModel, template_id) ssender = SmsSingleSender(appid, appkey) response = ResponseObject() try: if sendType == 'register': result = ssender.send(0, "86", phoneNumbers, u"{authCode}为您的注册验证码,请于2分钟内填写。" u"如非本人操作,请忽略本短信。".format(authCode=msg), "", "") elif sendType == 'forget': result = ssender.send(0, "86", phoneNumbers, u"{userPwd}为您的账号新密码,请登录账号后,修改为" u"用户自定义密码.".format(userPwd=msg), "", "") except HTTPError as e: errorInfo = traceback.format_exc() print('发送手机验证码出现网络错误: %s' % errorInfo) return response.json(1022,{'msg':repr(e)}) except Exception as e: errorInfo = traceback.format_exc() print('发送手机短信验证码错误: %s' % errorInfo) return response.json(1021) else: resultCode = result.get('result', None) if resultCode == 0: JSON = json.dumps(result, ensure_ascii=False) return JSON else: errorJSON = json.dumps(result, ensure_ascii=False) return errorJSON class QCloudSms(object): def __init__(self, nationcode, msg, template_id): self.appid = TX_PHONE_APP_ID self.appkey = TX_PHONE_APP_KEY self.msg = msg # 验证码msg self.nationcode = nationcode # 国家码 self.template_id = template_id # 模板ID def sms(self, mobiles, model, type = 'register'): response = ResponseObject() ssender = SmsSingleSender(self.appid, self.appkey) try: if type == 'register': result = ssender.send(0, "86", mobiles, u"{authCode}为您的注册验证码,请于2分钟内填写。" u"如非本人操作,请忽略本短信。".format(authCode= self.msg), "", "") elif type == 'forget': result = ssender.send(0, "86", mobiles, u"{userPwd}为您的账号新密码,请登录账号后,修改为" u"用户自定义密码.".format(userPwd = self.msg), "", "") except HTTPError as e: errorInfo = traceback.format_exc() print('发送手机短信验证码出现网络错误: %s' % errorInfo) return response.json(1022,repr(e)) except Exception as e: errorInfo = traceback.format_exc() print('发送手机验证码错误: %s' % errorInfo) return response.formal(1021,repr(e)) else: resultCode = result.get('result', None) if resultCode == 0: JSON = json.dumps(result, ensure_ascii=False) return JSON else: errorJSON = json.dumps(result, ensure_ascii=False) return errorJSON def voice(self, mobiles, model, type = 'register'): # 语音验证码请求 response = ResponseObject() vvcsender = SmsVoiceVerifyCodeSender(appid = self.appid, appkey = self.appkey) try: result = vvcsender.send(nation_code=self.nationcode, phone_number = \ mobiles, playtimes = 2, msg = self.msg, ext = '') except HTTPError as e: errorInfo = traceback.format_exc() print('发送手机验证码出现网络错误: %s' % errorInfo) return response.formal(1022,repr(e)) except Exception as e: errorInfo = traceback.format_exc() print('发送手机语音验证码错误: %s' % errorInfo) return response.formal(1023,repr(e)) else: resultCode = result.get('result', None) if resultCode == 0: JSON = json.dumps(result, ensure_ascii=False) return JSON else: errorJSON = json.dumps(result, ensure_ascii=False) return errorJSON # 发送语音通知 vpsender = SmsVoicePromptSender(appid=self.appid, appkey=self.appkey) # note: msg内容,首先需要申请内容模板,通过后才可以发送 try: result = vpsender.send(nation_code=self.nationcode, phone_number = \ mobiles, playtimes = 2, msg = self.msg, ext= '') except HTTPError as e: errorInfo = traceback.format_exc() print('发送手机验证码出现网络错误: %s' % errorInfo) return ResponseFormal(1022,repr(e)) except Exception as e: errorInfo = traceback.format_exc() print('发送手机语音验证码错误: %s' % errorInfo) return ResponseFormal(1023,repr(e)) else: resultCode = result.get('result', None) if resultCode == 0: JSON = json.dumps(result, ensure_ascii=False) return JSON else: errorJSON = json.dumps(result, ensure_ascii=False) return errorJSON @csrf_exempt def download_file(request, Upgradename, *callback_args, **callback_kwargs): """ 下载单个文件 :param request: :param Upgradename: :param callback_args: :param callback_kwargs: :return: """ print(Upgradename) print(callback_args, callback_kwargs) for value in callback_args: print("other args:", value) # 打印dict类型的不定长参数 args for key in callback_kwargs: print("dictargs:" + key + ":" + bytes(callback_kwargs[key])) print(request.body) file_name = os.path.join(BASE_DIR, "static/Upgrade/DVR/").replace('\\', '/') + Upgradename response = ResponseObject() if os.path.isfile(file_name): try: print(file_name) JSON = response.formal(0) wrapper = FileWrapper(open(file_name, 'rb')) response = HttpResponse(wrapper, content_type="application/octet-stream") response['Content-Length'] = os.path.getsize(file_name) response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(file_name) response['Content-Error'] = JSON return response except Exception as e: errorJSON = response.formal(10,'Wrong reason:' + repr(e)) response = HttpResponse(errorJSON, content_type='text/plain', charset='utf-8') response['Content-Error'] = errorJSON return response else: errorJSON = response.formal(907) response = HttpResponse(errorJSON, content_type='text/plain', charset='utf-8') response['Content-Error'] = errorJSON return response