chenjunkai пре 6 година
родитељ
комит
7953343f8f

+ 5 - 8
Ansjer/config.py

@@ -19,10 +19,10 @@ SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
 print(SERVER_TYPE)
 
 # 发送邮件邮箱
-COMPANY_EMAIL = 'user_server@nsst.com'
-AWS_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
-AWS_ACCESS_SECRET = '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'
-AWS_ACCESS_REGION = 'us-east-1'
+SES_COMPANY_EMAIL = 'user_server@nsst.com'
+AWS_SES_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
+AWS_SES_ACCESS_SECRET = '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'
+AWS_SES_ACCESS_REGION = 'us-east-1'
 AWS_BUCKET = 'ansjertest'
 # 设定离线时间为5分钟
 OFF_LINE_TIME_DELTA = 5
@@ -45,10 +45,7 @@ AuthCode_Expire = 600
 RTMP_PUSH_URL = 'http://13.56.215.252:8091/hls'
 # 根路径
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-#
-# print('[[[[[[[')
-# print(type())
-# print('[[[[[[[')
+
 if SERVER_TYPE == 'Ansjer.local_settings':
     NGINX_RTMP_STAT = 'http://192.168.136.45:8077/stat'
     SERVER_DOMAIN = 'http://192.168.136.45:8077'

+ 13 - 33
Ansjer/urls.py

@@ -12,14 +12,11 @@ urlpatterns = [
     url(r'^account/authcode$', UserController.authCodeView.as_view()),
     url(r'^account/register$', UserController.registerView.as_view()),
     url(r'^account/login$', UserController.v2LoginView.as_view()),
-    url(r'^account/logout$', UserController.LogoutView.as_view(), name='logout_user'),
-    url(r'^account/changePwd$', UserController.ChangePwdView.as_view(), name='change_password'),
-    url(r'^account/forget$', UserController.ForgetPwdView.as_view(), name='forget_password'),
+    url(r'^account/logout$', UserController.LogoutView.as_view()),
+    url(r'^account/changePwd$', UserController.ChangePwdView.as_view()),
+    url(r'^account/forget$', UserController.ForgetPwdView.as_view()),
     url(r'^account/email-re-pwd$', UserController.EmailResetPwdView.as_view()),
     url(r'^account/refreshTk$', UserController.refreshTokenView.as_view()),
-
-    ###
-    url(r'^admin/', admin.site.urls),
     url(r'^favicon.ico$', UserManger.success, name=u'favicon.ico'),
     url(r'^account/showUserMore$', UserManger.showUserMoreView.as_view()),
     url(r'^account/perfectUserInfo$', UserManger.perfectUserInfoView.as_view()),
@@ -31,27 +28,19 @@ urlpatterns = [
     url(r'^account/searchUser$', shareUserPermission.searchUserView.as_view()),
     url(r'^account/shareUserEquipment$', shareUserPermission.shareUserEquipmentView.as_view()),
     url(r'^account/unsharedUserEquipment$', shareUserPermission.unsharedUserEquipmentView.as_view()),
-
     url(r'^response/success$', UserManger.success),
-    # http://13.56.215.252:82/equipment/queryUserEquipment?token=test
     url(r'^equipment/queryUserEquipment$', EquipmentManager.queryUserEquipmentInterface),
-    url(r'^equipment/addNewUserEquipment$', EquipmentManager.addNewUserEquipmentInterface,
-        name='add_New_User_Equipment'),
+    url(r'^equipment/addNewUserEquipment$', EquipmentManager.addNewUserEquipmentInterface),
     url(r'^equipment/delUserEquipment$', EquipmentManager.delUserEquipmentInterface),
-    url(r'^equipment/modifyUserEquipment$', EquipmentManager.modifyUserEquipmentInterface,
-        name='modify_User_Equipment'),
-    url(r'^equipment/showAllUserEquipment$', EquipmentManager.showAllUserEquipmentInterface,
-        name='show_All_User_Equipment'),
+    url(r'^equipment/modifyUserEquipment$', EquipmentManager.modifyUserEquipmentInterface),
+    url(r'^equipment/showAllUserEquipment$', EquipmentManager.showAllUserEquipmentInterface),
     url(r'^equipment/findEquipmentInfo$', EquipmentManager.findEquipmentInfoInterface),
-
     url(r'^OTA/uploads$', OTAEquipment.getUploadFiletoDirView.as_view()),
     url(r'^OTA/download$', OTAEquipment.downloadUpdataFileUrl),
     url(r'^OTA/downloads/(\w+)/(\w+[\w+]*.+[^_w]*.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
     url(r'^OTA/getEquipmentVersion$', OTAEquipment.getEquipmentVersionInterface),
     url(r'^OTA/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
     url(r'^OTA/addNewEquipmentVersion$', OTAEquipment.addNewEquipmentVersionInterface),
-    # url(r'^OTA/showAllEquipmentVersion$', OTAEquipment.showAllEquipmentVersionInterface),
-
     url(r'^roles/addNewRole$', PermissionManager.addNewRoleView.as_view()),
     url(r'^roles/queryRole$', PermissionManager.queryRoleView.as_view()),
     url(r'^roles/delRole$', PermissionManager.delRoleView.as_view()),
@@ -61,29 +50,20 @@ urlpatterns = [
     url(r'^perms/queryPerms$', PermissionManager.queryPermsView.as_view()),
     url(r'^perms/modifyPerms$', PermissionManager.modifyPermsView.as_view()),
     url(r'^permsManager/queryRolePerms$', PermissionManager.queryRolePermsView.as_view()),
-
     url(r'^uploads/upgrade$', OTAEquipment.getUploadFiletoDirView.as_view()),
     url(r'^upgrade/download/(\w+.[^_w]*\w+.\w+)$', CheckUserData.download_file),
     url(r'^downloads/upgrade/(\w+)/(\w+.[^_w]*\w+.\w+)$', OTAEquipment.downloadUpdataFileUrlInterface),
     url(r'^getOTAurl/getUpdataFileUrl$', OTAEquipment.getUpdataFileUrlInterface),
-
-    #  流处理
-    url(r'^media/stream', StreamMedia.StreamMedia.as_view()),
+    url(r'^media/stream', StreamMedia.StreamMedia.as_view()),    #  流处理
     url(r'^media/auth_stream', StreamMedia.Auth_Stream),
     url(r'^media/send_video_s3', StreamMedia.send_video_s3),
-    url(r'^media/auth_live', StreamMedia.Auth_Live),
-    # 传感器
-    url(r'^equipment/sensor', EquipmentSensor.EquipmentSensor.as_view()),
-    # 设备推送信息
+    url(r'^media/auth_live', StreamMedia.Auth_Live),    # 传感器
+    url(r'^equipment/sensor', EquipmentSensor.EquipmentSensor.as_view()),    # 设备推送信息
     url(r'^equipment/info', EquipmentInfo.EquipmentInfo.as_view()),
-    # 管理员专属view
-    url(r'^adminManage/manage', AdminManage.AdminManage.as_view()),
-    # OTA重构类
-    url(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),
-    # 用户反馈信息
-    url(r'^feedbackInfo', FeedBackInfo.FeedBackInfo.as_view()),
-    # app版本信息
-    url(r'^appInfo', AppInfo.AppInfo.as_view()),
+    url(r'^adminManage/manage', AdminManage.AdminManage.as_view()),    # 管理员专属view
+    url(r'^equipment/OTA', EquipmentOTA.EquipmentOTA.as_view()),    # OTA重构类
+    url(r'^feedbackInfo', FeedBackInfo.FeedBackInfo.as_view()),    # 用户反馈信息
+    url(r'^appInfo', AppInfo.AppInfo.as_view()),    # app版本信息
     # 访问日志new
     url(r'^accesslog', AccessLog.AccessLog.as_view()),
     # 套餐信息管理

+ 60 - 98
Controller/UserController.py

@@ -273,97 +273,6 @@ class registerView(TemplateView):
             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)
-        print(username)
-        print(password)
-        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.name_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
-        print('userID' + 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)
-            res['userID'] = userID
-            print(res)
-            return response.json(0, res)
-        else:
-            return response.json(tko.code)
-
-
 # 登出
 class LogoutView(TemplateView):
     @method_decorator(csrf_exempt)
@@ -878,14 +787,16 @@ class v2forgetPwdCodeView(TemplateView):
 
     def ValidationError(self, request_dict, response):
         phone = request_dict.get('phone', None)
-        # email = request_dict.get('email', None)
+        email = request_dict.get('email', None)
         if phone is not None:
             phone = phone.strip()
-            return self.do_phone_pwd_forget(phone, response)
+            return self.do_send_phone_code(phone, response)
+        elif email is not None:
+            return self.do_send_email_code(email, response)
         else:
             return response.json(444, 'phone')
 
-    def do_phone_pwd_forget(self, phone, response):
+    def do_send_phone_code(self, phone, response):
         data_valid = DataValid()
         if data_valid.mobile_validate(phone) is not True:
             return response.json(100)
@@ -907,6 +818,28 @@ class v2forgetPwdCodeView(TemplateView):
         else:
             return response.json(10, res["Message"])
 
+    def do_send_email_code(self, email, response):
+        data_valid = DataValid()
+        if data_valid.email_validate(email) is not True:
+            return response.json(105)
+        user_qs = Device_User.objects.filter(Q(userEmail=email) | Q(username=email))
+        if not user_qs.exists():
+            return response.json(104)
+        reds = RedisObject()
+        resetCode = reds.get_data(key=email + '_forgetPwdResetCode')
+        if resetCode is True:
+            return response.json(90)
+        resetCode = RandomStr(6, True)
+        if not reds.set_data(key=email + '_forgetPwdResetCode', val=resetCode, expire=600):
+            return response.json(10, '生成缓存错误')
+        send_data = TemplateService.email_message(type='forgetCode', language=response.lang)
+        send_body = send_data['body'].format(userEmail=email,email_valid_code=resetCode)
+        ses = SesClassObject()
+        send_res = ses.send_email(send_address_list=[email], subject=send_data['title'], body=send_body)
+        if send_res is not True:
+            return response.json(44)
+        return response.json(0)
+
 
 # 忘记密码v2
 class v2resetPwdByCodeView(TemplateView):
@@ -936,15 +869,44 @@ class v2resetPwdByCodeView(TemplateView):
 
     def ValidationError(self, request_dict, response):
         phone = request_dict.get('phone', None)
+        email = request_dict.get('email', None)
         password = request_dict.get('password', None)
         authcode = request_dict.get('authcode', None)
-        if phone is not None and password is not None and authcode is not None:
+        if password is None or authcode is None:
+            return response.json(444, 'password,authcode')
+        authcode = authcode.strip()
+        password = password.strip()
+        if phone is not None:
             phone = phone.strip()
-            authcode = authcode.strip()
-            password = password.strip()
             return self.do_phone_pwd_reset(phone, authcode, password, response)
+        elif email is not None:
+            email = email.strip()
+            return self.do_email_pwd_reset(email, authcode, password, response)
         else:
-            return response.json(444, 'phone,password,authcode')
+            return response.json(444, 'phone')
+
+    def do_email_pwd_reset(self, email, authcode, password, response):
+        data_valid = DataValid()
+        if data_valid.email_validate(email) is not True:
+            return response.json(105)
+        if data_valid.password_validate(password) is not True:
+            return response.json(109)
+        user_qs = Device_User.objects.filter(Q(userEmail=email) | Q(username=email))
+        if not user_qs.exists():
+            return response.json(104)
+        reds = RedisObject()
+        resetCode = reds.get_data(key=email + '_forgetPwdResetCode')
+        if resetCode is True:
+            return response.json(90)
+        if authcode != resetCode:
+            return response.json(121)
+        if not reds.set_data(key=email + '_forgetPwdResetCode', val=resetCode, expire=300):
+            return response.json(10, '生成缓存错误')
+        user_qs.update(password=make_password(password))
+        if not reds.del_data(email + '_forgetPwdResetCode'):
+            return response.json(10, '删除缓存失败')
+        return response.json(0)
+
 
     def do_phone_pwd_reset(self, phone, authcode, password, response):
         data_valid = DataValid()

+ 106 - 82
Model/models.py

@@ -16,9 +16,10 @@ class PermissionsManager(models.Manager):
 
     def get_by_natural_key(self, permName):
         return self.get(
-            permName = permName
+            permName=permName
         )
 
+
 class RoleManager(models.Manager):
     """
     The manager for the auth's Role model.
@@ -26,30 +27,30 @@ class RoleManager(models.Manager):
     use_in_migrations = True
 
     def get_by_natural_key(self, roleName):
-        return self.get(roleName = roleName)
+        return self.get(roleName=roleName)
+
 
 class UserManager(BaseUserManager):
 
     def create_user(self, username, password, userID, is_active,
                     user_isValid, **extra_fields):
-
         user = self.model(
-            username = username,
-            userID = userID,
-            is_active = is_active,
-            user_isValid = user_isValid,
+            username=username,
+            userID=userID,
+            is_active=is_active,
+            user_isValid=user_isValid,
             **extra_fields
         )
         user.set_password(password)
         user.save(using=self._db)
 
-        role = Role.objects.get(rid = 1)
+        role = Role.objects.get(rid=1)
         user.role.add(role)
         return user
 
     def create_superuser(self, username, password, userID, is_active,
-                         user_isValid , **extra_fields):
-        #extra_fields.setdefault('is_superuser', is_superuser)
+                         user_isValid, **extra_fields):
+        # extra_fields.setdefault('is_superuser', is_superuser)
         is_superuser = extra_fields.get('is_superuser', None)
         if is_superuser != 100 and is_superuser != 1:
             raise ValueError('Superuser must have is_superuser=1 or 100.')
@@ -57,14 +58,17 @@ class UserManager(BaseUserManager):
         return self.create_user(username, password, userID, is_active,
                                 user_isValid, **extra_fields)
 
+
 @python_2_unicode_compatible
 class Permissions(models.Model):
     permName = models.CharField(blank=True, null=True, max_length=32, unique=True, verbose_name=u'权限名称')
     description = models.CharField(blank=True, null=True, max_length=128, verbose_name=u'描述信息', default='')
     objects = PermissionsManager()
+
     def __str__(self):
         return "%s" % (
             six.text_type(self.description))
+
     class Meta:
         ordering = ['permName']
         db_table = 'permissions'
@@ -75,6 +79,7 @@ class Permissions(models.Model):
     def natural_key(self):
         return (self.permName)
 
+
 class Role(models.Model):
     ROLE_TYPES = (
         ('Guests', u'Guests'),
@@ -152,21 +157,22 @@ class Role(models.Model):
             permslist.sort()
             return permslist
 
+
 class Device_User(AbstractBaseUser):
     userID = models.CharField(blank=True, max_length=32, primary_key=True,
                               verbose_name=u'用户ID', unique=True, default=CommonService.getUserID(getUser=True))
     role = models.ManyToManyField(to='Role', blank=True, verbose_name=u'用户角色', db_table='user_role')
 
-    username = models.CharField(max_length=40, verbose_name=u'用户名', unique = True, null=True,blank=True)
+    username = models.CharField(max_length=40, verbose_name=u'用户名', unique=True, null=True, blank=True)
     password = models.CharField(max_length=128, verbose_name=u'密码')
-    userEmail = models.EmailField(max_length = 64, verbose_name=u'邮箱', unique = True, null=True, blank=True)
+    userEmail = models.EmailField(max_length=64, verbose_name=u'邮箱', unique=True, null=True, blank=True)
     # 实际的路径就是 MEDIA_ROOT/Image/filename,所以可用upload_to来指定文件存放的前缀路径
     userIconPath = ProcessedImageField(blank=True, upload_to='User/Images/', default='static/User/default.png',
-                        verbose_name=u'头像',
-                        # 图片将处理成85x85的尺寸
-                        processors=[ResizeToFill(85, 85)],)
-    userIconUrl = models.URLField(blank = True, max_length = 128, default=SERVER_DOMAIN
-                                                                          + '/account/getAvatar/User/defaultUser.png')
+                                       verbose_name=u'头像',
+                                       # 图片将处理成85x85的尺寸
+                                       processors=[ResizeToFill(85, 85)], )
+    userIconUrl = models.URLField(blank=True, max_length=128, default=SERVER_DOMAIN
+                                                                      + '/account/getAvatar/User/defaultUser.png')
     NickName = models.CharField(blank=True, max_length=32, default='', verbose_name=u'用户昵称')
     is_superuser = models.IntegerField(blank=True, default=0, verbose_name=u'用户类型')
     is_active = models.BooleanField(blank=True, default=False, verbose_name=u'用户活动状态')
@@ -182,11 +188,11 @@ class Device_User(AbstractBaseUser):
 
     objects = UserManager()
 
-    USERNAME_FIELD = 'userID' # 必须有一个唯一标识
-    REQUIRED_FIELDS = ['is_superuser'] # 创建superuser时的必须字段
+    USERNAME_FIELD = 'userID'  # 必须有一个唯一标识
+    REQUIRED_FIELDS = ['is_superuser']  # 创建superuser时的必须字段
 
     class Meta:
-        ordering = ('-data_joined', )
+        ordering = ('-data_joined',)
         verbose_name = u'用户信息'
         db_table = 'device_user'
         get_latest_by = 'last_login'
@@ -279,16 +285,19 @@ class Device_User(AbstractBaseUser):
             permslist = list(permSet)
             permslist.sort()
             return permslist
+
     def has_module_perms(self, app_label):
         return True
+
     @property
     def is_staff(self):
         return self.is_superuser
 
+
 class Device_Info(models.Model):
     id = models.CharField(blank=True, max_length=32, primary_key=True)
     userID = models.ForeignKey(Device_User, blank=True, to_field='userID',
-                                   on_delete=models.CASCADE)
+                               on_delete=models.CASCADE)
     NickName = models.CharField(blank=True, max_length=32, verbose_name=u'设备名称')
     UID = models.CharField(blank=True, max_length=32, verbose_name=u'设备UID')
     SID = models.CharField(blank=True, max_length=32, verbose_name=u'服务器ID')
@@ -309,7 +318,7 @@ class Device_Info(models.Model):
     primaryUserID = models.CharField(blank=True, verbose_name='主用户',
                                      help_text=u'该设备的主用户', max_length=32, default='')
     data_joined = models.DateTimeField(blank=True, verbose_name=u'设备添加时间', auto_now_add=True)
-    update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True,null=True)
+    update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True, null=True)
 
     ip = models.CharField(blank=True, max_length=20, null=True, verbose_name=u'设备区域ip')
     area = models.CharField(blank=True, max_length=100, null=True, verbose_name=u'设备区域area')
@@ -320,9 +329,9 @@ class Device_Info(models.Model):
     WIFIName = models.CharField(blank=True, max_length=50, null=True, verbose_name=u'无线名称')
     WIFIIP = models.CharField(blank=True, max_length=20, null=True, verbose_name=u'无线ip')
     WIFIPwd = models.CharField(blank=True, max_length=50, null=True, verbose_name=u'无线密码')
-    isDetector = models.BooleanField(blank=True, verbose_name=u'侦测开关0:关闭,1:开启)',default=False)
+    isDetector = models.BooleanField(blank=True, verbose_name=u'侦测开关0:关闭,1:开启)', default=False)
     DetectorRank = models.IntegerField(blank=True, default=0, verbose_name=u'侦测灵敏度 1:低,2:中,3:高4:最高')
-    iSNotification = models.BooleanField(blank=True, verbose_name=u'报警通知 0:关闭,1:开启)',default=False)
+    iSNotification = models.BooleanField(blank=True, verbose_name=u'报警通知 0:关闭,1:开启)', default=False)
     MirrorType = models.IntegerField(blank=True, default=0, verbose_name=u'镜像类型 0:关闭镜像,1:上下镜像,2:左右镜像,3:上下左右镜像')
     RecordType = models.IntegerField(blank=True, default=0, verbose_name=u'录像模式(0:关闭,1:全是录像,3:报警录像)')
     TimeZone = models.CharField(blank=True, max_length=50, null=True, verbose_name=u'时区')
@@ -331,6 +340,7 @@ class Device_Info(models.Model):
 
     def __str__(self):
         return self.NickName
+
     def model_to_dict(self, fields=None, exclude=None):
         opts = self._meta
         data = {}
@@ -348,20 +358,23 @@ class Device_Info(models.Model):
         db_table = 'device_info'
         ordering = ('-data_joined',)
         verbose_name = u'用户设备信息表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
+
 
 class AuthToken_Token(models.Model):
-    tokenID = models.OneToOneField(Device_User, blank=True,on_delete=models.CASCADE,
-                                   primary_key=True) #定义一对一关系
+    tokenID = models.OneToOneField(Device_User, blank=True, on_delete=models.CASCADE,
+                                   primary_key=True)  # 定义一对一关系
     access_token = models.CharField(blank=True, max_length=256)
     refresh_token = models.CharField(blank=True, max_length=256)
     last_update = models.DateTimeField(blank=True, auto_now=True)
     iCode = models.CharField(blank=True, max_length=12, verbose_name=u'干扰码')
     mCode = models.CharField(blank=True, max_length=64, verbose_name=u'设备码')
+
     class Meta:
         verbose_name = u'用户Token'
         db_table = 'authtoken_token'
-        ordering = ('-last_update', )
+        ordering = ('-last_update',)
+
 
 class AuthToken_JWT(models.Model):
     jwtID = models.OneToOneField(Device_User, blank=True, on_delete=models.CASCADE,
@@ -375,12 +388,13 @@ class AuthToken_JWT(models.Model):
         verbose_name = u'用户JWT'
         verbose_name_plural = verbose_name
         db_table = 'authtoken_jwt'
-        ordering = ('-last_update', )
+        ordering = ('-last_update',)
+
 
 class Email_Captcha(models.Model):
     userCaptcha = models.CharField(max_length=10, verbose_name=u'验证码')
     userEmail = models.EmailField(max_length=50, verbose_name=u'邮箱')
-    sendType = models.CharField(choices=(("register",u"注册"),("forget",u"找回密码")), max_length=15)
+    sendType = models.CharField(choices=(("register", u"注册"), ("forget", u"找回密码")), max_length=15)
     sendTime = models.DateField(auto_now_add=True)
 
     class Meta:
@@ -388,12 +402,13 @@ class Email_Captcha(models.Model):
         ordering = ('-sendTime',)
 
         verbose_name = u'邮箱验证码'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
+
 
 class Auth_Captcha(models.Model):
     username = models.CharField(max_length=50, help_text=u'用户名(邮箱或电话号码)')
     authcaptca = models.CharField(max_length=6, help_text=u'验证码')
-    sendtype = models.CharField(max_length=15, choices=(("register",u"注册"),("forget",u"找回密码")))
+    sendtype = models.CharField(max_length=15, choices=(("register", u"注册"), ("forget", u"找回密码")))
     sendtime = models.DateTimeField(auto_now_add=True)
 
     class Meta:
@@ -401,47 +416,51 @@ class Auth_Captcha(models.Model):
         ordering = ('-sendtime',)
 
         verbose_name = u'邮箱验证码'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
+
 
 class Access_Log(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
-    user = models.CharField(max_length=100,null=True,db_index=True,blank=True,verbose_name=u'用户')
-    operation = models.CharField(max_length=100,db_index=True,null=True,blank=True,verbose_name=u'操作')
-    ip = models.CharField(max_length=100,null=True,blank=True,verbose_name=u'访问ip地址')
-    url = models.CharField(max_length=150,null=True,blank=True,verbose_name=u'访问路径')
-    status = models.IntegerField(null=True,blank=True,verbose_name=u'状态')
-    time = models.DateTimeField(null=True,blank=True, db_index=True,verbose_name=u'访问时间')
-    content = models.TextField(blank=True,null=True, verbose_name=u'参数内容')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    user = models.CharField(max_length=100, null=True, db_index=True, blank=True, verbose_name=u'用户')
+    operation = models.CharField(max_length=100, db_index=True, null=True, blank=True, verbose_name=u'操作')
+    ip = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'访问ip地址')
+    url = models.CharField(max_length=150, null=True, blank=True, verbose_name=u'访问路径')
+    status = models.IntegerField(null=True, blank=True, verbose_name=u'状态')
+    time = models.DateTimeField(null=True, blank=True, db_index=True, verbose_name=u'访问时间')
+    content = models.TextField(blank=True, null=True, verbose_name=u'参数内容')
+
     class Meta:
         db_table = 'access_log'
         verbose_name = u'访问日志表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
+
 
 class Equipment_Stream(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
-    userID = models.CharField(blank=True, max_length=32,verbose_name=u'用户ID')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    userID = models.CharField(blank=True, max_length=32, verbose_name=u'用户ID')
     status = models.IntegerField(null=True, blank=True, verbose_name=u'状态')
-    uid = models.CharField(null=True, blank=True,max_length=32, verbose_name=u'设备ID')
+    uid = models.CharField(null=True, blank=True, max_length=32, verbose_name=u'设备ID')
     channel = models.IntegerField(null=True, blank=True, verbose_name=u'设备通道')
-    access_token = models.CharField(blank=True, max_length=128,verbose_name=u'设备推流验证令牌')
+    access_token = models.CharField(blank=True, max_length=128, verbose_name=u'设备推流验证令牌')
     total_flow = models.FloatField(null=True, blank=True, verbose_name=u'传输总容量')
-    add_time = models.DateTimeField(blank=True, null=True,verbose_name=u'加入时间', auto_now_add=True)
+    add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     rank = models.IntegerField(null=True, blank=True, verbose_name=u'推流套餐类型')
 
     class Meta:
         db_table = 'equipment_stream'
         verbose_name = u'用户设备推流表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
+
 
 class Equipment_Sensor(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     status = models.IntegerField(null=True, blank=True, verbose_name=u'状态')
     type = models.IntegerField(null=True, blank=True, verbose_name=u'类型')
-    name = models.CharField(null=True, blank=True,max_length=128, verbose_name=u'传感器名称')
-    add_time = models.DateTimeField(blank=True,null=True, verbose_name=u'加入时间', auto_now_add=True)
+    name = models.CharField(null=True, blank=True, max_length=128, verbose_name=u'传感器名称')
+    add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
-    uid = models.CharField(null=True, blank=True,max_length=32, verbose_name=u'设备ID')
+    uid = models.CharField(null=True, blank=True, max_length=32, verbose_name=u'设备ID')
 
     def __str__(self):
         return self.id
@@ -449,37 +468,40 @@ class Equipment_Sensor(models.Model):
     class Meta:
         db_table = 'equipment_sensor'
         verbose_name = u'设备传感器表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
         ordering = ('id',)
 
+
 class Equipment_Info(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
-    devUid = models.CharField(null=True, blank=True,max_length=32, verbose_name=u'设备ID')
-    devNickName = models.CharField(blank=True, max_length=32, default='',verbose_name=u'设备昵称')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
+    devUid = models.CharField(null=True, blank=True, max_length=32, verbose_name=u'设备ID')
+    devNickName = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
     Channel = models.IntegerField(null=True, blank=True, verbose_name=u'设备通道')
     eventType = models.IntegerField(null=True, blank=True, verbose_name=u'事件类型')
-    viewAccont = models.CharField(blank=True,null=True, max_length=32, verbose_name=u'设备账户')
-    viewPwd = models.CharField(blank=True, null=True,max_length=32, verbose_name=u'设备密码')
+    viewAccont = models.CharField(blank=True, null=True, max_length=32, verbose_name=u'设备账户')
+    viewPwd = models.CharField(blank=True, null=True, max_length=32, verbose_name=u'设备密码')
     status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态')
     alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
-    eventTime = models.CharField(blank=True,null=True, max_length=16, verbose_name=u'设备报警时间')
-    receiveTime = models.CharField(blank=True,null=True, max_length=16, verbose_name=u'接收到报警时间')
-    userID = models.ForeignKey(Device_User, null=True,blank=True, to_field='userID',
-                                   on_delete=models.CASCADE)
+    eventTime = models.CharField(blank=True, null=True, max_length=16, verbose_name=u'设备报警时间')
+    receiveTime = models.CharField(blank=True, null=True, max_length=16, verbose_name=u'接收到报警时间')
+    userID = models.ForeignKey(Device_User, null=True, blank=True, to_field='userID',
+                               on_delete=models.CASCADE)
+
     def __str__(self):
         return self.id
 
     class Meta:
         db_table = 'equipment_info'
         verbose_name = u'设备信息推送表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
         ordering = ('-id',)
 
+
 class Feedback_Info(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     userID = models.CharField(blank=True, max_length=32, verbose_name=u'用户ID')
     status = models.BooleanField(blank=True, default=False, verbose_name=u'状态:0未解决/解决')
-    content = models.TextField(blank=True,null=True, verbose_name=u'反馈描述')
+    content = models.TextField(blank=True, null=True, verbose_name=u'反馈描述')
     add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间/反馈时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
 
@@ -489,17 +511,17 @@ class Feedback_Info(models.Model):
     class Meta:
         db_table = 'feedback_info'
         verbose_name = u'用户反馈信息表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
         ordering = ('id',)
 
 
 class Store_Meal(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增ID')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增ID')
     title = models.CharField(blank=True, max_length=32, verbose_name=u'标题')
     price = models.CharField(blank=True, max_length=32, verbose_name=u'价格')
     day = models.IntegerField(null=True, blank=True, verbose_name=u'存储时间')
-    content = models.TextField(blank=True,null=True, verbose_name=u'描述')
-    add_time = models.DateTimeField(blank=True,null=True, verbose_name=u'加入时间', auto_now_add=True)
+    content = models.TextField(blank=True, null=True, verbose_name=u'描述')
+    add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
 
     def __str__(self):
@@ -508,37 +530,38 @@ class Store_Meal(models.Model):
     class Meta:
         db_table = 'store_meal'
         verbose_name = u'存储套餐'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
         ordering = ('id',)
 
 
 class Device_Meal(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     status = models.IntegerField(null=True, blank=True, verbose_name=u'状态')
-    uid = models.CharField(null=True, blank=True,max_length=32,verbose_name=u'设备ID')
+    uid = models.CharField(null=True, blank=True, max_length=32, verbose_name=u'设备ID')
     channel = models.IntegerField(null=True, blank=True, verbose_name=u'设备通道')
-    add_time = models.DateTimeField(blank=True, null=True,verbose_name=u'加入时间', auto_now_add=True)
+    add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     end_time = models.DateTimeField(blank=True, verbose_name=u'最后时间')
     rank = models.ForeignKey(Store_Meal, blank=True, to_field='id',
-                               on_delete=models.CASCADE,verbose_name='套餐类型')
+                             on_delete=models.CASCADE, verbose_name='套餐类型')
 
     class Meta:
         db_table = 'device_meal'
         verbose_name = u'设备关联套餐表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
         ordering = ('id',)
 
     def __str__(self):
         return self.id
 
+
 class Equipment_Version(models.Model):
     eid = models.CharField(blank=True, max_length=32, primary_key=True)
     ESN = models.CharField(blank=True, max_length=32, verbose_name=u'设备规格名称')
     code = models.CharField(blank=True, max_length=32, verbose_name=u'设备规格代码')
     version = models.CharField(blank=True, max_length=32, verbose_name=u'设备版本')
     softwareVersion = models.CharField(blank=True, max_length=32, verbose_name=u'软件版本')
-    chipModelList2Code = models.CharField(max_length=32,blank=True, verbose_name=u'主芯片码')
+    chipModelList2Code = models.CharField(max_length=32, blank=True, verbose_name=u'主芯片码')
     channel = models.IntegerField(blank=True, verbose_name=u'通道数')
     resolutionRatio = models.IntegerField(blank=True, verbose_name=u'分辨率')
     type = models.CharField(blank=True, max_length=16, verbose_name=u'设备机型')
@@ -547,10 +570,10 @@ class Equipment_Version(models.Model):
     fileSize = models.IntegerField(blank=True, verbose_name=u'文件总大小')
     filePath = models.CharField(blank=True, max_length=256, verbose_name=u'升级文件路径')
     Description = models.TextField(blank=True, default='', verbose_name=u'描述信息')
-    fileMd5 = models.CharField(blank=True,max_length=32,null=True,verbose_name=u'上传文件MD5加密')
+    fileMd5 = models.CharField(blank=True, max_length=32, null=True, verbose_name=u'上传文件MD5加密')
     status = models.BooleanField(blank=True, default=True, verbose_name=u'是否开启更新状态')
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
-    lang = models.CharField(blank=True, null=True,default=0, max_length=32, verbose_name=u'ota包内置语言')
+    lang = models.CharField(blank=True, null=True, default=0, max_length=32, verbose_name=u'ota包内置语言')
 
     def __str__(self):
         return self.eid
@@ -560,16 +583,17 @@ class Equipment_Version(models.Model):
         ordering = ('-data_joined',)
         db_table = 'equipment_version'
 
+
 class App_Info(models.Model):
-    id = models.AutoField(primary_key=True,verbose_name=u'自增标记ID')
+    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
     appName = models.CharField(blank=True, max_length=32, verbose_name=u'app名称')
     systemLanguage = models.CharField(blank=True, max_length=32, verbose_name=u'系统语言')
     newAppversion = models.CharField(blank=True, max_length=12, verbose_name=u'系统版本')
     bundleVersion = models.CharField(blank=True, max_length=12, verbose_name=u'项目版本')
-    content = models.TextField(blank=True,null=True, verbose_name=u'更新内容')
+    content = models.TextField(blank=True, null=True, verbose_name=u'更新内容')
     app_type = models.IntegerField(null=True, blank=True, verbose_name=u'app类型')
-    add_time = models.DateTimeField(blank=True,null=True, verbose_name=u'加入时间', auto_now_add=True)
+    add_time = models.DateTimeField(blank=True, null=True, verbose_name=u'加入时间', auto_now_add=True)
     update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True)
     downloadLink = models.TextField(blank=True, null=True, verbose_name='升级')
 
@@ -579,5 +603,5 @@ class App_Info(models.Model):
     class Meta:
         db_table = 'app_info'
         verbose_name = u'app信息表'
-        verbose_name_plural=verbose_name
+        verbose_name_plural = verbose_name
         ordering = ('id',)

+ 8 - 8
Object/AWS/SesClassObject.py

@@ -1,17 +1,17 @@
-from Ansjer.config import AWS_ACCESS_ID,AWS_ACCESS_SECRET,AWS_ACCESS_REGION,COMPANY_EMAIL
+from Ansjer.config import AWS_SES_ACCESS_ID,AWS_SES_ACCESS_SECRET,AWS_SES_ACCESS_REGION,SES_COMPANY_EMAIL
 from boto3.session import Session
 import traceback
 
 class SesClassObject:
     def __init__(self, *args, **kwargs):
-        self.access_id = AWS_ACCESS_ID
-        self.access_secret = AWS_ACCESS_SECRET
-        self.region_name = AWS_ACCESS_REGION
-        self.company_email = COMPANY_EMAIL
+        self.access_id = AWS_SES_ACCESS_ID
+        self.access_secret = AWS_SES_ACCESS_SECRET
+        self.region_name = AWS_SES_ACCESS_REGION
+        self.company_email = SES_COMPANY_EMAIL
         session = Session(
-            aws_access_key_id=AWS_ACCESS_ID,
-            aws_secret_access_key=AWS_ACCESS_SECRET,
-            region_name=AWS_ACCESS_REGION,
+            aws_access_key_id=AWS_SES_ACCESS_ID,
+            aws_secret_access_key=AWS_SES_ACCESS_SECRET,
+            region_name=AWS_SES_ACCESS_REGION,
         )
         self.conn = session.client('ses')
 

BIN
Object/AWS/__pycache__/CloudfrontSignCookie.cpython-36.pyc


BIN
Object/AWS/__pycache__/CloudfrontSignUrl.cpython-36.pyc


BIN
Object/AWS/__pycache__/ElasticTranscoder.cpython-36.pyc


BIN
Object/AWS/__pycache__/S3ClassObject.cpython-36.pyc


BIN
Object/AWS/__pycache__/SesClassObject.cpython-36.pyc


+ 55 - 11
Service/TemplateService.py

@@ -11,6 +11,8 @@
 @file: TemplateService.py
 @Contact: chanjunkai@163.com
 """
+
+
 class TemplateService:
 
     @staticmethod
@@ -24,22 +26,18 @@ class TemplateService:
             'account/forget',
             'account/email-re-pwd'
             'account/refreshTk',
-
             'account/showUserMore',
             'account/perfectUserInfo',
             'account/getAvatar',
             'account/delUser',
             'account/setUserValid',
-            # 'account/showAllUser',
             'account/help',
             'account/searchUser',
             'account/unsharedUserEquipment',
-            # 'account/success',
             'equipment/queryUserEquipment',
             'equipment/addNewUserEquipment',
             'equipment/delUserEquipment',
             'equipment/modifyUserEquipment',
-            # 'equipment/showAllUserEquipment',
             'accessLog/findEquipmentInfo',
             'OTA/uploads',
             'OTA/download',
@@ -47,7 +45,6 @@ class TemplateService:
             'OTA/getEquipmentVersion',
             'OTA/getUpdataFileUrl',
             'OTA/addNewEquipmentVersion',
-            # 'OTA/showAllEquipmentVersion',
             'OTA/getUpdataFileUrl',
             'roles/addNewRole',
             'roles/queryRole',
@@ -59,22 +56,26 @@ class TemplateService:
             'perms/modifyPerms',
             'permsManager/queryRolePerms',
             'uploads/upgrade',
-            # 'upgrade/download',
             'downloads/upgrade',
             'getOTAurl/getUpdataFileUrl',
-            # 'equipment/sensor',
             'equipment/info',
             'adminManage/manage',
             'equipment/OTA',
-            # 'feedbackInfo',
             'appInfo',
-            'OTA/getNewVer'
+            'OTA/getNewVer',
+            'OTA/getNewVer',
+            'OTA/getNewVer',
+
+            'v2/account/authcode',
+            'v2/account/register',
+            'v2/account/forgetCode',
+            'v2/account/resetPwdByCode',
         ]
         return apiList
 
     @staticmethod
     def email_message(type, language):
-        if language is None:
+        if language != 'cn':
             language = 'en'
         if type == 'register_code':
             data = {
@@ -418,4 +419,47 @@ class TemplateService:
                     'body': 'Hello! Dear {username}.<br>You have asked to reset the password, and you can click the link below to reset the password.<br>' + '<p><a href="{reset_link}">{reset_link}</a></p><br>' + 'The new password is: {reset_pwd}<br>If you do not request to reset the password, please ignore this mail.',
                 }
             }
-        return data[language]
+        elif type == 'forgetCode':
+            data = {
+                'cn': {
+                    'title': '重置密码验证码',
+                    'body': """
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+</head>
+<body>
+<div class="content"
+     style="overflow: hidden;padding:30px 10% 70px 10%;margin:0 10%;background-color: #fff;box-shadow:0 4px 20px rgba(0,0,0,0.1);word-break: break-all;">
+    <h2 style="margin: 30px 0;">{userEmail},您好</h2>
+    <p style="margin-bottom: 40px;">请使用下面的验证码重置您的密码,验证码 10 分钟内有效: </p>
+    <span style="padding: 10px 20px; font-size: 24px;background-color: #EB6F5A;border-radius:4px;color:#fff;">{email_valid_code}</span>
+</div>
+</body>
+</html>
+"""
+                },
+                'en': {
+                    'title': 'Reset password verification code',
+                    'body': """
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+</head>
+<body>
+<div class="content"
+     style="overflow: hidden;padding:30px 10% 70px 10%;margin:0 10%;background-color: #fff;box-shadow:0 4px 20px rgba(0,0,0,0.1);word-break: break-all;">
+    <h2 style="margin: 30px 0;">Hello, {userEmail}</h2>
+    <p style="margin-bottom: 40px;">Please reset your password with the following captcha, which is valid for 10 minutes:</p>
+    <span style="padding: 10px 20px; font-size: 24px;background-color: #EB6F5A;border-radius:4px;color:#fff;">{email_valid_code}</span>
+</div>
+</body>
+</html>
+"""
+                }
+            }
+        return data[language]