瀏覽代碼

用户昵称头像合规检测

locky 1 年之前
父節點
當前提交
9497075403
共有 5 個文件被更改,包括 154 次插入10 次删除
  1. 3 2
      Ansjer/cn_config/config_test.py
  2. 4 0
      Ansjer/config.py
  3. 43 3
      Controller/UserManger.py
  4. 86 0
      Object/ContentSecurityObject.py
  5. 18 5
      Object/ResponseObject.py

+ 3 - 2
Ansjer/cn_config/config_test.py

@@ -16,6 +16,7 @@ AWS相关
 # SECRET_ACCESS_KEY = 'aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL'
 AWS_ARN_S3 = 'arn:aws:s3'
 REGION_NAME = 'us-east-1'
+REGION_NAME2 = 'us-west-1'
 ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
 SECRET_ACCESS_KEY = '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'
 
@@ -27,8 +28,8 @@ LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 # redis节点
-SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
-PUSH_REDIS_ADDRESS = 'pushredis.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
+SERVER_HOST = '127.0.0.1'
+PUSH_REDIS_ADDRESS = '127.0.0.1'
 # ======================================================================================================================
 
 # 域名

+ 4 - 0
Ansjer/config.py

@@ -27,6 +27,10 @@ RESET_REGION_ID_SERIAL_REDIS_LIST = 'reset_region_id_serial_redis_list'
 # 地区id列表
 REGION_ID_LIST = [1, 2, 3, 4, 5]
 
+# 阿里云AccessKey和AccessKeySecret
+ALI_ACCESS_KEY_ID = 'LTAI5t9BXQWTPfBEh2Qu8YNA'
+ALI_ACCESS_KEY_SECRET = '8TcEjHkHGsJaknbHlHzZP4HXQ7GuvT'
+
 # 亚马逊的数据库DynamoDB的密钥
 AWS_DynamoDB_REGION = 'us-west-1'
 AWS_DynamoDB_ACCESS_KEY = 'AKIA2E67UIMD6X23FEBG'

+ 43 - 3
Controller/UserManger.py

@@ -10,9 +10,12 @@ from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView, View
 
-from Ansjer.config import BASE_DIR, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, AVATAR_BUCKET
+from Ansjer.cn_config.config_test import REGION_NAME2
+from Ansjer.config import BASE_DIR, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, AVATAR_BUCKET, CONFIG_INFO, \
+    CONFIG_CN, CONFIG_TEST, LOGGER
 from Ansjer.config import SERVER_DOMAIN
 from Model.models import Role, Device_User, UserOauth2Model, UserExModel, CountryLanguageModel, LanguageModel, App_Info
+from Object.ContentSecurityObject import ContentSecurity
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -120,7 +123,7 @@ class showUserMoreView(TemplateView):
             sqlDict['oauth2'] = list(ua_qs)
             return response.json(0, sqlDict)
         except Exception as e:
-            return response.json(500, repr(e))
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
 
 class perfectUserInfoView(TemplateView):
@@ -152,6 +155,7 @@ class perfectUserInfoView(TemplateView):
         userID = tko.userID
         if not userID:
             return response.json(309)
+
         userIconPath = ''
         if userIcon:
             # 上传头像到aws s3
@@ -165,10 +169,34 @@ class perfectUserInfoView(TemplateView):
             Key = userID + '/' + userIcon.name
             aws_s3_client.put_object(Bucket=AVATAR_BUCKET, Key=Key, Body=userIcon)
             userIconPath = userID + '/' + userIcon.name
+
+            #  测试/国内服,验证头像是否合规
+            if CONFIG_INFO == CONFIG_CN or CONFIG_INFO == CONFIG_TEST:
+                # 测试服头像地区为us-west-1
+                if CONFIG_INFO == CONFIG_TEST:
+                    aws_s3_client = boto3.client(
+                        's3',
+                        region_name=REGION_NAME2,
+                        aws_access_key_id=ACCESS_KEY_ID,
+                        aws_secret_access_key=SECRET_ACCESS_KEY,
+                        config=botocore.client.Config(signature_version='s3v4'),
+                    )
+
+                params = {'Bucket': AVATAR_BUCKET, 'Key': Key}
+                image_url = aws_s3_client.generate_presigned_url('get_object', Params=params)
+                service = 'profilePhotoCheck'
+                LOGGER.info('头像链接:{}'.format(image_url))
+                service_dict = {'imageUrl': image_url}
+                service_parameters = json.dumps(service_dict)
+                legal = ContentSecurity().image_review(service, service_parameters)
+                if not legal:
+                    return response.json(106)
+
         if userContent:
             dataValid = json.loads(userContent)
             if 'userID' and 'password' and 'is_superuser' in dataValid.keys():
                 return response.json(444)
+
         if not userIconPath and not userContent:
             return response.json(444)
         elif not userIconPath and userContent:
@@ -199,6 +227,18 @@ class perfectUserInfoView(TemplateView):
                 UserData = json.loads(userContent)
             except Exception as e:
                 return response.json(444, repr(e))
+
+            # 测试/国内服,验证昵称是否合规
+            if CONFIG_INFO == CONFIG_CN or CONFIG_INFO == CONFIG_TEST:
+                nickname = UserData.get('NickName')
+                if nickname:
+                    service = 'nickname_detection'
+                    service_dict = {'content': nickname}
+                    service_parameters = json.dumps(service_dict)
+                    legal = ContentSecurity().text_review(service, service_parameters)
+                    if not legal:
+                        return response.json(108)
+
         try:
             if userIconPath and userContent:
                 User.update(userIconPath=userIconPath, userIconUrl=userIconUrl, **UserData)
@@ -253,7 +293,7 @@ class getAvatarView(TemplateView):
                 return HttpResponse(get_object_response['Body'], content_type="image/jpeg")
             except Exception as e:
                 print(e)
-                return response.json(500, repr(e))
+                return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
         fullPath = os.path.join(BASE_DIR, "static", filePath).replace('\\', '/')
         if os.path.isfile(fullPath):

+ 86 - 0
Object/ContentSecurityObject.py

@@ -0,0 +1,86 @@
+# @Author    : Rocky
+# @File      : ContentSecurityObject.py
+# @Time      : 2023/8/18 11:02
+from alibabacloud_green20220302.client import Client as Green20220302Client
+from alibabacloud_tea_openapi import models as open_api_models
+from alibabacloud_green20220302 import models as green_20220302_models
+from alibabacloud_tea_util import models as util_models
+from Ansjer.config import ALI_ACCESS_KEY_ID, ALI_ACCESS_KEY_SECRET, LOGGER
+
+TEXT_ILLEGAL_LABEL_LIST = ['political_content', 'profanity', 'contraband', 'sexual_content', 'violence',
+                           'negative_content', 'religion', 'cyberbullying']
+IMAGE_ILLEGAL_LABEL_LIST = ['pornographic_adultContent', 'sexual_suggestiveContent', 'political_politicalFigure_1',
+                            'violent_blood', 'contraband_drug']
+
+
+class ContentSecurity:
+    """
+    阿里云内容安全服务类
+    """
+    def __init__(self):
+        pass
+
+    @staticmethod
+    def create_client() -> Green20220302Client:
+        """
+        使用AK&SK初始化账号Client
+        @return: Client
+        @throws Exception
+        """
+        config = open_api_models.Config(
+            # 必填,您的 AccessKey ID,
+            access_key_id=ALI_ACCESS_KEY_ID,
+            # 必填,您的 AccessKey Secret,
+            access_key_secret=ALI_ACCESS_KEY_SECRET
+        )
+        # Endpoint 请参考 https://api.aliyun.com/product/Green
+        config.endpoint = f'green-cip.cn-shanghai.aliyuncs.com'
+        return Green20220302Client(config)
+
+    def text_review(self, service, service_parameters):
+        """
+        文本审核
+        @param service: 审核服务类型
+        @param service_parameters: 审核服务参数集
+        @return: bool, True: 审核通过, False: 审核不通过
+        """
+        client = self.create_client()
+        text_moderation_request = green_20220302_models.TextModerationRequest(service, service_parameters)
+        runtime = util_models.RuntimeOptions()
+        res = client.text_moderation_with_options(text_moderation_request, runtime)
+        print(res)
+        if res.status_code != 200:
+            return False
+        labels = res.body.data.labels
+        labels_list = labels.split(',')
+        for label in labels_list:
+            if label in TEXT_ILLEGAL_LABEL_LIST:
+                return False
+            return True
+
+    def image_review(self, service, service_parameters):
+        """
+        图片审核
+        @param service: 审核服务类型
+        @param service_parameters: 审核服务参数集
+        @return: bool, True: 审核通过, False: 审核不通过
+        """
+        client = self.create_client()
+        image_moderation_request = green_20220302_models.ImageModerationRequest(service, service_parameters)
+        runtime = util_models.RuntimeOptions()
+        res = client.image_moderation_with_options(image_moderation_request, runtime)
+        print(res)
+        LOGGER.info('图片审核响应内容:{}'.format(res))
+        if res.status_code != 200:
+            return False
+        # 获取审核结果
+        result = res.body
+        if result.code != 200:
+            return False
+        result_list = result.data.result
+        # 配到风险标签且置信分高于80时返回False
+        for result in result_list:
+            if result.label in IMAGE_ILLEGAL_LABEL_LIST:
+                if result.confidence >= 80:
+                    return False
+        return True

+ 18 - 5
Object/ResponseObject.py

@@ -1,4 +1,3 @@
-from django.shortcuts import HttpResponse
 import simplejson as json
 from django.shortcuts import HttpResponse
 
@@ -34,7 +33,9 @@ class ResponseObject(object):
             103: 'Mail already existed!',
             104: 'Account doesn\'t exist!',
             105: 'Email format error!',
+            106: 'Illegal profile picture!',
             107: 'The username not conform to the rules!',
+            108: 'Illegal nickname!',
             109: 'The password not conform to the rules!',
             110: 'user doesn\'t activated',
             111: 'Error password',
@@ -50,6 +51,7 @@ class ResponseObject(object):
             179: 'Nickname repeated',
             180: 'Smart button scene trigger conditions cannot be repeated',
             181: 'The gateway only bind 3 smart button at most',
+            182: 'Scene effective time conflict',
             201: 'You can only add 3 custom voice at most',
             306: 'The link has expired!',
             309: 'Please ReLogin! errmsg token',
@@ -78,6 +80,8 @@ class ResponseObject(object):
             904: 'Version does not support this feature!',
             906: 'Cause of file operation error',
             907: 'The download file does not exist!',
+            910: 'Icloud Insufficient capacity!',
+            911: 'No opened Icloud',
             10001: 'Customer number, customer confidentiality error',
             10002: 'Check your configuration: no customer number, customer confidentiality',
             10003: 'The authorization code does not exist. Please reauthorize',
@@ -104,12 +108,14 @@ class ResponseObject(object):
             10038: 'Non device primary user cannot transfer packages',
             10039: 'Activation code has been used',
             10040: 'Invalid activation code',
-            10041: 'This device has purchased a domestic cloud storage package, and cannot purchase a foreign cloud storage package',
+            10041: 'This device has purchased a domestic cloud storage package, '
+                   'and cannot purchase a foreign cloud storage package',
             10042: 'The device has registered a certificate',
             10043: 'The device does not registered a certificate',
             10044: 'Failed to publish MQTT message',
             10045: 'Already the latest version',
-            10046: 'Sorry, users who have activated cloud storage packages do not support logout at the moment, please contact customer service',
+            10046: 'Sorry, users who have activated cloud storage packages do not support logout at the moment, '
+                   'please contact customer service',
             10047: 'Please delete all devices under your account first',
             10048: 'Subscribe to the failure',
             10049: 'The coupon is not available',
@@ -119,11 +125,13 @@ class ResponseObject(object):
             10053: 'The AI service is not purchased',
             10054: 'The AI service has expired',
             10055: 'The AI does not recognize any labels',
-            10056: 'The device has enabled automatic renewal of cloud storage package and cannot be transferred for the time being',
+            10056: 'The device has enabled automatic renewal of cloud storage package and cannot be transferred '
+                   'for the time being',
             10057: "Can't delete",
             10058: 'Default family cannot be deleted',
             10059: 'Order deactivation failure',
-            10060: 'This device has purchased foreign cloud storage package, so it cannot buy domestic cloud storage package',
+            10060: 'This device has purchased foreign cloud storage package, so it cannot buy domestic '
+                   'cloud storage package',
             10061: 'Add the limit reached',
             10062: 'This device has experienced the package',
             10063: 'Failed to claim',
@@ -155,7 +163,9 @@ class ResponseObject(object):
             103: '邮箱已存在!',
             104: '账户不存在!',
             105: '邮箱格式错误!',
+            106: '头像违规!',
             107: '用户名格式不符合!',
+            108: '用户昵称违规!',
             109: '密码格式不符合!',
             110: '用户未激活!',
             111: '密码不正确!',
@@ -171,6 +181,7 @@ class ResponseObject(object):
             179: '名称不能重复',
             180: '智能按钮场景触发条件不能重复',
             181: '该网关最多只能绑定3个智能按钮',
+            182: '场景生效时间冲突',
             201: '最多只能添加3条自定义语音',
             306: '链接已超过有效期!',
             309: '请重新登录!',
@@ -199,6 +210,8 @@ class ResponseObject(object):
             904: '版本不支持本功能!',
             906: '文件操作错误',
             907: '文件不存在!',
+            910: '云盘容量不足!',
+            911: '未开通云盘!',
             10001: '客户编号,客户机密错误',
             10002: '检查您的配置:没有客户编号,客户机密',
             10003: '授权码不存在,请重新授权',