From 7599e5f3a2fa561add8dd40e4fd8362becf07b12 Mon Sep 17 00:00:00 2001 From: youngS Date: Wed, 4 Aug 2021 13:05:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fir_ser/admin/views/login.py | 18 +- fir_ser/admin/views/order.py | 2 +- fir_ser/admin/views/storage.py | 2 +- fir_ser/api/base_views.py | 20 +- fir_ser/api/models.py | 8 +- fir_ser/api/tasks.py | 1 - fir_ser/api/urls.py | 6 +- fir_ser/api/utils/TokenManager.py | 74 ++++---- fir_ser/api/utils/app/apputils.py | 106 +++++------ fir_ser/api/utils/app/iossignapi.py | 126 ++++++------- fir_ser/api/utils/app/shellcmds.py | 8 +- fir_ser/api/utils/app/supersignutils.py | 177 +++++++++--------- fir_ser/api/utils/apple/appleapiv3.py | 35 ++-- fir_ser/api/utils/baseutils.py | 63 ++++++- fir_ser/api/utils/crontab/ctasks.py | 13 +- fir_ser/api/utils/geetest/geetest_lib.py | 20 +- fir_ser/api/utils/geetest/geetest_utils.py | 14 +- fir_ser/api/utils/middlewares.py | 2 +- fir_ser/api/utils/pay/ali.py | 10 +- fir_ser/api/utils/pay/alipay/__init__.py | 1 - fir_ser/api/utils/pay/wx.py | 10 +- fir_ser/api/utils/pay/wxpay/__init__.py | 26 ++- fir_ser/api/utils/sendmsg/sendmsg.py | 91 ++++----- fir_ser/api/utils/serializer.py | 15 +- fir_ser/api/utils/storage/aliyunApi.py | 27 +-- fir_ser/api/utils/storage/caches.py | 48 ++--- fir_ser/api/utils/storage/localApi.py | 35 ++-- fir_ser/api/utils/storage/qiniuApi.py | 18 +- fir_ser/api/utils/storage/storage.py | 46 +++-- fir_ser/api/utils/tempcaches.py | 2 +- fir_ser/api/utils/throttle.py | 2 - fir_ser/api/utils/utils.py | 44 +++-- fir_ser/api/views/apps.py | 203 ++++++++++----------- fir_ser/api/views/domain.py | 23 ++- fir_ser/api/views/download.py | 90 ++++----- fir_ser/api/views/login.py | 78 ++++---- fir_ser/api/views/logout.py | 4 +- fir_ser/api/views/order.py | 20 +- fir_ser/api/views/receiveudids.py | 10 +- fir_ser/api/views/storage.py | 28 ++- fir_ser/api/views/supersign.py | 91 +++++---- fir_ser/api/views/uploads.py | 141 +++++++------- fir_ser/cli/urls.py | 4 +- fir_ser/cli/views/apps.py | 4 +- 44 files changed, 885 insertions(+), 881 deletions(-) diff --git a/fir_ser/admin/views/login.py b/fir_ser/admin/views/login.py index 6b33088..0568c32 100644 --- a/fir_ser/admin/views/login.py +++ b/fir_ser/admin/views/login.py @@ -11,9 +11,8 @@ from api.utils.auth import ExpiringTokenAuthentication from api.utils.serializer import UserInfoSerializer from django.core.cache import cache from rest_framework.views import APIView -import binascii import os, datetime -from api.utils.utils import get_captcha, valid_captcha +from api.utils.utils import get_captcha, valid_captcha, set_user_token from api.utils.response import BaseResponse from fir_ser.settings import CACHE_KEY_TEMPLATE, LOGIN from api.utils.storage.caches import login_auth_failed @@ -26,9 +25,6 @@ logger = logging.getLogger(__name__) class LoginView(APIView): throttle_classes = [VisitRegister1Throttle, VisitRegister2Throttle] - def generate_key(self): - return binascii.hexlify(os.urandom(32)).decode() - def post(self, request): response = BaseResponse() receive = request.data @@ -41,18 +37,12 @@ class LoginView(APIView): if login_auth_failed("get", username): password = receive.get("password") user = auth.authenticate(username=username, password=password) - logger.info("username:%s password:%s" % (username, password)) + logger.info(f"username:{username} password:{password}") if user: if user.is_active: if user.role == 3: login_auth_failed("del", username) - # update the token - key = self.generate_key() - now = datetime.datetime.now() - user_info = UserInfo.objects.get(pk=user.pk) - auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), key]) - cache.set(auth_key, {'uid': user_info.uid, 'username': user_info.username}, 3600 * 24 * 7) - Token.objects.create(user=user, **{"access_token": key, "created": now}) + key, user_info = set_user_token(user) response.data = { "username": user_info.username, "token": key @@ -69,7 +59,7 @@ class LoginView(APIView): response.code = 1002 else: response.code = 1006 - logger.error("username:%s failed too try , locked" % (username,)) + logger.error(f"username:{username} failed too try , locked") response.msg = "用户登录失败次数过多,已被锁定,请1小时之后再次尝试" else: response.code = 1001 diff --git a/fir_ser/admin/views/order.py b/fir_ser/admin/views/order.py index 5bc1445..462f4e1 100644 --- a/fir_ser/admin/views/order.py +++ b/fir_ser/admin/views/order.py @@ -87,7 +87,7 @@ class OrderPayView(APIView): return Response(res.dict) obj = UserInfo.objects.filter(pk=pk).first() if obj: - logger.info("user %s update storage data:%s" % (obj, data)) + logger.info(f"user {obj} update storage data:{data}") use_storage_id = data.get("use_storage_id", None) force = data.get("force", None) if use_storage_id: diff --git a/fir_ser/admin/views/storage.py b/fir_ser/admin/views/storage.py index c6fdab8..b182c30 100644 --- a/fir_ser/admin/views/storage.py +++ b/fir_ser/admin/views/storage.py @@ -88,7 +88,7 @@ class StorageChangeView(APIView): return Response(res.dict) obj = UserInfo.objects.filter(pk=pk).first() if obj: - logger.info("user %s update storage data:%s" % (obj, data)) + logger.info(f"user {obj} update storage data:{data}") use_storage_id = data.get("use_storage_id", None) force = data.get("force", None) if use_storage_id: diff --git a/fir_ser/api/base_views.py b/fir_ser/api/base_views.py index a842559..8902b47 100644 --- a/fir_ser/api/base_views.py +++ b/fir_ser/api/base_views.py @@ -8,9 +8,9 @@ from api.utils.response import BaseResponse from api.utils.app.supersignutils import IosUtils from api.utils.storage.storage import Storage -from api.utils.storage.caches import del_cache_response_by_short, get_app_today_download_times, del_cache_by_delete_app, \ +from api.utils.storage.caches import del_cache_response_by_short, del_cache_by_delete_app, \ del_cache_storage -from api.models import Apps, AppReleaseInfo, APPToDeveloper, AppIOSDeveloperInfo, UserInfo, AppScreenShot, AppStorage +from api.models import AppReleaseInfo, APPToDeveloper, UserInfo, AppScreenShot, AppStorage import logging from api.utils.utils import delete_local_files, delete_app_screenshots_files, change_storage_and_change_head_img, \ migrating_storage_data, clean_storage_data, check_storage_is_new_storage @@ -27,21 +27,19 @@ def app_delete(app_obj): user_obj = app_obj.user_id count = APPToDeveloper.objects.filter(app_id=app_obj).count() if app_obj.issupersign or count > 0: - logger.info("app_id:%s is supersign ,delete this app need clean IOS developer" % (app_obj.app_id)) + logger.info(f"app_id:{app_obj.app_id} is supersign ,delete this app need clean IOS developer") IosUtils.clean_app_by_user_obj(app_obj, user_obj) storage = Storage(user_obj) has_combo = app_obj.has_combo if has_combo: logger.info( - "app_id:%s has_combo ,delete this app need uncombo and clean del_cache_response_by_short" % ( - app_obj.app_id)) + f"app_id:{app_obj.app_id} has_combo ,delete this app need uncombo and clean del_cache_response_by_short") has_combo.has_combo = None del_cache_response_by_short(app_obj.app_id) del_cache_by_delete_app(app_obj.app_id) for app_release_obj in AppReleaseInfo.objects.filter(app_id=app_obj).all(): - logger.info("delete app_id:%s need clean all release,release_id:%s" % ( - app_obj.app_id, app_release_obj.release_id)) + logger.info(f"delete app_id:{app_obj.app_id} need clean all release,release_id:{app_release_obj.release_id}") storage.delete_file(app_release_obj.release_id, app_release_obj.release_type) delete_local_files(app_release_obj.release_id, app_release_obj.release_type) storage.delete_file(app_release_obj.icon_url) @@ -67,17 +65,17 @@ def app_release_delete(app_obj, release_id, storage): apprelease_count = AppReleaseInfo.objects.filter(app_id=app_obj).values("release_id").count() appreleaseobj = AppReleaseInfo.objects.filter(app_id=app_obj, release_id=release_id).first() if not appreleaseobj.is_master: - logger.info("delete app release %s" % (appreleaseobj)) + logger.info(f"delete app release {appreleaseobj}") storage.delete_file(appreleaseobj.release_id, appreleaseobj.release_type) delete_local_files(appreleaseobj.release_id, appreleaseobj.release_type) storage.delete_file(appreleaseobj.icon_url) appreleaseobj.delete() elif appreleaseobj.is_master and apprelease_count < 2: - logger.info("delete app master release %s and clean app %s " % (appreleaseobj, app_obj)) + logger.info(f"delete app master release {appreleaseobj} and clean app {app_obj} ") count = APPToDeveloper.objects.filter(app_id=app_obj).count() if app_obj.issupersign or count > 0: - logger.info("app_id:%s is supersign ,delete this app need clean IOS developer" % (app_obj.app_id)) + logger.info(f"app_id:{app_obj.app_id} is supersign ,delete this app need clean IOS developer") IosUtils.clean_app_by_user_obj(app_obj, user_obj) storage.delete_file(appreleaseobj.release_id, appreleaseobj.release_type) @@ -118,7 +116,7 @@ def storage_change(use_storage_id, user_obj, force): UserInfo.objects.filter(pk=user_obj.pk).update(storage_id=use_storage_id) except Exception as e: - logger.error("update user %s storage failed Exception:%s" % (user_obj, e)) + logger.error(f"update user {user_obj} storage failed Exception:{e}") if force: if use_storage_id == -1: UserInfo.objects.filter(pk=user_obj.pk).update(storage=None) diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index 7c0b904..9e1c818 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -5,7 +5,7 @@ from django.db import models from django.contrib.contenttypes.models import ContentType from api.utils.app.randomstrings import make_random_uuid from django.contrib.auth.models import AbstractUser -from api.utils.TokenManager import generateAlphanumericTokenOfLength, generateNumericTokenOfLength +from api.utils.TokenManager import generate_alphanumeric_token_of_length, generate_numeric_token_of_length ######################################## 用户表 ######################################## @@ -58,7 +58,7 @@ class UserInfo(AbstractUser): if len(self.uid) < 8: self.uid = make_random_uuid() if len(self.api_token) < 8: - self.api_token = self.uid + generateAlphanumericTokenOfLength(64) + self.api_token = self.uid + generate_alphanumeric_token_of_length(64) super(UserInfo, self).save(*args, **kwargs) @@ -93,7 +93,7 @@ class VerifyName(models.Model): verbose_name_plural = "实名认证" def __str__(self): - return "%s" % (self.name) + return f"self.name" ######################################## APP表 ######################################## @@ -456,7 +456,7 @@ class DomainCnameInfo(models.Model): def save(self, *args, **kwargs): if not self.domain_record or (self.domain_record and len(self.domain_record) < 26): # 最多3个启用的价格表 - self.domain_record = '%s.%s' % (generateNumericTokenOfLength(24, 'abcdef'), self.domain_record) + self.domain_record = '%s.%s' % (generate_numeric_token_of_length(24, 'abcdef'), self.domain_record) super(DomainCnameInfo, self).save(*args, **kwargs) def __str__(self): diff --git a/fir_ser/api/tasks.py b/fir_ser/api/tasks.py index beb464f..b52e392 100644 --- a/fir_ser/api/tasks.py +++ b/fir_ser/api/tasks.py @@ -6,7 +6,6 @@ from celery import shared_task from django.core.cache import cache -from celery import Celery from api.utils.storage.storage import get_local_storage diff --git a/fir_ser/api/urls.py b/fir_ser/api/urls.py index 5ffcf2b..4e94658 100644 --- a/fir_ser/api/urls.py +++ b/fir_ser/api/urls.py @@ -13,12 +13,12 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ -from django.urls import path, re_path, include +from django.urls import re_path from api.views.login import LoginView, UserInfoView, RegistView, AuthorizationView, ChangeAuthorizationView, \ UserApiTokenView, CertificationView, ChangeInfoView from api.views.logout import LogoutView -from api.views.apps import AppsView, AppInfoView, AppReleaseinfoView +from api.views.apps import AppsView, AppInfoView, AppReleaseInfoView from api.views.download import ShortDownloadView from api.views.uploads import AppAnalyseView, UploadView from api.views.storage import StorageView @@ -41,7 +41,7 @@ urlpatterns = [ re_path("^apps$", AppsView.as_view()), re_path("^storage$", StorageView.as_view()), re_path(r"^apps/(?P\w+)", AppInfoView.as_view()), - re_path(r"^appinfos/(?P\w+)/(?P\w+)", AppReleaseinfoView.as_view()), + re_path(r"^appinfos/(?P\w+)/(?P\w+)", AppReleaseInfoView.as_view()), re_path("^upload$", UploadView.as_view()), re_path("^userinfo", UserInfoView.as_view()), re_path("^token", UserApiTokenView.as_view()), diff --git a/fir_ser/api/utils/TokenManager.py b/fir_ser/api/utils/TokenManager.py index cec65ca..2916482 100644 --- a/fir_ser/api/utils/TokenManager.py +++ b/fir_ser/api/utils/TokenManager.py @@ -11,59 +11,57 @@ from django.core.cache import cache from fir_ser.settings import CACHE_KEY_TEMPLATE import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) -class DownloadToken(object): +def make_token(release_id, time_limit=60, key='', force_new=False): + token_key = "_".join([key.lower(), CACHE_KEY_TEMPLATE.get("make_token_key"), release_id]) + token = cache.get(token_key) + if token and not force_new: + logger.debug( + f"make_token cache exists get token:{token} release_id:{release_id} force_new:{force_new} token_key:{token_key}") + return token + else: + random_str = uuid.uuid1().__str__().split("-")[0:-1] + user_ran_str = uuid.uuid5(uuid.NAMESPACE_DNS, release_id).__str__().split("-") + user_ran_str.extend(random_str) + token = "".join(user_ran_str) + cache.set(token, { + "atime": time.time() + time_limit, + "data": release_id + }, time_limit) + cache.set(token_key, token, time_limit - 1) + logger.debug( + f"make_token cache not exists get token:{token} release_id:{release_id} force_new:{force_new} token_key:{token_key}") + return token - def make_token(self, release_id, time_limit=60, key='', force_new=False): - token_key = "_".join([key.lower(), CACHE_KEY_TEMPLATE.get("make_token_key"), release_id]) - token = cache.get(token_key) - if token and not force_new: - logger.debug("make_token cache exists get token:%s release_id:%s force_new:%s token_key:%s" % ( - token, release_id, force_new, token_key)) - return token - else: - random_str = uuid.uuid1().__str__().split("-")[0:-1] - user_ran_str = uuid.uuid5(uuid.NAMESPACE_DNS, release_id).__str__().split("-") - user_ran_str.extend(random_str) - token = "".join(user_ran_str) - cache.set(token, { - "atime": time.time() + time_limit, - "data": release_id - }, time_limit) - cache.set(token_key, token, time_limit - 1) - logger.debug( - "make_token cache not exists get token:%s release_id:%s force_new:%s token_key:%s" % ( - token, release_id, force_new, token_key)) - return token - def verify_token(self, token, release_id): - try: - values = cache.get(token) - if values and release_id == values.get("data", None): - logger.debug("verify_token token:%s release_id:%s success" % (token, release_id)) - return True - except Exception as e: - logger.error("verify_token token:%s release_id:%s failed Exception:%s" % (token, release_id, e)) - return False - logger.error("verify_token token:%s release_id:%s failed" % (token, release_id)) +def verify_token(token, release_id): + try: + values = cache.get(token) + if values and release_id == values.get("data", None): + logger.debug(f"verify_token token:{token} release_id:{release_id} success") + return True + except Exception as e: + logger.error(f"verify_token token:{token} release_id:{release_id} failed Exception:{e}") return False + logger.error(f"verify_token token:{token} release_id:{release_id} failed") + return False -def generateTokenForMedium(medium): +def generate_token_for_medium(medium): if medium == 'email': - return generateAlphanumericTokenOfLength(32) + return generate_alphanumeric_token_of_length(32) elif medium == 'wechat': return 'WeChat' else: - return generateNumericTokenOfLength(6) + return generate_numeric_token_of_length(6) -def generateNumericTokenOfLength(length, random_str=''): +def generate_numeric_token_of_length(length, random_str=''): return "".join([random.choice(string.digits + random_str) for _ in range(length)]) -def generateAlphanumericTokenOfLength(length): +def generate_alphanumeric_token_of_length(length): return "".join( [random.choice(string.digits + string.ascii_lowercase + string.ascii_uppercase) for _ in range(length)]) diff --git a/fir_ser/api/utils/app/apputils.py b/fir_ser/api/utils/app/apputils.py index cddcccd..61ef730 100644 --- a/fir_ser/api/utils/app/apputils.py +++ b/fir_ser/api/utils/app/apputils.py @@ -12,7 +12,7 @@ from api.utils.storage.storage import Storage from api.utils.storage.caches import del_cache_response_by_short import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def make_resigned(bin_url, img_url, bundle_id, app_version, name): @@ -27,7 +27,7 @@ def make_resigned(bin_url, img_url, bundle_id, app_version, name): kind software-package url - + kind @@ -35,7 +35,7 @@ def make_resigned(bin_url, img_url, bundle_id, app_version, name): needs-shine 0 url - + kind @@ -43,26 +43,26 @@ def make_resigned(bin_url, img_url, bundle_id, app_version, name): needs-shine url - + metadata bundle-identifier - %s + {bundle_id} bundle-version - + kind software title - + -""" % (bin_url, img_url, img_url, bundle_id, app_version, name) - logger.info("make_resigned bin_url %s ,img_url %s, img_url %s, bundle_id %s, app_version %s, name %s" % ( - bin_url, img_url, img_url, bundle_id, app_version, name)) +""".format(bin_url=bin_url, img_url=img_url, bundle_id=bundle_id, app_version=app_version, name=name) + logger.info( + f"make_resigned bin_url {bin_url} ,img_url {img_url}, bundle_id {bundle_id}, app_version {app_version}, name {name}") return ios_plist_tem @@ -78,10 +78,10 @@ def bytes2human(n): return '%sB' % n -def get_release_type(app_file_name, appinfo): +def get_release_type(app_file_name, app_info): extension = app_file_name.split(".")[1] if extension == "ipa": - release_type = appinfo.get("release_type") + release_type = app_info.get("release_type") if release_type == "Adhoc": # Adhoc: 内测版 Inhouse:企业版 return 1 elif release_type == "Inhouse": @@ -106,94 +106,94 @@ def get_random_short(): short_url = ''.join(random.sample( ['z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'], 4)) - appobj = Apps.objects.filter(short=short_url).first() - if appobj: + app_obj = Apps.objects.filter(short=short_url).first() + if app_obj: return get_random_short() else: return short_url -def SaveAppInfos(app_file_name, user_obj, appinfo, bundle_id, app_img, short, size): +def save_app_infos(app_file_name, user_obj, app_info, bundle_id, app_img, short, size): app_uuid = make_app_uuid(user_obj, bundle_id + app_file_name.split(".")[1]) ##判断是否存在该app - appmobj = Apps.objects.filter(app_id=app_uuid, user_id=user_obj).first() + app_obj = Apps.objects.filter(app_id=app_uuid, user_id=user_obj).first() storage = Storage(user_obj) - newapp = False - if not appmobj: - newapp = True + is_new_app = False + if not app_obj: + is_new_app = True appdata = { "app_id": app_uuid, "user_id": user_obj, "type": get_app_type(app_file_name), - "name": appinfo["labelname"], - "new_bundle_name": appinfo["labelname"], + "name": app_info["labelname"], + "new_bundle_name": app_info["labelname"], "short": short, "bundle_id": bundle_id, "count_hits": 0, "wxeasytype": False if get_user_domain_name(user_obj) else True } try: - appmobj = Apps.objects.create(**appdata) + app_obj = Apps.objects.create(**appdata) except Exception as e: - logger.error("create new app failed,appdata:%s Exception:%s" % (appdata, e)) + logger.error(f"create new app failed,appdata:{appdata} Exception:{e}") return False else: try: - newapp = False - appmobj.short = short - appmobj.name = appinfo["labelname"] + is_new_app = False + app_obj.short = short + app_obj.name = app_info["labelname"] # appmobj.wxeasytype = False if user_obj.domain_name or appmobj.domain_name else True - appmobj.bundle_id = bundle_id - appmobj.save() - del_cache_response_by_short(appmobj.app_id) + app_obj.bundle_id = bundle_id + app_obj.save() + del_cache_response_by_short(app_obj.app_id) except Exception as e: - logger.error("save app info failed,appmobj:%s Exception:%s" % (appmobj, e)) - appmobj.bundle_id = bundle_id - appmobj.name = appinfo["labelname"] - appmobj.save() + logger.error(f"save app info failed,app_obj:{app_obj} Exception:{e}") + app_obj.bundle_id = bundle_id + app_obj.name = app_info["labelname"] + app_obj.save() - AppReleaseInfo.objects.filter(app_id=appmobj).update(**{"is_master": False}) + AppReleaseInfo.objects.filter(app_id=app_obj).update(**{"is_master": False}) release_data = { - "app_id": appmobj, + "app_id": app_obj, "icon_url": app_img, "release_id": app_file_name.split(".")[0], - "build_version": str(appinfo.get("version", "latest")), - "app_version": str(appinfo.get("versioncode", "latest")), - "release_type": get_release_type(app_file_name, appinfo), - "minimum_os_version": str(appinfo.get("miniOSversion", "latest")), + "build_version": str(app_info.get("version", "latest")), + "app_version": str(app_info.get("versioncode", "latest")), + "release_type": get_release_type(app_file_name, app_info), + "minimum_os_version": str(app_info.get("miniOSversion", "latest")), "binary_size": size, "is_master": True, - "changelog": appinfo.get("changelog", ''), - "udid": appinfo.get("udid", ''), - "distribution_name": appinfo.get("distribution_name", ''), + "changelog": app_info.get("changelog", ''), + "udid": app_info.get("udid", ''), + "distribution_name": app_info.get("distribution_name", ''), } try: AppReleaseInfo.objects.create(**release_data) except Exception as e: - logging.error("create app release failed,release_data:%s Exception:%s" % (release_data, e)) - if newapp: - logger.info("create app release failed,release_data:%s ,and app is new ,so delete this app:%s" % ( - release_data, appmobj)) - appmobj.delete() + logger.error(f"create app release failed,release_data:{release_data} Exception:{e}") + if is_new_app: + logger.info( + f"create app release failed,release_data:{release_data} ,and app is new ,so delete this app:{app_obj}") + app_obj.delete() return False try: history_release_limit = int(user_obj.history_release_limit) except Exception as e: - logger.error("get history_release_limit failed,history_release_limit:%s Exception:%s" % ( - user_obj.history_release_limit, e)) + logger.error( + f"get history_release_limit failed,history_release_limit:{user_obj.history_release_limit} Exception:{e}") return True if history_release_limit != 0: - release_queryset = AppReleaseInfo.objects.filter(app_id=appmobj).order_by("-created_time") + release_queryset = AppReleaseInfo.objects.filter(app_id=app_obj).order_by("-created_time") if release_queryset.count() > history_release_limit: flag = 0 for release_obj in release_queryset: flag += 1 if flag > history_release_limit: - logging.info("history_release_limit:%s this release is to more,so delete it release_id:%s" % ( - history_release_limit, release_obj.release_id)) - storage.delete_file(release_obj.release_id, appmobj.type) + logger.info( + f"history_release_limit:{history_release_limit} this release is to more,so delete it release_id:{release_obj.release_id}") + storage.delete_file(release_obj.release_id, app_obj.type) storage.delete_file(release_obj.icon_url) release_obj.delete() return True diff --git a/fir_ser/api/utils/app/iossignapi.py b/fir_ser/api/utils/app/iossignapi.py index c91c818..4f7b360 100644 --- a/fir_ser/api/utils/app/iossignapi.py +++ b/fir_ser/api/utils/app/iossignapi.py @@ -16,25 +16,25 @@ import base64 from OpenSSL.crypto import (load_pkcs12, dump_certificate_request, dump_privatekey, PKey, TYPE_RSA, X509Req, dump_certificate, load_privatekey, load_certificate, PKCS12, FILETYPE_PEM, FILETYPE_ASN1) -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def exec_shell(cmd, remote=False, timeout=None): if remote: - hostip = "10.66.6.66" + host_ip = "10.66.6.66" port = 65534 user = "root" passwd = "root" - result = use_user_pass(hostip, port, user, passwd, cmd) + result = use_user_pass(host_ip, port, user, passwd, cmd) return result else: - logger.info("exec_shell cmd:%s" % (cmd)) + logger.info(f"exec_shell cmd:{cmd}") result = shell_command(cmd, timeout) - logger.info("exec_shell cmd:%s result:%s" % (cmd, result)) + logger.info(f"exec_shell cmd:{cmd} result:{result}") if result.get("exit_code") != 0: err_info = result.get("err_info", None) if err_info: - logger.error("exec_shell cmd:%s failed: %s" % (cmd, err_info)) + logger.error(f"exec_shell cmd:{cmd} failed: {err_info}") result["err_info"] = "Unknown Error" return False, result return True, result @@ -49,17 +49,17 @@ class ResignApp(object): self.cmd = "zsign -c '%s' -k '%s' " % (self.app_dev_pem, self.my_local_key) @staticmethod - def sign_mobileconfig(mobilconfig_path, sign_mobilconfig_path, ssl_pem_path, ssl_key_path): - ''' - :param mobilconfig_path: 描述文件绝对路径 - :param sign_mobilconfig_path: 签名之后的文件绝对路径 + def sign_mobile_config(mobile_config_path, sign_mobile_config_path, ssl_pem_path, ssl_key_path): + """ + :param mobile_config_path: 描述文件绝对路径 + :param sign_mobile_config_path: 签名之后的文件绝对路径 :param ssl_pem_path: pem证书的绝对路径 :param ssl_key_path: key证书的绝对路径 :return: - ''' + """ cmd = "openssl smime -sign -in %s -out %s -signer %s " \ "-inkey %s -certfile %s -outform der -nodetach " % ( - mobilconfig_path, sign_mobilconfig_path, ssl_pem_path, ssl_key_path, ssl_pem_path) + mobile_config_path, sign_mobile_config_path, ssl_pem_path, ssl_key_path, ssl_pem_path) return exec_shell(cmd) def make_p12_from_cert(self, password): @@ -132,12 +132,42 @@ class ResignApp(object): return exec_shell(self.cmd) +def make_csr_content(csr_file_path, private_key_path): + # create public/private key + key = PKey() + key.generate_key(TYPE_RSA, 2048) + # Generate CSR + req = X509Req() + req.get_subject().CN = 'FLY APP' + req.get_subject().O = 'FLY APP Inc' + req.get_subject().OU = 'IT' + req.get_subject().L = 'BJ' + req.get_subject().ST = 'BJ' + req.get_subject().C = 'CN' + req.get_subject().emailAddress = 'flyapps@126.com' + req.set_pubkey(key) + req.sign(key, 'sha256') + csr_content = dump_certificate_request(FILETYPE_PEM, req) + with open(csr_file_path, 'wb+') as f: + f.write(csr_content) + with open(private_key_path, 'wb+') as f: + f.write(dump_privatekey(FILETYPE_PEM, key)) + + return csr_content + + +def make_pem(cer_content, pem_path): + cert = load_certificate(FILETYPE_ASN1, cer_content) + with open(pem_path, 'wb+') as f: + f.write(dump_certificate(FILETYPE_PEM, cert)) + + class AppDeveloperApiV2(object): - def __init__(self, issuer_id, private_key_id, p8key, certid): + def __init__(self, issuer_id, private_key_id, p8key, cert_id): self.issuer_id = issuer_id self.private_key_id = private_key_id self.p8key = p8key - self.certid = certid + self.cert_id = cert_id def active(self): result = {'data': []} @@ -145,11 +175,11 @@ class AppDeveloperApiV2(object): apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) certificates = apple_obj.get_all_certificates() result['data'] = certificates - logger.info("ios developer active result:%s" % certificates) + logger.info(f"ios developer active result:{certificates}") if len(certificates) > 0: return True, result except Exception as e: - logger.error("ios developer active Failed Exception:%s" % e) + logger.error(f"ios developer active Failed Exception:{e}") result['return_info'] = "%s" % e return False, result @@ -160,34 +190,6 @@ class AppDeveloperApiV2(object): os.makedirs(cert_dir_path) return os.path.join(cert_dir_path, cert_dir_name) - def make_csr_content(self, csr_file_path, private_key_path): - # create public/private key - key = PKey() - key.generate_key(TYPE_RSA, 2048) - # Generate CSR - req = X509Req() - req.get_subject().CN = 'FLY APP' - req.get_subject().O = 'FLY APP Inc' - req.get_subject().OU = 'IT' - req.get_subject().L = 'BJ' - req.get_subject().ST = 'BJ' - req.get_subject().C = 'CN' - req.get_subject().emailAddress = 'flyapps@126.com' - req.set_pubkey(key) - req.sign(key, 'sha256') - csr_content = dump_certificate_request(FILETYPE_PEM, req) - with open(csr_file_path, 'wb+') as f: - f.write(csr_content) - with open(private_key_path, 'wb+') as f: - f.write(dump_privatekey(FILETYPE_PEM, key)) - - return csr_content - - def make_pem(self, cer_content, pem_path): - cert = load_certificate(FILETYPE_ASN1, cer_content) - with open(pem_path, 'wb+') as f: - f.write(dump_certificate(FILETYPE_PEM, cert)) - def create_cert(self, user_obj): result = {} try: @@ -195,51 +197,51 @@ class AppDeveloperApiV2(object): csr_path = self.file_format_path_name(user_obj) if not os.path.isdir(os.path.dirname(csr_path)): os.makedirs(os.path.dirname(csr_path)) - csr_content = self.make_csr_content(csr_path + ".csr", csr_path + ".key") + csr_content = make_csr_content(csr_path + ".csr", csr_path + ".key") certificates = apple_obj.create_certificate(csr_content.decode("utf-8")) if certificates: n = base64.b64decode(certificates.certificateContent) with open(csr_path + ".cer", 'wb') as f: f.write(n) - self.make_pem(n, csr_path + ".pem") - logger.info("ios developer create cert result:%s" % certificates.certificateContent) + make_pem(n, csr_path + ".pem") + logger.info(f"ios developer create cert result:{certificates.certificateContent}") return True, certificates except Exception as e: - logger.error("ios developer create cert Failed Exception:%s" % e) + logger.error(f"ios developer create cert Failed Exception:{e}") result['return_info'] = "%s" % e return False, result - def get_cert_obj_by_cid(self, cert_id): + def get_cert_obj_by_cid(self): result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) - cert_obj = apple_obj.get_certificate_by_cid(cert_id) + cert_obj = apple_obj.get_certificate_by_cid(self.cert_id) if cert_obj and cert_obj.id: return True, result else: - logger.info("ios developer get cert %s failed" % cert_id) + logger.info(f"ios developer get cert {self.cert_id} failed") return False, result except Exception as e: - logger.error("ios developer get cert %s Failed Exception:%s" % (cert_id, e)) + logger.error(f"ios developer get cert {self.cert_id} Failed Exception:{e}") result['return_info'] = "%s" % e return False, result - def revoke_cert(self, cert_id): + def revoke_cert(self): result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) - cert_obj = apple_obj.get_certificate_by_cid(cert_id) + cert_obj = apple_obj.get_certificate_by_cid(self.cert_id) if cert_obj: s_date = format_apple_date(cert_obj.expirationDate) if s_date.timestamp() - datetime.datetime.now().timestamp() < 3600 * 24 * 3: - if apple_obj.revoke_certificate(cert_id): - logger.info("ios developer cert %s revoke" % cert_id) + if apple_obj.revoke_certificate(self.cert_id): + logger.info(f"ios developer cert {self.cert_id} revoke") return True, result else: - logger.info("ios developer cert %s not revoke.because expire time < 3 day " % cert_id) + logger.info(f"ios developer cert {self.cert_id} not revoke.because expire time < 3 day ") return True, result except Exception as e: - logger.error("ios developer cert %s revoke Failed Exception:%s" % (cert_id, e)) + logger.error(f"ios developer cert {self.cert_id} revoke Failed Exception:{e}") result['return_info'] = "%s" % e return False, result @@ -252,12 +254,12 @@ class AppDeveloperApiV2(object): certificates = apple_obj.get_all_certificates() for cert_obj in certificates: f_date = format_apple_date(cert_obj.expirationDate) - logger.info("%s-%s - %s " % (cert_obj.id, not_after.timestamp(), f_date.timestamp())) + logger.info(f"{cert_obj.id}-{not_after.timestamp()} - {f_date.timestamp()} ") if not_after.timestamp() == f_date.timestamp(): return True, cert_obj return False, result except Exception as e: - logger.error("ios developer cert %s auto get Failed Exception:%s" % (111, e)) + logger.error(f"ios developer cert {app_dev_pem} auto get Failed Exception:{e}") result['return_info'] = "%s" % e return False, result @@ -297,7 +299,7 @@ class AppDeveloperApiV2(object): f.write(n) return True, result except Exception as e: - logger.error("ios developer make profile Failed Exception:%s" % e) + logger.error(f"app_id {app_obj.app_id} ios developer make profile Failed Exception:{e}") result['return_info'] = "%s" % e return False, result @@ -310,7 +312,7 @@ class AppDeveloperApiV2(object): if apple_obj.delete_profile_by_id(profile_obj.id): return True, profile_obj except Exception as e: - logger.error("ios developer delete profile Failed Exception:%s" % e) + logger.error(f"ios developer delete profile Failed Exception:{e}") result['return_info'] = "%s" % e return False, result diff --git a/fir_ser/api/utils/app/shellcmds.py b/fir_ser/api/utils/app/shellcmds.py index 33c0a19..8410044 100644 --- a/fir_ser/api/utils/app/shellcmds.py +++ b/fir_ser/api/utils/app/shellcmds.py @@ -9,7 +9,7 @@ import logging import paramiko, json import socket -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def default_result(): @@ -109,7 +109,7 @@ def shell_command(cmdstrs, timeout): out = out.strip(b'\n') result['return_info'] = out result['exit_code'] = child.returncode - logging.info(u'shell: %s - %s%s - %s%d' % (cmdstrs, 'return_info: ', out, 'exit_code: ', child.returncode)) + logger.info(f'shell: {cmdstrs} - return_info:{out} - exit_code:{child.returncode}') return result @@ -131,8 +131,6 @@ def use_user_pass(hostip, port, user, passwd, cmdstrs): outs = outs.strip('\n') result['return_info'] = outs result['exit_code'] = out['status'] - # logging.info(u'shell: %s - %s%s - %s%d' % (cmdstrs, 'return_info: ', out, 'exit_code: ', out['status'])) - logger.info('host: %s user:%s - shell: %s - %s%s - %s%d' % ( - hostip, user, cmdstrs, 'return_info: ', out, 'exit_code: ', out['status'])) + logger.info(f'host: {hostip} user:{user} - shell: {cmdstrs} - return_info:{out} - exit_code:{out["status"]}') conn.close() return result diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index cce16b8..dd2a842 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -6,7 +6,6 @@ import uuid, xmltodict, os, re, logging, time -from django.utils import timezone import zipfile from api.utils.response import BaseResponse from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, SERVER_DOMAIN, MOBILECONFIG_SIGN_SSL, MSGTEMPLATE @@ -23,7 +22,7 @@ from api.utils.baseutils import file_format_path, delete_app_profile_file, get_p from api.utils.storage.storage import Storage from django.core.cache import cache -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def check_org_file(user_obj, org_file): @@ -41,9 +40,9 @@ def resign_by_app_id(app_obj, need_download_profile=True): user_obj = app_obj.user_id info_list = [] if app_obj.issupersign and user_obj.supersign_active: - for dappid_obj in DeveloperAppID.objects.filter(app_id=app_obj).all(): - developer_obj = dappid_obj.developerid - developer_app_id = dappid_obj.aid + for developer_app_id_obj in DeveloperAppID.objects.filter(app_id=app_obj).all(): + developer_obj = developer_app_id_obj.developerid + developer_app_id = developer_app_id_obj.aid d_time = time.time() if need_download_profile: with cache.lock("%s_%s_%s" % ('download_profile', app_obj.app_id, developer_obj.issuer_id), timeout=60): @@ -77,59 +76,59 @@ def udid_bytes_to_dict(xml_stream): for i in range(len(xml_dict['plist']['dict']['key'])): new_uuid_info[xml_dict['plist']['dict']['key'][i].lower()] = xml_dict['plist']['dict']['string'][i] except Exception as e: - logger.error("udid_xml_stream:%s Exception:%s" % (xml_stream, e)) + logger.error(f"udid_xml_stream:{xml_stream} Exception:{e}") return None return new_uuid_info -def make_sign_udid_mobileconfig(udid_url, PayloadOrganization, appname): +def make_sign_udid_mobile_config(udid_url, payload_organization, app_name): if MOBILECONFIG_SIGN_SSL.get("open"): ssl_key_path = MOBILECONFIG_SIGN_SSL.get("ssl_key_path", None) ssl_pem_path = MOBILECONFIG_SIGN_SSL.get("ssl_pem_path", None) if ssl_key_path and ssl_pem_path and os.path.isfile(ssl_key_path) and os.path.isfile(ssl_pem_path): - mobileconfig_tmp_dir = os.path.join(SUPER_SIGN_ROOT, 'tmp', 'mobileconfig') - if not os.path.exists(mobileconfig_tmp_dir): - os.makedirs(mobileconfig_tmp_dir) + mobile_config_tmp_dir = os.path.join(SUPER_SIGN_ROOT, 'tmp', 'mobile_config') + if not os.path.exists(mobile_config_tmp_dir): + os.makedirs(mobile_config_tmp_dir) - mobileconfig_filename = PayloadOrganization + str(uuid.uuid1()) - mobilconfig_path = os.path.join(mobileconfig_tmp_dir, mobileconfig_filename) + mobile_config_filename = payload_organization + str(uuid.uuid1()) + mobile_config_path = os.path.join(mobile_config_tmp_dir, mobile_config_filename) - sign_mobilconfig_path = os.path.join(mobileconfig_tmp_dir, 'sign_' + mobileconfig_filename) - with open(mobilconfig_path, "w") as f: - f.write(make_udid_mobileconfig(udid_url, PayloadOrganization, appname)) + sign_mobile_config_path = os.path.join(mobile_config_tmp_dir, 'sign_' + mobile_config_filename) + with open(mobile_config_path, "w") as f: + f.write(make_udid_mobile_config(udid_url, payload_organization, app_name)) - status, result = ResignApp.sign_mobileconfig(mobilconfig_path, sign_mobilconfig_path, ssl_pem_path, - ssl_key_path) + status, result = ResignApp.sign_mobile_config(mobile_config_path, sign_mobile_config_path, ssl_pem_path, + ssl_key_path) if status: - mobileconfig_body = open(sign_mobilconfig_path, 'rb') + mobile_config_body = open(sign_mobile_config_path, 'rb') else: logger.error( - "%s %s sign_mobileconfig failed ERROR:%s" % (PayloadOrganization, appname, result.get("err_info"))) - return make_udid_mobileconfig(udid_url, PayloadOrganization, appname) + f"{payload_organization} {app_name} sign_mobile_config failed ERROR:{result.get('err_info')}") + return make_udid_mobile_config(udid_url, payload_organization, app_name) - return mobileconfig_body + return mobile_config_body else: - logger.error("sign_mobileconfig %s or %s is not exists" % (ssl_key_path, ssl_pem_path)) - return make_udid_mobileconfig(udid_url, PayloadOrganization, appname) + logger.error(f"sign_mobile_config {ssl_key_path} or {ssl_pem_path} is not exists") + return make_udid_mobile_config(udid_url, payload_organization, app_name) else: - return make_udid_mobileconfig(udid_url, PayloadOrganization, appname) + return make_udid_mobile_config(udid_url, payload_organization, app_name) -def make_udid_mobileconfig(udid_url, PayloadOrganization, appname, PayloadUUID=uuid.uuid1(), - PayloadDescription='该文件仅用来获取设备ID,帮助用户安装授权', - PayloadDisplayName='设备安装授权'): +def make_udid_mobile_config(udid_url, payload_organization, app_name, payload_uuid=uuid.uuid1(), + payload_description='该文件仅用来获取设备ID,帮助用户安装授权', + display_name='设备安装授权'): # - mobileconfig = ''' + return f''' PayloadContent URL - %s + {udid_url} DeviceAttributes SERIAL @@ -141,29 +140,27 @@ def make_udid_mobileconfig(udid_url, PayloadOrganization, appname, PayloadUUID=u PayloadOrganization - %s + {payload_organization} PayloadDisplayName - %s + {app_name}--{display_name} PayloadVersion 1 PayloadUUID - %s + {payload_uuid} PayloadIdentifier - %s.profile-service + {payload_organization}.profile-service PayloadDescription - %s + {payload_description} PayloadType Profile Service -''' % (udid_url, PayloadOrganization, appname + " -- " + PayloadDisplayName, PayloadUUID, PayloadOrganization, - PayloadDescription) - return mobileconfig +''' def get_post_udid_url(request, short): - server_domain = get_http_server_doamin(request) - PATH_INFO_lists = [server_domain, "udid", short] - udid_url = "/".join(PATH_INFO_lists) + server_domain = get_http_server_domain(request) + path_info_lists = [server_domain, "udid", short] + udid_url = "/".join(path_info_lists) return udid_url @@ -189,24 +186,24 @@ def get_api_obj(auth): def get_apple_udid_key(auth): - mpkey = '' + m_key = '' if auth.get("issuer_id"): - mpkey = auth.get("issuer_id") - return mpkey + m_key = auth.get("issuer_id") + return m_key def get_server_domain_from_request(request, server_domain): if not server_domain or not server_domain.startswith("http"): - HTTP_HOST = request.META.get('HTTP_HOST') - SERVER_PROTOCOL = request.META.get('SERVER_PROTOCOL') + http_host = request.META.get('HTTP_HOST') + server_protocol = request.META.get('SERVER_PROTOCOL') protocol = 'https' - if SERVER_PROTOCOL == 'HTTP/1.1': + if server_protocol == 'HTTP/1.1': protocol = 'http' - server_domain = "%s://%s" % (protocol, HTTP_HOST) + server_domain = "%s://%s" % (protocol, http_host) return server_domain -def get_http_server_doamin(request): +def get_http_server_domain(request): server_domain = SERVER_DOMAIN.get('POST_UDID_DOMAIN', None) return get_server_domain_from_request(request, server_domain) @@ -245,7 +242,7 @@ class IosUtils(object): if self.developer_obj: self.auth = get_auth_form_developer(self.developer_obj) else: - logger.error("user %s has no actived apple developer" % self.user_obj) + logger.error(f"user {self.user_obj} has no active apple developer") if self.user_obj.email: if send_msg_over_limit("get", self.user_obj.email): send_msg_over_limit("set", self.user_obj.email) @@ -253,15 +250,15 @@ class IosUtils(object): % ( self.user_obj.first_name, self.app_obj.name)) else: - logger.error("user %s send msg failed. over limit" % self.user_obj) + logger.error(f"user {self.user_obj} send msg failed. over limit") def get_developer_user_by_app_udid(self): - usedeviceobj = APPSuperSignUsedInfo.objects.filter(udid__udid=self.udid_info.get('udid'), - user_id=self.user_obj, developerid__is_actived=True, - developerid__certid__isnull=False).first() + use_device_obj = APPSuperSignUsedInfo.objects.filter(udid__udid=self.udid_info.get('udid'), + user_id=self.user_obj, developerid__is_actived=True, + developerid__certid__isnull=False).first() # 只要账户下面存在udid,就可以使用该苹果开发者账户,避免多个开发者账户下面出现同一个udid - if usedeviceobj: - developer_obj = usedeviceobj.developerid + if use_device_obj: + developer_obj = use_device_obj.developerid else: developer_udid_obj = UDIDsyncDeveloper.objects.filter(udid=self.udid_info.get('udid'), developerid__is_actived=True, @@ -271,9 +268,7 @@ class IosUtils(object): else: for developer_obj in AppIOSDeveloperInfo.objects.filter(user_id=self.user_obj, is_actived=True, certid__isnull=False).order_by("created_time"): - usable_number = developer_obj.usable_number - flyapp_used = get_developer_udided(developer_obj)[1] - if flyapp_used < usable_number: + if get_developer_udided(developer_obj)[1] < developer_obj.usable_number: return developer_obj return None return developer_obj @@ -307,19 +302,20 @@ class IosUtils(object): def exec_download_profile(app_obj, developer_obj, udid_info, sign_try_attempts=3): result = {} developer_app_id = None - add_did_flag = False auth = get_auth_form_developer(developer_obj) while sign_try_attempts > 0: - logger.info("exec_download_profile appid:%s developer:%s sign_try_attempts:%s" % ( - app_obj, developer_obj, sign_try_attempts)) + logger.info( + f"exec_download_profile app_id:{app_obj} developer:{developer_obj} sign_try_attempts:{sign_try_attempts}") device_id_list = DeveloperDevicesID.objects.filter(app_id=app_obj, developerid=developer_obj).values_list('did') device_id_lists = [did[0] for did in device_id_list] developer_app_id = None - developer_appid_obj = DeveloperAppID.objects.filter(developerid=developer_obj, - app_id=app_obj).first() - if developer_appid_obj: - developer_app_id = developer_appid_obj.aid + add_did_flag = False + sync_device_obj = None + developer_app_id_obj = DeveloperAppID.objects.filter(developerid=developer_obj, + app_id=app_obj).first() + if developer_app_id_obj: + developer_app_id = developer_app_id_obj.aid if udid_info: sync_device_obj = UDIDsyncDeveloper.objects.filter(udid=udid_info.get('udid'), developerid=developer_obj).first() @@ -327,23 +323,22 @@ class IosUtils(object): device_id_lists.append(sync_device_obj.serial) udid_info = None add_did_flag = True - logger.info( - "app %s device %s already in developer %s" % (app_obj, sync_device_obj.serial, developer_obj)) + logger.info(f"app {app_obj} device {sync_device_obj.serial} already in developer {developer_obj}") status, result = get_api_obj(auth).get_profile(app_obj, udid_info, get_profile_full_path(developer_obj, app_obj), auth, developer_app_id, device_id_lists) - if add_did_flag: + if add_did_flag and sync_device_obj: result['did'] = sync_device_obj.serial result['did_exists'] = True if not status: sign_try_attempts -= 1 - logger.warning("app %s developer %s sign failed %s .try again " % (app_obj, developer_obj, result)) + logger.warning(f"app {app_obj} developer {developer_obj} sign failed {result} .try again ") time.sleep(3) else: sign_try_attempts = -1 if sign_try_attempts != -1: - logger.error("app %s developer %s sign failed %s" % (app_obj, developer_obj, result)) + logger.error(f"app {app_obj} developer {developer_obj} sign failed {result}") developer_obj.is_actived = False developer_obj.save() send_ios_developer_active_status(developer_obj.user_id, @@ -394,11 +389,10 @@ class IosUtils(object): status, result = resign_app_obj.sign(get_profile_full_path(developer_obj, app_obj), org_file, new_file, properties_info) if status: - logger.info("%s %s %s sign_ipa success" % (user_obj, developer_obj, app_obj)) + logger.info(f"{user_obj} {developer_obj} {app_obj} sign_ipa success") return True, result else: - logger.error( - "%s %s %s sign_ipa failed ERROR:%s" % (user_obj, developer_obj, app_obj, result.get("err_info"))) + logger.error(f"{user_obj} {developer_obj} {app_obj} sign_ipa failed ERROR:{result.get('err_info')}") return False, result @staticmethod @@ -423,8 +417,8 @@ class IosUtils(object): if appsupersign_obj.count() == 0: developer_obj = self.developer_obj developer_obj.use_number = developer_obj.use_number + 1 - logger.info("developer %s use_number+1 now %s udid %s app_id %s" % ( - developer_obj, developer_obj.use_number, self.udid_info.get('udid'), self.app_obj)) + logger.info( + f"developer {developer_obj} use_number+1 now {developer_obj.use_number} udid {self.udid_info.get('udid')} app_id {self.app_obj}") developer_obj.save() if not appsupersign_obj.filter(app_id=self.app_obj, user_id=self.user_obj).first(): @@ -451,13 +445,13 @@ class IosUtils(object): d_result = {'code': 0, 'msg': 'success'} start_time = time.time() if download_flag: - logger.info("app_id %s download profile success. time:%s" % (app_obj, start_time - d_time)) + logger.info(f"app_id {app_obj} download profile success. time:{start_time - d_time}") random_file_name = make_from_user_uuid(user_obj) release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first() status, e_result = IosUtils.exec_sign(user_obj, app_obj, developer_obj, random_file_name, release_obj) if status: s_time1 = time.time() - logger.info("app_id %s exec sign ipa success. time:%s" % (app_obj, s_time1 - start_time)) + logger.info(f"app_id {app_obj} exec sign ipa success. time:{s_time1 - start_time}") if resign: IosUtils.update_sign_file_name(user_obj, app_obj, developer_obj, release_obj, random_file_name) else: @@ -465,12 +459,12 @@ class IosUtils(object): else: return status, e_result else: - msg = "app_id %s download profile failed. %s time:%s" % (app_obj, result, time.time() - start_time) + msg = f"app_id {app_obj} download profile failed. {result} time:{time.time() - start_time}" d_result['code'] = 1002 d_result['msg'] = msg logger.error(d_result) return False, d_result - msg = "app_id %s developer %s sign end... time:%s" % (app_obj, developer_obj, time.time() - start_time) + msg = f"app_id {app_obj} developer {developer_obj} sign end... time:{time.time() - start_time}" logger.info(msg) d_result['msg'] = msg return True, d_result @@ -627,16 +621,16 @@ class IosUtils(object): @staticmethod def clean_app_by_user_obj(app_obj, user_obj): - ''' + """ 该APP为超级签,删除app的时候,需要清理一下开发者账户里面的profile 和 bundleid :param app_obj: :param user_obj: :return: - ''' - SuperSign_obj_lists = list( + """ + super_sign_obj_lists = list( set(APPSuperSignUsedInfo.objects.values_list("developerid").filter(user_id=user_obj, app_id=app_obj))) - for SuperSign_obj in SuperSign_obj_lists: - developer_obj = AppIOSDeveloperInfo.objects.filter(pk=SuperSign_obj[0]).first() + for super_sign_obj in super_sign_obj_lists: + developer_obj = AppIOSDeveloperInfo.objects.filter(pk=super_sign_obj[0]).first() if developer_obj: IosUtils.clean_app_by_developer_obj(app_obj, developer_obj) delete_app_to_dev_and_file(developer_obj, app_obj.id) @@ -655,13 +649,13 @@ class IosUtils(object): @staticmethod def clean_developer(developer_obj, user_obj, cert_id=None): - ''' + """ 根据消耗记录 删除该苹果账户下所有信息 :param user_obj: :param cert_id: :param developer_obj: :return: - ''' + """ for APPToDeveloper_obj in APPToDeveloper.objects.filter(developerid=developer_obj): app_obj = APPToDeveloper_obj.app_id IosUtils.clean_app_by_developer_obj(app_obj, developer_obj, cert_id) @@ -688,12 +682,11 @@ class IosUtils(object): @staticmethod def active_developer(developer_obj): - ''' + """ 激活开发者账户 :param developer_obj: - :param code: :return: - ''' + """ auth = get_auth_form_developer(developer_obj) app_api_obj = get_api_obj(auth) status, result = app_api_obj.active() @@ -742,7 +735,7 @@ class IosUtils(object): def revoke_developer_cert(developer_obj, user_obj): auth = get_auth_form_developer(developer_obj) app_api_obj = get_api_obj(auth) - status, result = app_api_obj.revoke_cert(developer_obj.certid) + status, result = app_api_obj.revoke_cert() if not status: logger.warning('%s revoke cert failed,but i need clean cert_id %s' % (developer_obj.issuer_id, result)) AppIOSDeveloperInfo.objects.filter(user_id=user_obj, issuer_id=auth.get("issuer_id")).update( @@ -755,14 +748,14 @@ class IosUtils(object): # 暂时无用 auth = get_auth_form_developer(developer_obj) app_api_obj = get_api_obj(auth) - status, result = app_api_obj.get_cert_obj_by_cid(developer_obj.certid) + status, result = app_api_obj.get_cert_obj_by_cid() if not status: AppIOSDeveloperInfo.objects.filter(user_id=user_obj, issuer_id=auth.get("issuer_id")).update( certid=None, cert_expire_time=None) return status, result @staticmethod - def auto_get_certid_by_p12(developer_obj, user_obj): + def auto_get_cert_id_by_p12(developer_obj, user_obj): auth = get_auth_form_developer(developer_obj) app_api_obj = get_api_obj(auth) file_format_path_name = file_format_path(user_obj, auth) diff --git a/fir_ser/api/utils/apple/appleapiv3.py b/fir_ser/api/utils/apple/appleapiv3.py index 276b813..875b27d 100644 --- a/fir_ser/api/utils/apple/appleapiv3.py +++ b/fir_ser/api/utils/apple/appleapiv3.py @@ -13,7 +13,7 @@ import jwt import logging from collections import namedtuple -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) # https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api @@ -22,7 +22,7 @@ logger = logging.getLogger(__file__) def request_format_log(req): try: - logger.info("url:%s header:%s code:%s body:%s" % (req.url, req.headers, req.status_code, req.content)) + logger.info(f"url:{req.url} header:{req.headers} code:{req.status_code} body:{req.content}") except Exception as e: logger.error(e) return req @@ -273,6 +273,7 @@ class BundleIDsCapabilityAPI(object): def disable_capability(self, bundle_id, capability_type): """ + :param capability_type: :param bundle_id: :return: 204 No Content @@ -652,13 +653,13 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi JWT_ALG = 'ES256' def __init__(self, issuer_id, private_key_id, p8_private_key, exp_seconds=1200): - ''' + """ 根据 Apple 文档,会话最长持续时间为 20 分钟:https : //developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests :param issuer_id: :param private_key_id: :param p8_private_key: :param exp_seconds: max 20*60 - ''' + """ self.issuer_id = issuer_id self.private_key_id = private_key_id self.p8_private_key = p8_private_key @@ -678,10 +679,10 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi self.rate_limit_info[limit_info_list[0]] = limit_info_list[1] user_rem_info = self.rate_limit_info if int(user_rem_info.get('user-hour-rem')) < 3595: - logger.warning("user-hour-rem over limit. so get jwt headers") + logger.warning(f"user-hour-rem over limit. so get jwt headers") self.__init__(self.issuer_id, self.private_key_id, self.p8_private_key) self.rate_limit_info = user_rem_info - logger.info("rate_limit_info:%s" % self.rate_limit_info) + logger.info(f"rate_limit_info:{self.rate_limit_info}") def __make_jwt_headers(self): data = { @@ -700,7 +701,7 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi } self.headers = headers - def __base_format(self, stype, req, success_code): + def __base_format(self, s_type, req, success_code): # self.__set_rate_limit_info(req.headers) if req.status_code == success_code: req_data = req.json() @@ -709,20 +710,20 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi obj = None if isinstance(data, dict): data = [data] - if stype == 'devices': + if s_type == 'devices': obj = Devices.from_json_list(data) - elif stype == 'bundleIds': + elif s_type == 'bundleIds': obj = BundleIds.from_json_list(data) - elif stype == 'profiles': + elif s_type == 'profiles': obj = Profiles.from_json_list(data) - elif stype == 'certificates': + elif s_type == 'certificates': obj = Certificates.from_json_list(data) if len(obj) == 1: return obj[0] return obj else: # self.__init_jwt_headers() - raise Exception('error: %s' % (req.text)) + raise Exception(f'error instance: {req.text}') elif req.status_code == 401: # 授权问题 raise Exception(req.text) elif req.status_code == 429: # 请求超过每小时限制 {'user-hour-lim': '3600', 'user-hour-rem': '3586'} @@ -809,9 +810,9 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi for capability in capability_list: req = super().enable_capability(bundle_id, capability) if self.__do_success(req, 201): - logger.info("%s enable_capability %s success" % (bundle_id, capability)) + logger.info(f"{bundle_id} enable_capability {capability} success") else: - logger.warning("%s enable_capability %s failed %s" % (bundle_id, capability, req.content)) + logger.warning(f"{bundle_id} enable_capability {capability} failed {req.content}") return True def disable_capability_by_s_type(self, bundle_id, s_type=len(capability) - 1): @@ -820,13 +821,12 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi for capability in capability_list: req = super().disable_capability(bundle_id, capability) if self.__do_success(req, 204): - logger.info("%s enable_capability %s success" % (bundle_id, capability)) + logger.info(f"{bundle_id} enable_capability {capability} success") else: - logger.warning("%s enable_capability %s failed %s" % (bundle_id, capability, req.content)) + logger.warning(f"{bundle_id} enable_capability {capability} failed {req.content}") return True def enable_push_vpn_capability(self, bundle_id): - # 'PUSH_NOTIFICATIONS', # PERSONAL_VPN , NETWORK_EXTENSIONS req = super().enable_capability(bundle_id, 'PUSH_NOTIFICATIONS') if self.__do_success(req, 201): req = super().enable_capability(bundle_id, 'PERSONAL_VPN') @@ -835,7 +835,6 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi return False def disable_push_vpn_capability(self, bundle_id): - # 'PUSH_NOTIFICATIONS', # PERSONAL_VPN req = super().disable_capability(bundle_id, 'PUSH_NOTIFICATIONS') if self.__do_success(req, 204): req = super().disable_capability(bundle_id, 'PERSONAL_VPN') diff --git a/fir_ser/api/utils/baseutils.py b/fir_ser/api/utils/baseutils.py index b3fa14a..d69f305 100644 --- a/fir_ser/api/utils/baseutils.py +++ b/fir_ser/api/utils/baseutils.py @@ -50,23 +50,70 @@ def delete_app_profile_file(developer_obj, app_obj): if os.path.isfile(file): os.remove(file) except Exception as e: - logger.error("delete_app_profile_file developer_obj:%s app_obj:%s file:%s Exception:%s" % ( - developer_obj, app_obj, file, e)) + logger.error( + f"delete_app_profile_file developer_obj:{developer_obj} app_obj:{app_obj} file:{file} Exception:{e}") def is_valid_domain(value): pattern = re.compile( - r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|' - r'([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|' + r'^(([a-zA-Z])|([a-zA-Z][a-zA-Z])|' + r'([a-zA-Z][0-9])|([0-9][a-zA-Z])|' r'([a-zA-Z0-9][-_.a-zA-Z0-9]{0,61}[a-zA-Z0-9]))\.' r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$' ) return True if pattern.match(value) else False +def is_telephone_number(telephone): + if len(telephone) == 11: + if re.match(r"^1(?:749)\d{7}$", telephone): + return 'MSC' # 海事卫星通信的 + elif re.match(r"^174(?:0[6-9]|1[0-2])\d{6}$", telephone): + return 'MCC' # 工信部应急通信的 + elif re.match(r"^1(?:349)\d{7}$", telephone): + return 'CM_SMC' # 中国移动卫星通信 + elif re.match(r"^1(?:740[0-5])\d{6}$", telephone): + return 'CT_SMC' # 中国电信卫星通信 + elif re.match(r"^1(?:47)\d{8}$", telephone): + return 'CM_IDC' # 中国移动上网数据卡 + elif re.match(r"^1(?:45)\d{8}$", telephone): + return 'CU_IDC' # 中国联通上网数据卡 + elif re.match(r"^1(?:49)\d{8}$", telephone): + return 'CT_IDC' # 中国电信上网数据卡 + elif re.match(r"^1(?:70[356]|65\d)\d{7}$", telephone): + return 'CM_VNO' # 中国移动虚拟运营商 + elif re.match(r"^1(?:70[4,7-9]|71\d|67\d)\d{7}$", telephone): + return 'CU_VNO' # 中国联通虚拟运营商 + elif re.match(r"^1(?:70[0-2]|62\d)\d{7}$", telephone): + return 'CT_VNO' # 中国电信虚拟运营商 + elif re.match(r"^1(?:34[0-8]|3[5-9]\d|5[0-2,7-9]\d|7[28]\d|8[2-4,7-8]\d|9[5,7,8]\d)\d{7}$", telephone): + return 'CM_BO' # 中国移动 + elif re.match(r"^1(?:3[0-2]|[578][56]|66|96)\d{8}$", telephone): + return 'CU_BO' # 中国联通 + elif re.match(r"^1(?:33|53|7[37]|8[019]|9[0139])\d{8}$", telephone): + return 'CT_BO' # 中国电信 + elif re.match(r"^1(?:92)\d{8}$", telephone): + return 'CBN_BO' # 中国广电 + else: + return False + elif len(telephone) == 13: + if re.match(r"^14(?:40|8\d)\d{9}$", telephone): + return 'CM_IoT' # 中国移动物联网数据卡 + elif re.match(r"^14(?:00|6\d)\d{9}$", telephone): + return 'CU_IoT' # 中国联通物联网数据卡 + elif re.match(r"^14(?:10)\d{9}$", telephone): + return 'CT_IoT' # 中国电信物联网数据卡 + else: + return False + else: + return False + + def is_valid_phone(value): - phone_pat = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$') - return True if str(value) and re.search(phone_pat, str(value)) else False + # phone_pat = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$') + # return True if str(value) and re.search(phone_pat, str(value)) else False + logger.info(f"valid phone {value}") + return str(value) and is_telephone_number(str(value)) def is_valid_email(email): @@ -112,9 +159,9 @@ def get_cname_from_domain(domain): while count: try: dns_resolver.nameservers = dns_list[len(dns_list) - count] - return dns_resolver.query(domain, 'CNAME')[0].to_text() + return dns_resolver.resolve(domain, 'CNAME')[0].to_text() except Exception as e: - logger.error("dns %s resolve %s failed Exception:%s" % (dns_resolver.nameservers, domain, e)) + logger.error(f"dns {dns_resolver.nameservers} resolve {domain} failed Exception:{e}") count -= 1 time.sleep(0.3) if count <= 0: diff --git a/fir_ser/api/utils/crontab/ctasks.py b/fir_ser/api/utils/crontab/ctasks.py index f6a8f63..185ca47 100644 --- a/fir_ser/api/utils/crontab/ctasks.py +++ b/fir_ser/api/utils/crontab/ctasks.py @@ -13,7 +13,7 @@ from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE, SUPER_S import time, os import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def sync_download_times(): @@ -23,7 +23,7 @@ def sync_download_times(): count_hits = cache.get(app_download) app_id = app_download.split(down_tem_key)[1].strip('_') Apps.objects.filter(app_id=app_id).update(count_hits=count_hits) - logger.info("sync_download_times app_id:%s count_hits:%s" % (app_id, count_hits)) + logger.info(f"sync_download_times app_id:{app_id} count_hits:{count_hits}") def auto_clean_upload_tmp_file(): @@ -40,10 +40,10 @@ def auto_clean_upload_tmp_file(): filename = data.get("filename", None) if filename: storage.delete_file(filename) - logger.info("auto_clean_upload_tmp_file delete_file :%s " % (filename)) + logger.info(f"auto_clean_upload_tmp_file delete_file :{filename}") cache.delete(upload_tem_file_key) - logger.info("auto_clean_upload_tmp_file upload_tem_file_key :%s " % (upload_tem_file_key)) + logger.info(f"auto_clean_upload_tmp_file upload_tem_file_key :{upload_tem_file_key}") def auto_delete_tmp_file(): @@ -57,7 +57,7 @@ def auto_delete_tmp_file(): try: os.remove(file_path) except Exception as e: - logger.error("auto_delete_tmp_file %s Failed . Exception %s" % (file_path, e)) + logger.error(f"auto_delete_tmp_file {file_path} Failed . Exception {e}") def auto_check_ios_developer_active(): @@ -66,8 +66,7 @@ def auto_check_ios_developer_active(): userinfo = ios_developer.user_id if userinfo.supersign_active: status, result = IosUtils.active_developer(ios_developer) - msg = "auto_check_ios_developer_active user:%s ios.developer:%s status:%s result:%s" % ( - userinfo, ios_developer, status, result) + msg = f"auto_check_ios_developer_active user:{userinfo} ios.developer:{ios_developer} status:{status} result:{result}" if status: logger.info(msg) else: diff --git a/fir_ser/api/utils/geetest/geetest_lib.py b/fir_ser/api/utils/geetest/geetest_lib.py index 32bad49..02cf6e8 100644 --- a/fir_ser/api/utils/geetest/geetest_lib.py +++ b/fir_ser/api/utils/geetest/geetest_lib.py @@ -81,14 +81,16 @@ class GeetestLib: self.libResult.set_all(1, data, "") # 正常流程下(即验证初始化成功),二次验证 - def successValidate(self, challenge, validate, seccode, param_dict={}): + def success_validate(self, challenge, validate, seccode, param_dict=None): + if param_dict is None: + param_dict = {} self.gtlog( - "successValidate(): 开始二次验证 正常模式, challenge={0}, validate={1}, seccode={2}.".format(challenge, validate, - seccode)) + "success_validate(): 开始二次验证 正常模式, challenge={0}, validate={1}, seccode={2}.".format(challenge, validate, + seccode)) if not self.check_param(challenge, validate, seccode): self.libResult.set_all(0, "", "正常模式,本地校验,参数challenge、validate、seccode不可为空") else: - response_seccode = self.requestValidate(challenge, validate, seccode, param_dict) + response_seccode = self.request_validate(challenge, validate, seccode, param_dict) if not response_seccode: self.libResult.set_all(0, "", "请求极验validate接口失败") elif response_seccode == "false": @@ -100,19 +102,19 @@ class GeetestLib: # 异常流程下(即验证初始化失败,宕机模式),二次验证 # 注意:由于是宕机模式,初衷是保证验证业务不会中断正常业务,所以此处只作简单的参数校验,可自行设计逻辑。 - def failValidate(self, challenge, validate, seccode): + def fail_validate(self, challenge, validate, seccode): self.gtlog( - "failValidate(): 开始二次验证 宕机模式, challenge={0}, validate={1}, seccode={2}.".format(challenge, validate, - seccode)) + "fail_validate(): 开始二次验证 宕机模式, challenge={0}, validate={1}, seccode={2}.".format(challenge, validate, + seccode)) if not self.check_param(challenge, validate, seccode): self.libResult.set_all(0, "", "宕机模式,本地校验,参数challenge、validate、seccode不可为空.") else: self.libResult.set_all(1, "", "") - self.gtlog("failValidate(): 二次验证 宕机模式, lib包返回信息={0}.".format(self.libResult)) + self.gtlog("fail_validate(): 二次验证 宕机模式, lib包返回信息={0}.".format(self.libResult)) return self.libResult # 向极验发送二次验证的请求,POST方式 - def requestValidate(self, challenge, validate, seccode, param_dict): + def request_validate(self, challenge, validate, seccode, param_dict): param_dict.update( {"seccode": seccode, "json_format": self.JSON_FORMAT, "challenge": challenge, "sdk": self.VERSION, "captchaid": self.geetest_id}) diff --git a/fir_ser/api/utils/geetest/geetest_utils.py b/fir_ser/api/utils/geetest/geetest_utils.py index ceedec9..0bf13d5 100644 --- a/fir_ser/api/utils/geetest/geetest_utils.py +++ b/fir_ser/api/utils/geetest/geetest_utils.py @@ -12,7 +12,7 @@ from fir_ser.settings import GEETEST_ID, GEETEST_KEY, GEETEST_BYPASS_URL, \ GEETEST_BYPASS_STATUS_KEY from api.utils.geetest.geetest_lib import GeetestLib -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) # 发送bypass请求,获取bypass状态并进行缓存(如何缓存可根据自身情况合理选择,这里是使用redis进行缓存) @@ -22,16 +22,16 @@ def check_bypass_status(): try: response = requests.get(url=GEETEST_BYPASS_URL, params=params) except Exception as e: - logger.error("check_bypass_status failed Exception:%s" % e) + logger.error(f"check_bypass_status failed Exception:{e}") if response and response.status_code == 200: - logger.debug("check_bypass_status success %s" % response.content) + logger.debug(f"check_bypass_status success {response.content}") bypass_status_str = response.content.decode("utf-8") bypass_status = json.loads(bypass_status_str).get("status") redis_connect.set(GEETEST_BYPASS_STATUS_KEY, bypass_status) else: bypass_status = "fail" redis_connect.set(GEETEST_BYPASS_STATUS_KEY, bypass_status) - logger.debug("bypass状态已经获取并存入redis,当前状态为 {}".format(bypass_status)) + logger.debug(f"bypass状态已经获取并存入redis,当前状态为 {bypass_status}") # 从缓存中取出当前缓存的bypass状态(success/fail) @@ -70,13 +70,13 @@ def second_validate(rdata): bypass_status = get_bypass_cache() gt_lib = GeetestLib(GEETEST_ID, GEETEST_KEY) if bypass_status == "success": - result = gt_lib.successValidate(challenge, validate, seccode) + result = gt_lib.success_validate(challenge, validate, seccode) else: - result = gt_lib.failValidate(challenge, validate, seccode) + result = gt_lib.fail_validate(challenge, validate, seccode) # 注意,不要更改返回的结构和值类型 if result.status == 1: response = {"result": "success", "version": GeetestLib.VERSION} else: response = {"result": "fail", "version": GeetestLib.VERSION, "msg": result.msg} - logger.info("geetest second_validate info %s" % response) + logger.info(f"geetest second_validate info {response}") return response diff --git a/fir_ser/api/utils/middlewares.py b/fir_ser/api/utils/middlewares.py index a0e7127..f8b6092 100644 --- a/fir_ser/api/utils/middlewares.py +++ b/fir_ser/api/utils/middlewares.py @@ -1,7 +1,7 @@ from django.utils.deprecation import MiddlewareMixin import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class CorsMiddleWare(MiddlewareMixin): diff --git a/fir_ser/api/utils/pay/ali.py b/fir_ser/api/utils/pay/ali.py index 46a8a57..5ed7d68 100644 --- a/fir_ser/api/utils/pay/ali.py +++ b/fir_ser/api/utils/pay/ali.py @@ -13,7 +13,7 @@ from api.utils.storage.caches import update_order_info, update_order_status import json import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class Alipay(object): @@ -56,7 +56,7 @@ class Alipay(object): signature = data.pop("sign") success = self.alipay.verify(data, signature) if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"): - logger.info("付款成功,等待下一步验证 %s" % data) + logger.info(f"付款成功,等待下一步验证 {data}") app_id = data.get("app_id", "") if app_id == self.ali_config.get("APP_ID"): out_trade_no = data.get("out_trade_no", "") # 服务器订单号 @@ -67,15 +67,15 @@ class Alipay(object): payment_number = data.get("trade_no", "") return update_order_info(user_id, out_trade_no, payment_number, 1) else: - logger.error("passback_params %s user_id not exists" % passback_params) + logger.error(f"passback_params {passback_params} user_id not exists") else: - logger.error("APP_ID 校验失败 response: %s server: %s" % (app_id, self.ali_config.get("APP_ID"))) + logger.error(f"APP_ID 校验失败 response: {app_id} server: {self.ali_config.get('APP_ID')}") return False def update_order_status(self, out_trade_no): data = self.alipay.api_alipay_trade_query(out_trade_no=out_trade_no) code = data.get("code", '') - logger.info("out_trade_no: %s info:%s" % (out_trade_no, data)) + logger.info(f"out_trade_no: {out_trade_no} info:{data}") if code == '10000': trade_status = data.get("trade_status", '') if trade_status in ['TRADE_SUCCESS']: diff --git a/fir_ser/api/utils/pay/alipay/__init__.py b/fir_ser/api/utils/pay/alipay/__init__.py index abeff97..c3205bf 100644 --- a/fir_ser/api/utils/pay/alipay/__init__.py +++ b/fir_ser/api/utils/pay/alipay/__init__.py @@ -210,7 +210,6 @@ class BaseAliPay: data = self.build_body(api_name, biz_content, **kwargs) # alipay.trade.query => alipay_trade_query_response response_type = api_name.replace(".", "_") + "_response" - print(data) return self.verified_sync_response(data, response_type) def api_alipay_trade_wap_pay( diff --git a/fir_ser/api/utils/pay/wx.py b/fir_ser/api/utils/pay/wx.py index ffd6ce0..03fadd7 100644 --- a/fir_ser/api/utils/pay/wx.py +++ b/fir_ser/api/utils/pay/wx.py @@ -10,7 +10,7 @@ from api.utils.storage.caches import update_order_info, update_order_status import json import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class Weixinpay(object): @@ -54,7 +54,7 @@ class Weixinpay(object): } result = self.wxpay.decrypt_callback(headers, request.body.decode('utf-8')) if result: - logger.info("付款成功,等待下一步验证 %s" % result) + logger.info(f"付款成功,等待下一步验证 {result}") data = json.loads(result) passback_params = data.get("attach", "") out_trade_no = data.get("out_trade_no", "") @@ -64,16 +64,16 @@ class Weixinpay(object): transaction_id = data.get("transaction_id", "") return update_order_info(user_id, out_trade_no, transaction_id, 0) else: - logger.error("passback_params %s user_id not exists" % passback_params) + logger.error(f"passback_params {passback_params} user_id not exists") else: - logger.error("消息解密失败") + logger.error(f"消息解密失败 {request.body}") return False def update_order_status(self, out_trade_no): code, data = self.wxpay.query(out_trade_no=out_trade_no) # (0, '交易成功'), (1, '待支付'), (2, '订单已创建'), (3, '退费申请中'), (4, '已退费'), (5, '主动取消'), (6, '超时取消') data = json.loads(data) - logger.info("out_trade_no: %s info:%s" % (out_trade_no, data)) + logger.info(f"out_trade_no: {out_trade_no} info:{data}") if code == 200: trade_status = data.get("trade_state", '') if trade_status in ['SUCCESS']: diff --git a/fir_ser/api/utils/pay/wxpay/__init__.py b/fir_ser/api/utils/pay/wxpay/__init__.py index 1eed32e..8dac0b2 100644 --- a/fir_ser/api/utils/pay/wxpay/__init__.py +++ b/fir_ser/api/utils/pay/wxpay/__init__.py @@ -1,11 +1,10 @@ # -*- coding: utf-8 -*- -import json from enum import Enum from .core import Core, RequestType -class WeChatPay(): +class WeChatPay(object): def __init__(self, wechatpay_type, mchid, @@ -17,10 +16,10 @@ class WeChatPay(): """ :param wechatpay_type: 微信支付类型,示例值:WeChatPayType.MINIPROG :param mchid: 直连商户号,示例值:'1230000109' - :param mch_private_key: 商户证书私钥,示例值:'MIIEvwIBADANBgkqhkiG9w0BAQE...' - :param mch_key_serial_no: 商户证书序列号,示例值:'444F4864EA9B34415...' + :param parivate_key: 商户证书私钥,示例值:'MIIEvwIBADANBgkqhkiG9w0BAQE...' + :param cert_serial_no: 商户证书序列号,示例值:'444F4864EA9B34415...' :param appid: 应用ID,示例值:'wxd678efh567hg6787' - :param mch_apiv3_key: 商户APIv3密钥,示例值:'a12d3924fd499edac8a5efc...' + :param apiv3_key: 商户APIv3密钥,示例值:'a12d3924fd499edac8a5efc...' :param notify_url: 通知地址,示例值:'https://www.weixin.qq.com/wxpay/pay.php' """ self._type = wechatpay_type @@ -58,10 +57,7 @@ class WeChatPay(): :param settle_info: 结算信息,示例值:{'profit_sharing':False} :param notify_url: 通知地址,示例值:'https://www.weixin.qq.com/wxpay/pay.php' """ - params = {} - params['appid'] = self._appid - params['mchid'] = self._mchid - params['notify_url'] = notify_url or self._notify_url + params = {'appid': self._appid, 'mchid': self._mchid, 'notify_url': notify_url or self._notify_url} if description: params.update({'description': description}) else: @@ -88,6 +84,7 @@ class WeChatPay(): params.update({'detail': detail}) if settle_info: params.update({'settle_info': settle_info}) + path = "" if self._type in [WeChatPayType.JSAPI, WeChatPayType.MINIPROG]: if not payer: raise Exception('payer is not assigned') @@ -100,7 +97,10 @@ class WeChatPay(): path = '/v3/pay/transactions/h5' elif self._type == WeChatPayType.NATIVE: path = '/v3/pay/transactions/native' - return self._core.request(path, method=RequestType.POST, data=params) + if path: + return self._core.request(path, method=RequestType.POST, data=params) + else: + raise Exception('path is not assigned') def close(self, out_trade_no): """关闭订单 @@ -145,8 +145,7 @@ class WeChatPay(): :param goods_detail: 退款商品,示例值:{'merchant_goods_id':'1217752501201407033233368018', 'wechatpay_goods_id':'1001', 'goods_name':'iPhone6s 16G', 'unit_price':528800, 'refund_amount':528800, 'refund_quantity':1} :param notify_url: 通知地址,示例值:'https://www.weixin.qq.com/wxpay/pay.php' """ - params = {} - params['notify_url'] = notify_url or self._notify_url + params = {'notify_url': notify_url or self._notify_url} if out_refund_no: params.update({'out_refund_no': out_refund_no}) else: @@ -281,8 +280,7 @@ class WeChatPay(): :param sub_orders: 子单信息, 示例值:[{'mchid': '1900000109', 'out_trade_no': '20150806125346'}] :param combine_appid: 合单商户appid, 示例值:'wxd678efh567hg6787' """ - params = {} - params['combine_appid'] = combine_appid or self._appid + params = {'combine_appid': combine_appid or self._appid} if not combine_out_trade_no: raise Exception('combine_out_trade_no is not assigned.') diff --git a/fir_ser/api/utils/sendmsg/sendmsg.py b/fir_ser/api/utils/sendmsg/sendmsg.py index 7a519a9..00ce367 100644 --- a/fir_ser/api/utils/sendmsg/sendmsg.py +++ b/fir_ser/api/utils/sendmsg/sendmsg.py @@ -10,71 +10,74 @@ from .jiguangApi import JiGuangMsgSender from fir_ser.settings import THIRD_PART_CONFIG import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) + + +def get_default_sender(send_type): + """ + sender_type : + 0: 邮件 + 1: 阿里云 + 2: 极光 + """ + sender_lists = THIRD_PART_CONFIG.get('sender') + for sender in sender_lists: + if sender.get("active", None): + sender_type = sender.get('type', None) + auth = sender.get('auth', {}) + if sender_type == 0 and send_type == 0: + return EmailMsgSender(**auth) + if sender_type == 1: + return AliMsgSender(**auth) + elif sender_type == 2: + return JiGuangMsgSender(**auth) + else: + continue + return None + + +def get_sms_sender(): + return get_default_sender(1) + + +def get_email_sender(): + return get_default_sender(0) class SendMessage(object): - def __init__(self, type): - ''' - :param type: sms or email - ''' - self.type = type + def __init__(self, send_type): + """ + :param send_type: sms or email + """ + self.send_type = send_type try: - if type == 'sms': - self.sender = self._get_sms_sender() - elif type == 'email': - self.sender = self._get_email_sender() + if send_type == 'sms': + self.sender = get_sms_sender() + elif send_type == 'email': + self.sender = get_email_sender() if self.sender is None: raise except Exception as e: - logger.error("get %s sender failed Exception:%s" % (type, e)) + logger.error(f"get {send_type} sender failed Exception:{e}") self.sender = None def send_register_msg(self, target, code): status, msg = self.sender.send_register_msg(target, code) - logger.info("send_register_msg target:%s code:%s status:%s msg:%s" % (target, code, status, msg)) + logger.info(f"send_register_msg target:{target} code:{code} status:{status} msg:{msg}") return status, msg def send_change_msg(self, target, code): status, msg = self.sender.send_change_msg(target, code) - logger.info("send_change_msg target:%s code:%s status:%s msg:%s" % (target, code, status, msg)) + logger.info(f"send_change_msg target:{target} code:{code} status:{status} msg:{msg}") return status, msg def send_login_msg(self, target, code): status, msg = self.sender.send_login_msg(target, code) - logger.info("send_login_msg target:%s code:%s status:%s msg:%s" % (target, code, status, msg)) + logger.info(f"send_login_msg target:{target} code:{code} status:{status} msg:{msg}") return status, msg def send_email_msg(self, email, text): - if self.type == 'email': + if self.send_type == 'email': status, msg = self.sender.send_email_msg(email, text) - logger.info("send_email_msg target:%s text:%s status:%s msg:%s" % (email, text, status, msg)) + logger.info(f"send_email_msg target:{email} text:{text} status:{status} msg:{msg}") return status, msg - - def _get_email_sender(self): - return self._get_default_sender(0) - - def _get_sms_sender(self): - return self._get_default_sender(1) - - def _get_default_sender(self, type): - ''' - sender_type : - 0: 邮件 - 1: 阿里云 - 2: 极光 - ''' - sender_lists = THIRD_PART_CONFIG.get('sender') - for sender in sender_lists: - if sender.get("active", None): - sender_type = sender.get('type', None) - auth = sender.get('auth', {}) - if sender_type == 0 and type == 0: - return EmailMsgSender(**auth) - if sender_type == 1: - return AliMsgSender(**auth) - elif sender_type == 2: - return JiGuangMsgSender(**auth) - else: - continue - return None diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index 09ef732..4604211 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -1,7 +1,7 @@ from rest_framework import serializers from api import models +from api.utils.TokenManager import make_token from api.utils.app.apputils import bytes2human -from api.utils.TokenManager import DownloadToken from api.utils.app.supersignutils import get_redirect_server_domain from api.utils.baseutils import get_user_domain_name, get_app_domain_name from api.utils.storage.storage import Storage @@ -9,9 +9,7 @@ from api.utils.utils import get_developer_udided, get_choices_dict, get_choices_ from api.utils.storage.caches import get_user_free_download_times, get_user_cert_auth_status import os, logging -logger = logging.getLogger(__file__) - -token_obj = DownloadToken() +logger = logging.getLogger(__name__) def get_download_url_from_context(self, obj, key, url, force_new=False): @@ -33,8 +31,7 @@ def get_download_url_from_context(self, obj, key, url, force_new=False): storage = None if storage: download_url = storage.get_download_url(os.path.basename(url), 600, key, force_new) - logger.info( - 'get %s download_url %s force_new:%s key:%s' % (os.path.basename(url), download_url, force_new, key)) + logger.info(f'get {os.path.basename(url)} download_url {download_url} force_new:{force_new} key:{key}') return download_url @@ -187,7 +184,7 @@ class AppsSerializer(serializers.ModelSerializer): "binary_url": master_release_obj.binary_url, } - download_token = token_obj.make_token(master_release_obj.release_id, 600, key=key) + download_token = make_token(master_release_obj.release_id, 600, key=key) datainfo["download_token"] = download_token udid_lists = [] try: @@ -284,7 +281,7 @@ class AppsShortSerializer(serializers.ModelSerializer): "binary_url": master_release_obj.binary_url, } - download_token = token_obj.make_token(master_release_obj.release_id, 600, key=key, force_new=True) + download_token = make_token(master_release_obj.release_id, 600, key=key, force_new=True) datainfo["download_token"] = download_token return datainfo else: @@ -322,7 +319,7 @@ class AppReleaseSerializer(serializers.ModelSerializer): return bytes2human(obj.binary_size) def get_download_token(self, obj): - return token_obj.make_token(obj.release_id, 600) + return make_token(obj.release_id, 600) def get_icon_url(self, obj): return get_download_url_from_context(self, obj, '', os.path.basename(obj.icon_url)) diff --git a/fir_ser/api/utils/storage/aliyunApi.py b/fir_ser/api/utils/storage/aliyunApi.py index cdb0213..e0e60eb 100644 --- a/fir_ser/api/utils/storage/aliyunApi.py +++ b/fir_ser/api/utils/storage/aliyunApi.py @@ -16,7 +16,7 @@ import hashlib import time import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) # 以下代码展示了STS的用法,包括角色扮演获取临时用户的密钥、使用临时用户的密钥访问OSS。 @@ -62,19 +62,19 @@ class AliYunCdn(object): if not args: args = "" rand = "0" # "0" by default, other value is ok uid = "0" # "0" by default, other value is ok - sstring = "%s-%s-%s-%s-%s" % (path, exp, rand, uid, self.key) - hashvalue = md5sum(sstring.encode("utf-8")) - auth_key = "%s-%s-%s-%s" % (exp, rand, uid, hashvalue) + ss_string = f"{path}-{exp}-{rand}-{uid}-{self.key}" + hash_value = md5sum(ss_string.encode("utf-8")) + auth_key = f"{exp}-{rand}-{uid}-{hash_value}" if args: - return "%s%s%s%s&auth_key=%s" % (scheme, host, path, args, auth_key) + return f"{scheme}{host}{path}{args}&auth_key={auth_key}" else: - return "%s%s%s%s?auth_key=%s" % (scheme, host, path, args, auth_key) + return f"{scheme}{host}{path}{args}?auth_key={auth_key}" def get_cdn_download_token(self, filename, expires=1800): - uri = "%s/%s" % (self.domain, filename) + uri = f"{self.domain}/{filename}" exp = int(time.time()) + expires download_url = self.a_auth(uri, exp) - logger.info("make cdn download url %s" % download_url) + logger.info(f"make cdn download url {download_url}") return download_url @@ -131,6 +131,7 @@ class AliYunOss(object): req.set_RoleArn(self.sts_role_arn) req.set_RoleSessionName(name) req.set_DurationSeconds(expires) + p_action = "oss:GetObject" if only_put: p_action = ["oss:PutObject", "oss:AbortMultipartUpload"] if only_get: @@ -159,7 +160,7 @@ class AliYunOss(object): token.expiration = oss2.utils.to_unixtime(j['Credentials']['Expiration'], '%Y-%m-%dT%H:%M:%SZ') token.bucket = self.bucket_name token.endpoint = self.endpoint.replace('-internal', '') - logger.info("get aliyun sts token %s" % token.__dict__) + logger.info(f"get aliyun sts token {token.__dict__}") return token def get_upload_token(self, name, expires=1800): @@ -191,9 +192,9 @@ class AliYunOss(object): # bucket = oss2.Bucket(auth, self.endpoint,self.bucket_name) return self.bucket.delete_object(name) - def rename_file(self, oldfilename, newfilename): - self.bucket.copy_object(self.bucket_name, oldfilename, newfilename) - return self.del_file(oldfilename) + def rename_file(self, old_filename, new_filename): + self.bucket.copy_object(self.bucket_name, old_filename, new_filename) + return self.del_file(old_filename) def upload_file(self, local_file_full_path): if os.path.isfile(local_file_full_path): @@ -210,7 +211,7 @@ class AliYunOss(object): # self.bucket.put_object(os.path.basename(local_file_full_path), fileobj) return True else: - logger.error("file %s is not file" % local_file_full_path) + logger.error(f"file {local_file_full_path} is not file") def download_file(self, name, local_file_full_path): dir_path = os.path.dirname(local_file_full_path) diff --git a/fir_ser/api/utils/storage/caches.py b/fir_ser/api/utils/storage/caches.py index 937c6a7..0cb7dbc 100644 --- a/fir_ser/api/utils/storage/caches.py +++ b/fir_ser/api/utils/storage/caches.py @@ -16,7 +16,7 @@ from api.utils.baseutils import get_app_d_count_by_app_id, get_app_domain_name, import logging from django.db.models import F -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def sync_download_times_by_app_id(app_ids): @@ -28,7 +28,7 @@ def sync_download_times_by_app_id(app_ids): for k, v in down_times_lists.items(): app_id = k.split(CACHE_KEY_TEMPLATE.get("download_times_key"))[1].strip('_') Apps.objects.filter(app_id=app_id).update(count_hits=v) - logger.info("sync_download_times_by_app_id app_id:%s count_hits:%s" % (app_id, v)) + logger.info(f"sync_download_times_by_app_id app_id:{app_id} count_hits:{v}") def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', udid=None): @@ -42,17 +42,17 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', else: appudid_obj = AppUDID.objects.filter(app_id_id=app_obj.get("pk"), udid=udid, is_signed=True).first() if appudid_obj: - SuperSign_obj = APPSuperSignUsedInfo.objects.filter(udid__udid=udid, - app_id_id=app_obj.get("pk")).first() - if SuperSign_obj and SuperSign_obj.user_id.supersign_active: - APPToDeveloper_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"), - developerid=SuperSign_obj.developerid).first() - if APPToDeveloper_obj: + super_sign_obj = APPSuperSignUsedInfo.objects.filter(udid__udid=udid, + app_id_id=app_obj.get("pk")).first() + if super_sign_obj and super_sign_obj.user_id.supersign_active: + app_to_developer_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"), + developerid=super_sign_obj.developerid).first() + if app_to_developer_obj: release_obj = AppReleaseInfo.objects.filter(app_id_id=app_obj.get("pk"), is_master=True).first() - if release_obj.release_id == APPToDeveloper_obj.release_file: - binary_file = APPToDeveloper_obj.binary_file + if release_obj.release_id == app_to_developer_obj.release_file: + binary_file = app_to_developer_obj.binary_file else: - binary_file = APPToDeveloper_obj.release_file + binary_file = app_to_developer_obj.release_file return local_storage.get_download_url( binary_file + "." + download_url_type, limit), "" else: @@ -146,7 +146,7 @@ def del_cache_response_by_short(app_id, udid=''): def del_cache_response_by_short_util(short, app_id, udid): - logger.info("del_cache_response_by_short short:%s app_id:%s udid:%s" % (short, app_id, udid)) + logger.info(f"del_cache_response_by_short short:{short} app_id:{app_id} udid:{udid}") key = "_".join([CACHE_KEY_TEMPLATE.get("download_short_key"), short, '*']) for app_download_key in cache.iter_keys(key): cache.delete(app_download_key) @@ -188,7 +188,7 @@ def del_cache_by_app_id(app_id, user_obj): def del_cache_storage(user_obj): - logger.info("del_cache_storage user:%s" % user_obj) + logger.info(f"del_cache_storage user:{user_obj}") for app_obj in Apps.objects.filter(user_id=user_obj): del_cache_response_by_short(app_obj.app_id) del_cache_by_app_id(app_obj.app_id, user_obj) @@ -249,13 +249,13 @@ def limit_cache_util(act, cache_key, cache_limit_times): if cdata: data["count"] = cdata["count"] + 1 data["time"] = time.time() - logger.info("limit_cache_util cache_key:%s data:%s" % (cache_key, data)) + logger.info(f"limit_cache_util cache_key:{cache_key} data:{data}") cache.set(cache_key, data, cache_times) elif act == "get": cdata = cache.get(cache_key) if cdata: if cdata["count"] > limit_times: - logging.error("limit_cache_util cache_key %s over limit ,is locked . cdata:%s" % (cache_key, cdata)) + logger.error(f"limit_cache_util cache_key {cache_key} over limit ,is locked . cdata:{cdata}") return False return True elif act == "del": @@ -263,7 +263,7 @@ def limit_cache_util(act, cache_key, cache_limit_times): def login_auth_failed(act, email): - logger.error("login email:%s act:%s" % (email, act)) + logger.error(f"login email:{email} act:{act}") auth_code_key = "_".join([CACHE_KEY_TEMPLATE.get("login_failed_try_times_key"), email]) return limit_cache_util(act, auth_code_key, SYNC_CACHE_TO_DATABASE.get("try_login_times")) @@ -340,7 +340,7 @@ def consume_user_download_times(user_id, app_id, amount=1, auth_status=False): try: UserInfo.objects.filter(pk=user_id).update(download_times=F('download_times') - amount) except Exception as e: - logger.error("%s download_times less then 0. Exception:%s" % (user_id, e)) + logger.error(f"{user_id} download_times less then 0. Exception:{e}") disable_user_download_times_flag(user_id) del_cache_response_by_short(app_id) return False @@ -360,7 +360,7 @@ def add_user_download_times(user_id, download_times=0): UserInfo.objects.filter(pk=user_id).update(download_times=F('download_times') + download_times) return enable_user_download(user_id) except Exception as e: - logger.error("%s download_times less then 0. Exception:%s" % (user_id, e)) + logger.error(f"{user_id} download_times less then 0. Exception:{e}") return False @@ -390,11 +390,11 @@ def consume_user_download_times_by_app_obj(app_obj): def user_auth_success(user_id): - ''' + """ 认证成功,需要调用该方法增加次数 :param user_id: :return: - ''' + """ get_user_free_download_times(user_id, 'get') get_user_free_download_times(user_id, 'set', USER_FREE_DOWNLOAD_TIMES - AUTH_USER_FREE_DOWNLOAD_TIMES) return enable_user_download(user_id) @@ -429,19 +429,19 @@ def update_order_info(user_id, out_trade_no, payment_number, payment_type): download_times, user_obj.download_times + download_times) order_obj.save() add_user_download_times(user_id, download_times) - logger.info("%s 订单 %s msg:%s" % (user_obj, out_trade_no, order_obj.description)) + logger.info(f"{user_obj} 订单 {out_trade_no} msg:{order_obj.description}") return True except Exception as e: - logger.error("%s 订单 %s 更新失败 Exception:%s" % (user_obj, out_trade_no, e)) + logger.error(f"{user_obj} 订单 {out_trade_no} 更新失败 Exception:{e}") elif order_obj.status == 0: return True else: return False else: - logger.error("%s 订单 %s 订单获取失败,或订单已经支付" % (user_obj, out_trade_no)) + logger.error(f"{user_obj} 订单 {out_trade_no} 订单获取失败,或订单已经支付") except Exception as e: - logger.error("%s download_times less then 0. Exception:%s" % (user_obj, e)) + logger.error(f"{user_obj} download_times less then 0. Exception:{e}") return False diff --git a/fir_ser/api/utils/storage/localApi.py b/fir_ser/api/utils/storage/localApi.py index 31525cb..1b769fb 100644 --- a/fir_ser/api/utils/storage/localApi.py +++ b/fir_ser/api/utils/storage/localApi.py @@ -3,16 +3,16 @@ # project: 3月 # author: liuyu # date: 2020/3/18 -''' +""" 本地存储api -''' -from api.utils.TokenManager import DownloadToken +""" +from api.utils.TokenManager import make_token from api.utils.storage.aliyunApi import AliYunCdn from fir_ser import settings import os import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class LocalStorage(object): @@ -22,22 +22,20 @@ class LocalStorage(object): self.download_auth_type = download_auth_type self.cnd_auth_key = cnd_auth_key - def get_upload_token(self, name, expires): - dtoken = DownloadToken() - return dtoken.make_token(name, expires) + @staticmethod + def get_upload_token(name, expires): + return make_token(name, expires) def get_base_url(self): uri = 'http://' if self.is_https: uri = 'https://' - return "%s%s" % (uri, self.domain_name) + return f"{uri}${self.domain_name}" def get_download_url(self, name, expires=600, force_new=False): - dtoken = DownloadToken() download_url = '/'.join([self.get_base_url(), 'download', name]) if self.download_auth_type == 1: - download_url = "%s?%s=%s" % ( - download_url, settings.DATA_DOWNLOAD_KEY, dtoken.make_token(name, expires, force_new=force_new)) + download_url = f"{download_url}?{settings.DATA_DOWNLOAD_KEY}={make_token(name, expires, force_new=force_new)}" elif self.download_auth_type == 2: cdn_obj = AliYunCdn(self.cnd_auth_key, self.is_https, self.domain_name) download_url = cdn_obj.get_cdn_download_token(name, expires) @@ -45,25 +43,28 @@ class LocalStorage(object): pass return download_url - def del_file(self, name): + @staticmethod + def del_file(name): file = os.path.join(settings.MEDIA_ROOT, name) try: if os.path.isfile(file): os.remove(file) return True except Exception as e: - logger.error("delete file %s failed Exception %s" % (file, e)) + logger.error(f"delete file {file} failed Exception {e}") return False - def rename_file(self, oldfilename, newfilename): + @staticmethod + def rename_file(old_filename, new_filename): try: - os.rename(os.path.join(settings.MEDIA_ROOT, oldfilename), os.path.join(settings.MEDIA_ROOT, newfilename)) + os.rename(os.path.join(settings.MEDIA_ROOT, old_filename), os.path.join(settings.MEDIA_ROOT, new_filename)) return True except Exception as e: - logger.error("rename_file file %s to %s failed Exception %s" % (oldfilename, newfilename, e)) + logger.error(f"rename_file file {old_filename} to {new_filename} failed Exception {e}") return False - def upload_file(self, local_file_full_path): + @staticmethod + def upload_file(local_file_full_path): if os.path.isfile(local_file_full_path): return True return False diff --git a/fir_ser/api/utils/storage/qiniuApi.py b/fir_ser/api/utils/storage/qiniuApi.py index 7dc9dae..98ee645 100644 --- a/fir_ser/api/utils/storage/qiniuApi.py +++ b/fir_ser/api/utils/storage/qiniuApi.py @@ -3,15 +3,15 @@ # project: 3月 # author: liuyu # date: 2020/3/18 -''' +""" 主要是调用七牛云存储,处理七牛云存储的逻辑 -''' +""" from qiniu import Auth, put_file, etag from qiniu import BucketManager import os, requests import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class QiNiuOss(object): @@ -41,7 +41,7 @@ class QiNiuOss(object): uri = 'http://' if self.is_https: uri = 'https://' - base_url = '%s%s/%s' % (uri, self.domain_name, name) + base_url = f'{uri}{self.domain_name}/{name}' # 或者直接输入url的方式下载 # 可以设置token过期时间 private_url = self.qiniu_obj.private_download_url(base_url, expires=expires) @@ -54,9 +54,9 @@ class QiNiuOss(object): ret, info = bucket.delete(self.bucket_name, name) return ret - def rename_file(self, oldfilename, newfilename): + def rename_file(self, old_filename, new_filename): bucket = BucketManager(self.qiniu_obj) - ret, info = bucket.move(self.bucket_name, oldfilename, self.bucket_name, newfilename) + ret, info = bucket.move(self.bucket_name, old_filename, self.bucket_name, new_filename) return ret def upload_file(self, local_file_full_path): @@ -73,15 +73,15 @@ class QiNiuOss(object): os.makedirs(dir_path) req = requests.get(self.get_download_url(name)) if req.status_code != 200: - logger.error("download file %s failed %s" % (name, req.content)) + logger.error(f"download file {name} failed {req.content}") return False try: with open(local_file_full_path, "wb") as f: for chunk in req.iter_content(chunk_size=5120): if chunk: f.write(chunk) - logger.info("save download file %s success" % local_file_full_path) + logger.info(f"save download file {local_file_full_path} success") return True except Exception as e: - logger.error("check download file and move file %s failed Exception %s" % (local_file_full_path, e)) + logger.error(f"check download file and move file {local_file_full_path} failed Exception {e}") return False diff --git a/fir_ser/api/utils/storage/storage.py b/fir_ser/api/utils/storage/storage.py index 5da1eb2..9b79190 100644 --- a/fir_ser/api/utils/storage/storage.py +++ b/fir_ser/api/utils/storage/storage.py @@ -14,7 +14,7 @@ from fir_ser.settings import THIRD_PART_CONFIG, CACHE_KEY_TEMPLATE from django.core.cache import cache import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) def get_storage_auth(storage_obj): @@ -38,7 +38,7 @@ def get_storage(user, assigned_storage_obj, use_default_storage): storage_type = storage_obj.storage_type new_storage_obj = cache.get(storage_key) if new_storage_obj and not assigned_storage_obj: - logger.info("user %s get storage obj %s cache %s" % (user, storage_key, new_storage_obj)) + logger.info(f"user {user} get storage obj {storage_key} cache {new_storage_obj}") return new_storage_obj else: if storage_type == 1: @@ -47,12 +47,12 @@ def get_storage(user, assigned_storage_obj, use_default_storage): new_storage_obj = AliYunOss(**auth) else: new_storage_obj = LocalStorage(**auth) - logger.warning("user %s make storage obj key:%s obj: %s" % (user, storage_key, new_storage_obj)) + logger.warning(f"user {user} make storage obj key:{storage_key} obj: {new_storage_obj}") new_storage_obj.storage_type = storage_type cache.set(storage_key, new_storage_obj, 600) return new_storage_obj else: - logger.info("user %s has not storage obj, so get default" % user) + logger.info(f"user {user} has not storage obj, so get default") # return self.get_default_storage(user, storage_obj, False) # 不需要管理存储,直接从配置文件获取默认存储 return get_storage_form_conf(user) @@ -61,8 +61,7 @@ def get_storage(user, assigned_storage_obj, use_default_storage): def get_default_storage(user, storage_obj, use_default_storage): admin_obj = UserInfo.objects.filter(is_superuser=True).order_by('pk').first() if admin_obj and admin_obj.storage and admin_obj.pk != user.pk: - logger.info("user %s has not storage obj, from admin " - "get default storage" % user) + logger.info(f"user {user} has not storage obj, from admin get default storage") return get_storage(admin_obj, storage_obj, use_default_storage) else: return get_storage_form_conf(user) @@ -74,7 +73,7 @@ class Storage(object): with cache.lock("%s_%s" % ('make_storage_cache', user.uid), timeout=10, blocking_timeout=6): self.storage = get_storage(user, assigned_storage_obj, use_default_storage) except Exception as e: - logger.error("get %s storage failed Exception:%s" % (user, e)) + logger.error(f"get {user} storage failed Exception:{e}") self.storage = None def get_upload_token(self, filename, expires=900): @@ -97,39 +96,39 @@ class Storage(object): cache.set(down_key, {"download_url": download_url, "time": now + expires}, expires) return download_url - def delete_file(self, filename, apptype=None): + def delete_file(self, filename, app_type=None): if self.storage: - if apptype is not None: - if apptype == 0: + if app_type is not None: + if app_type == 0: filename = filename + '.apk' else: filename = filename + '.ipa' try: - logger.info("storage %s delete file %s" % (self.storage, filename)) + logger.info(f"storage {self.storage} delete file {filename}") return self.storage.del_file(filename) except Exception as e: - logger.error("delete file %s failed Exception %s" % (filename, e)) + logger.error(f"delete file {filename} failed Exception {e}") - def rename_file(self, oldfilename, newfilename): + def rename_file(self, old_filename, new_filename): if self.storage: try: - return self.storage.rename_file(oldfilename, newfilename) + return self.storage.rename_file(old_filename, new_filename) except Exception as e: - logger.error("rename %s to %s failed Exception %s" % (oldfilename, newfilename, e)) + logger.error(f"rename {old_filename} to {new_filename} failed Exception {e}") def upload_file(self, local_file_full_path): if self.storage: try: return self.storage.upload_file(local_file_full_path) except Exception as e: - logger.error("oss upload %s failed Exception %s" % (local_file_full_path, e)) + logger.error(f"oss upload {local_file_full_path} failed Exception {e}") def download_file(self, file_name, local_file_full_path): if self.storage: try: return self.storage.download_file(file_name, local_file_full_path) except Exception as e: - logger.error("oss download %s failed Exception %s" % (local_file_full_path, e)) + logger.error(f"oss download {local_file_full_path} failed Exception {e}") def get_storage_type(self): if self.storage: @@ -145,18 +144,17 @@ def get_local_storage(clean_cache=False): storage_key = "_".join(['local_storage_', CACHE_KEY_TEMPLATE.get('user_storage_key'), "_system_", base64.b64encode(json.dumps(auth).encode("utf-8")).decode("utf-8")[0:64]]) if clean_cache: - logger.info("system clean local storage obj cache storage_key %s" % storage_key) + logger.info(f"system clean local storage obj cache storage_key {storage_key}") cache.delete(storage_key) new_storage_obj = cache.get(storage_key) if new_storage_obj: - logger.info("system get local storage obj cache %s" % new_storage_obj) + logger.info(f"system get local storage obj cache {new_storage_obj}") return new_storage_obj else: new_storage_obj = LocalStorage(**auth) new_storage_obj.storage_type = 3 cache.set(storage_key, new_storage_obj, 600) - logger.info("system get local storage obj, from settings " - "storage %s" % new_storage_obj) + logger.info(f"system get local storage obj, from settings storage {new_storage_obj}") return new_storage_obj @@ -170,7 +168,7 @@ def get_storage_form_conf(user): base64.b64encode(json.dumps(auth).encode("utf-8")).decode("utf-8")[0:64]]) new_storage_obj = cache.get(storage_key) if new_storage_obj: - logger.info("user %s get default storage %s obj cache %s " % (user, storage_key, new_storage_obj)) + logger.info(f"user {user} get default storage {storage_key} obj cache {new_storage_obj} ") return new_storage_obj else: if storage_type == 1: @@ -183,7 +181,7 @@ def get_storage_form_conf(user): new_storage_obj = LocalStorage(**auth) new_storage_obj.storage_type = 3 cache.set(storage_key, new_storage_obj, 600) - logger.warning("user %s has not storage obj, from settings " - "get default storage key:%s obj:%s" % (user, storage_key, new_storage_obj)) + logger.warning( + f"user {user} has not storage obj, from settings get default storage key:{storage_key} obj:{new_storage_obj}") return new_storage_obj return None diff --git a/fir_ser/api/utils/tempcaches.py b/fir_ser/api/utils/tempcaches.py index 591171a..44c133d 100644 --- a/fir_ser/api/utils/tempcaches.py +++ b/fir_ser/api/utils/tempcaches.py @@ -8,7 +8,7 @@ from django.core.cache import cache import base64 -class tmpCache(object): +class TmpCache(object): @staticmethod def set_tmp_cache(key, token, target, limit=60 * 5): diff --git a/fir_ser/api/utils/throttle.py b/fir_ser/api/utils/throttle.py index f39326e..a4be7fd 100644 --- a/fir_ser/api/utils/throttle.py +++ b/fir_ser/api/utils/throttle.py @@ -7,8 +7,6 @@ from rest_framework.throttling import SimpleRateThrottle import hashlib -from rest_framework.exceptions import Throttled - class VisitShortThrottle(SimpleRateThrottle): """短连接用户访问频率限制1""" diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py index 6b9afc8..78c3cf6 100644 --- a/fir_ser/api/utils/utils.py +++ b/fir_ser/api/utils/utils.py @@ -3,15 +3,17 @@ # project: 5月 # author: liuyu # date: 2020/5/7 -import os, json, requests, datetime, random -from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT +import os, datetime, random +import binascii +from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT, CACHE_KEY_TEMPLATE from api.models import APPSuperSignUsedInfo, APPToDeveloper, \ - UDIDsyncDeveloper, UserInfo, AppReleaseInfo, AppScreenShot, UserDomainInfo + UDIDsyncDeveloper, UserInfo, AppReleaseInfo, AppScreenShot, Token from api.utils.storage.caches import get_app_d_count_by_app_id from api.utils.storage.localApi import LocalStorage from api.utils.storage.storage import Storage -from api.utils.tempcaches import tmpCache -from api.utils.TokenManager import DownloadToken, generateNumericTokenOfLength, generateAlphanumericTokenOfLength +from api.utils.tempcaches import TmpCache +from api.utils.TokenManager import generate_numeric_token_of_length, generate_alphanumeric_token_of_length, make_token, \ + verify_token from api.utils.sendmsg.sendmsg import SendMessage from django.db.models import Sum from captcha.models import CaptchaStore @@ -77,7 +79,7 @@ def get_captcha(): def valid_captcha(cptch_key, code, username): if username: challenge = CaptchaStore.objects.filter(hashkey=cptch_key).values("challenge").first() - logger.info("cptch_key:%s code:%s challenge:%s" % ((cptch_key, code, challenge))) + logger.info(f"cptch_key:{cptch_key} code:{code} challenge:{challenge}") if challenge: if cptch_key and code and code.strip(" ").lower() == challenge.get("challenge").lower(): return True @@ -92,10 +94,9 @@ def upload_oss_default_head_img(user_obj, storage_obj): def get_sender_token(sender, user_id, target, action, msg=None): - sms_token_obj = DownloadToken() - code = generateNumericTokenOfLength(6) - token = sms_token_obj.make_token(code, time_limit=300, key=user_id) - tmpCache.set_tmp_cache(user_id, token, target) + code = generate_numeric_token_of_length(6) + token = make_token(code, time_limit=300, key=user_id) + TmpCache.set_tmp_cache(user_id, token, target) if action == 'change': sender.send_change_msg(target, code) elif action == 'register': @@ -105,7 +106,7 @@ def get_sender_token(sender, user_id, target, action, msg=None): elif action == 'msg': sender.send_email_msg(target, msg) else: - logger.error("get_sender_token failed. action is %s" % (action)) + logger.error(f"get_sender_token failed. action is {action}") return None, None return token, code @@ -116,8 +117,7 @@ def get_sender_sms_token(key, phone, action): def is_valid_sender_code(key, token, code): - sms_token_obj = DownloadToken() - return sms_token_obj.verify_token(token, code), tmpCache.get_tmp_cache(key, token) + return verify_token(token, code), TmpCache.get_tmp_cache(key, token) def get_sender_email_token(key, email, action, msg=None): @@ -133,7 +133,7 @@ def check_username_exists(username): def get_random_username(length=16): - username = generateAlphanumericTokenOfLength(length) + username = generate_alphanumeric_token_of_length(length) if check_username_exists(username): return get_random_username(length) return username @@ -145,7 +145,7 @@ def send_ios_developer_active_status(user_info, msg): if email: get_sender_email_token(act, email, 'msg', msg) else: - logger.warning("user %s has no email. so %s can't send!" % (user_info, msg)) + logger.warning(f"user {user_info} has no email. so {msg} can't send!") def get_filename_from_apptype(filename, apptype): @@ -163,7 +163,7 @@ def delete_local_files(filename, apptype=None): try: return storage.del_file(filename) except Exception as e: - logger.error("delete file %s failed Exception %s" % (filename, e)) + logger.error(f"delete file {filename} failed Exception {e}") def delete_app_screenshots_files(storage_obj, app_obj): @@ -262,7 +262,7 @@ def migrating_storage_data(user_obj, new_storage_obj, clean_old_data): def clean_storage_data(user_obj, storage_obj=None): storage_obj = Storage(user_obj, storage_obj) - logger.info("%s clean_storage_data %s" % (user_obj, storage_obj)) + logger.info(f"{user_obj} clean_storage_data {storage_obj}") for app_release_obj in AppReleaseInfo.objects.filter(app_id__user_id=user_obj).all(): storage_obj.delete_file(app_release_obj.release_id, app_release_obj.release_type) storage_obj.delete_file(app_release_obj.icon_url) @@ -295,3 +295,13 @@ def get_choices_name_from_key(choices, key): if choice[0] == key: return choice[1] return '' + + +def set_user_token(user_obj): + key = binascii.hexlify(os.urandom(32)).decode() + now = datetime.datetime.now() + user_info = UserInfo.objects.get(pk=user_obj.pk) + auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), key]) + cache.set(auth_key, {'uid': user_info.uid, 'username': user_info.username}, 3600 * 24 * 7) + Token.objects.create(user=user_obj, **{"access_token": key, "created": now}) + return key, user_info diff --git a/fir_ser/api/views/apps.py b/fir_ser/api/views/apps.py index 4cb7835..bde8c2a 100644 --- a/fir_ser/api/views/apps.py +++ b/fir_ser/api/views/apps.py @@ -68,8 +68,7 @@ class AppsView(APIView): if count_hits: if count_hits > 0: logger.info( - "update user all_download_times old:%s now:%s" % ( - count_hits, request.user.all_download_times)) + f"update user all_download_times old:{count_hits} now:{request.user.all_download_times}") UserInfo.objects.filter(pk=request.user.id).update( all_download_times=count_hits) else: @@ -110,14 +109,14 @@ class AppInfoView(APIView): def get(self, request, app_id): res = BaseResponse() if app_id: - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - if apps_obj: - app_serializer = AppsSerializer(apps_obj, context={"storage": Storage(request.user)}) + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + if app_obj: + app_serializer = AppsSerializer(app_obj, context={"storage": Storage(request.user)}) res.data = app_serializer.data - count = APPToDeveloper.objects.filter(app_id=apps_obj).count() + count = APPToDeveloper.objects.filter(app_id=app_obj).count() res.data["count"] = count else: - logger.error("app_id:%s is not found in user:%s " % (app_id, request.user)) + logger.error(f"app_id:{app_id} is not found in user:{request.user}") res.msg = "未找到该应用" res.code = 1003 @@ -126,8 +125,8 @@ class AppInfoView(APIView): def delete(self, request, app_id): res = BaseResponse() if app_id: - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - res = app_delete(apps_obj) + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + res = app_delete(app_obj) return Response(res.dict) def put(self, request, app_id): @@ -137,16 +136,16 @@ class AppInfoView(APIView): clean = data.get("clean", None) if clean: - logger.info("app_id:%s clean:%s ,close supersign should clean_app_by_user_obj" % (app_id, clean)) - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - IosUtils.clean_app_by_user_obj(apps_obj, request.user) + logger.info(f"app_id:{app_id} clean:{clean} ,close super_sign should clean_app_by_user_obj") + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + IosUtils.clean_app_by_user_obj(app_obj, request.user) return Response(res.dict) has_combo = data.get("has_combo", None) if has_combo: actions = has_combo.get("action", None) hcombo_id = has_combo.get("hcombo_id", None) - logger.info("app_id:%s actions:%s hcombo_id:%s" % (app_id, actions, hcombo_id)) + logger.info(f"app_id:{app_id} actions:{actions} hcombo_id:{hcombo_id}") if actions and hcombo_id: has_combo = Apps.objects.filter(user_id=request.user, app_id=hcombo_id) @@ -166,54 +165,54 @@ class AppInfoView(APIView): del_cache_response_by_short(has_combo.first().app_id) except Exception as e: - logger.error("app_id:%s actions:%s hcombo_id:%s Exception:%s" % (app_id, actions, hcombo_id, e)) + logger.error(f"app_id:{app_id} actions:{actions} hcombo_id:{hcombo_id} Exception:{e}") res.code = 1004 res.msg = "该应用已经关联" else: try: do_sign_flag = 0 - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - logger.info("app_id:%s update old data:%s" % (app_id, apps_obj.__dict__)) - apps_obj.description = data.get("description", apps_obj.description) - apps_obj.short = data.get("short", apps_obj.short) - apps_obj.name = data.get("name", apps_obj.name) - apps_obj.password = data.get("password", apps_obj.password) - apps_obj.supersign_limit_number = data.get("supersign_limit_number", - apps_obj.supersign_limit_number) - apps_obj.isshow = data.get("isshow", apps_obj.isshow) - - if get_user_domain_name(request.user) or get_app_domain_name(apps_obj): - apps_obj.wxeasytype = data.get("wxeasytype", apps_obj.wxeasytype) + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + logger.info("app_id:%s update old data:%s" % (app_id, app_obj.__dict__)) + app_obj.description = data.get("description", app_obj.description) + app_obj.short = data.get("short", app_obj.short) + app_obj.name = data.get("name", app_obj.name) + app_obj.password = data.get("password", app_obj.password) + app_obj.supersign_limit_number = data.get("supersign_limit_number", + app_obj.supersign_limit_number) + app_obj.isshow = data.get("isshow", app_obj.isshow) + + if get_user_domain_name(request.user) or get_app_domain_name(app_obj): + app_obj.wxeasytype = data.get("wxeasytype", app_obj.wxeasytype) else: - apps_obj.wxeasytype = 1 + app_obj.wxeasytype = 1 - if apps_obj.issupersign: - if apps_obj.supersign_type in [x[0] for x in list(apps_obj.supersign_type_choices)]: - if apps_obj.supersign_type != data.get("supersign_type", apps_obj.supersign_type): + if app_obj.issupersign: + if app_obj.supersign_type in [x[0] for x in list(app_obj.supersign_type_choices)]: + if app_obj.supersign_type != data.get("supersign_type", app_obj.supersign_type): do_sign_flag = 1 - apps_obj.supersign_type = data.get("supersign_type", apps_obj.supersign_type) + app_obj.supersign_type = data.get("supersign_type", app_obj.supersign_type) new_bundle_id = data.get("new_bundle_id", None) new_bundle_name = data.get("new_bundle_name", None) - if new_bundle_id and new_bundle_id != apps_obj.bundle_id and len(new_bundle_id) > 3: - if new_bundle_id != apps_obj.new_bundle_id: + if new_bundle_id and new_bundle_id != app_obj.bundle_id and len(new_bundle_id) > 3: + if new_bundle_id != app_obj.new_bundle_id: do_sign_flag = 2 - apps_obj.new_bundle_id = new_bundle_id + app_obj.new_bundle_id = new_bundle_id if new_bundle_id == '': - if new_bundle_id != apps_obj.new_bundle_id: + if new_bundle_id != app_obj.new_bundle_id: do_sign_flag = 2 - apps_obj.new_bundle_id = None + app_obj.new_bundle_id = None - if new_bundle_name and new_bundle_name != apps_obj.name and len(new_bundle_name) > 0: - if new_bundle_name != apps_obj.new_bundle_name: + if new_bundle_name and new_bundle_name != app_obj.name and len(new_bundle_name) > 0: + if new_bundle_name != app_obj.new_bundle_name: do_sign_flag = 2 - apps_obj.new_bundle_name = new_bundle_name + app_obj.new_bundle_name = new_bundle_name if new_bundle_name == '': # if new_bundle_name != apps_obj.new_bundle_name: # do_sign_flag = 2 - apps_obj.new_bundle_name = apps_obj.name + app_obj.new_bundle_name = app_obj.name - apps_obj.wxredirect = data.get("wxredirect", apps_obj.wxredirect) - if apps_obj.type == 1 and data.get('issupersign', -1) != -1: + app_obj.wxredirect = data.get("wxredirect", app_obj.wxredirect) + if app_obj.type == 1 and data.get('issupersign', -1) != -1: # 为啥注释掉,就是该udid已经在该平台使用了,虽然已经没有余额,但是其他应用也是可以超级签名的 # developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user) # use_num = get_developer_devices(developer_obj) @@ -223,45 +222,45 @@ class AppInfoView(APIView): # return Response(res.dict) developer_count = AppIOSDeveloperInfo.objects.filter(user_id=request.user).count() if developer_count == 0: - logger.error("app_id:%s can't open supersign,owner has no ios developer" % (app_id)) + logger.error(f"app_id:{app_id} can't open super_sign,owner has no ios developer") res.code = 1008 res.msg = "超级签开发者不存在,无法开启" return Response(res.dict) - apps_obj.issupersign = data.get("issupersign", apps_obj.issupersign) - logger.info("app_id:%s update new data:%s" % (app_id, apps_obj.__dict__)) - apps_obj.save() - if apps_obj.issupersign: + app_obj.issupersign = data.get("issupersign", app_obj.issupersign) + logger.info(f"app_id:{app_id} update new data:{app_obj.__dict__}") + app_obj.save() + if app_obj.issupersign: c_task = None if do_sign_flag == 1: - c_task = run_resign_task.apply_async((apps_obj.app_id, True)) + c_task = run_resign_task.apply_async((app_obj.app_id, True)) if do_sign_flag == 2: - c_task = run_resign_task.apply_async((apps_obj.app_id, False)) + c_task = run_resign_task.apply_async((app_obj.app_id, False)) if c_task: msg = c_task.get(propagate=False) - logger.info("app %s run_resign_task msg:%s" % (apps_obj, msg)) + logger.info(f"app {app_obj} run_resign_task msg:{msg}") if c_task.successful(): c_task.forget() - del_cache_response_by_short(apps_obj.app_id) + del_cache_response_by_short(app_obj.app_id) except Exception as e: - logger.error("app_id:%s update Exception:%s" % (app_id, e)) + logger.error(f"app_id:{app_id} update Exception:{e}") res.code = 1005 res.msg = "短连接已经存在" return Response(res.dict) -class AppReleaseinfoView(APIView): +class AppReleaseInfoView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] def get(self, request, app_id, act): res = BaseResponse() res.data = {} if app_id: - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - if apps_obj: + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + if app_obj: storage = Storage(request.user) - app_serializer = AppsSerializer(apps_obj, context={"storage": storage}) - res = get_release_apps(request, res, app_serializer, apps_obj, storage) + app_serializer = AppsSerializer(app_obj, context={"storage": storage}) + res = get_release_apps(request, res, app_serializer, app_obj, storage) else: res.msg = "未找到该应用" res.code = 1003 @@ -270,52 +269,52 @@ class AppReleaseinfoView(APIView): def delete(self, request, app_id, act): res = BaseResponse() if app_id: - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - if apps_obj: + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + if app_obj: storage = Storage(request.user) if act == 'screen': screen_id = request.query_params.get('screen_id', None) if screen_id: - screen_obj = AppScreenShot.objects.filter(pk=screen_id, app_id=apps_obj).first() + screen_obj = AppScreenShot.objects.filter(pk=screen_id, app_id=app_obj).first() if screen_obj: storage.delete_file(screen_obj.screenshot_url) screen_obj.delete() - del_cache_response_by_short(apps_obj.app_id) + del_cache_response_by_short(app_obj.app_id) return Response(res.dict) - apprelease_count = AppReleaseInfo.objects.filter(app_id=apps_obj).values("release_id").count() - appreleaseobj = AppReleaseInfo.objects.filter(app_id=apps_obj, release_id=act).first() - if appreleaseobj: - if not appreleaseobj.is_master: - logger.info("delete app release %s" % (appreleaseobj)) - storage.delete_file(appreleaseobj.release_id, appreleaseobj.release_type) - delete_local_files(appreleaseobj.release_id, appreleaseobj.release_type) - storage.delete_file(appreleaseobj.icon_url) - - appreleaseobj.delete() - elif appreleaseobj.is_master and apprelease_count < 2: - logger.info("delete app master release %s and clean app %s " % (appreleaseobj, apps_obj)) - count = APPToDeveloper.objects.filter(app_id=apps_obj).count() - if apps_obj.issupersign or count > 0: - logger.info("app_id:%s is supersign ,delete this app need clean IOS developer" % (app_id)) - IosUtils.clean_app_by_user_obj(apps_obj, request.user) - - storage.delete_file(appreleaseobj.release_id, appreleaseobj.release_type) - delete_local_files(appreleaseobj.release_id, appreleaseobj.release_type) - storage.delete_file(appreleaseobj.icon_url) - del_cache_by_delete_app(apps_obj.app_id) - - appreleaseobj.delete() - delete_app_screenshots_files(storage, apps_obj) - has_combo = apps_obj.has_combo + app_release_count = AppReleaseInfo.objects.filter(app_id=app_obj).values("release_id").count() + app_release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, release_id=act).first() + if app_release_obj: + if not app_release_obj.is_master: + logger.info(f"delete app release {app_release_obj}") + storage.delete_file(app_release_obj.release_id, app_release_obj.release_type) + delete_local_files(app_release_obj.release_id, app_release_obj.release_type) + storage.delete_file(app_release_obj.icon_url) + + app_release_obj.delete() + elif app_release_obj.is_master and app_release_count < 2: + logger.info(f"delete app master release {app_release_obj} and clean app {app_obj}") + count = APPToDeveloper.objects.filter(app_id=app_obj).count() + if app_obj.issupersign or count > 0: + logger.info(f"app_id:{app_id} is super_sign ,delete this app need clean IOS developer") + IosUtils.clean_app_by_user_obj(app_obj, request.user) + + storage.delete_file(app_release_obj.release_id, app_release_obj.release_type) + delete_local_files(app_release_obj.release_id, app_release_obj.release_type) + storage.delete_file(app_release_obj.icon_url) + del_cache_by_delete_app(app_obj.app_id) + + app_release_obj.delete() + delete_app_screenshots_files(storage, app_obj) + has_combo = app_obj.has_combo if has_combo: has_combo.has_combo = None has_combo.save() del_cache_response_by_short(has_combo.app_id) - apps_obj.delete() + app_obj.delete() else: pass - del_cache_response_by_short(apps_obj.app_id) + del_cache_response_by_short(app_obj.app_id) return Response(res.dict) @@ -323,36 +322,36 @@ class AppReleaseinfoView(APIView): res = BaseResponse() res.data = {} if app_id: - apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() - if apps_obj: - appreleaseobj = AppReleaseInfo.objects.filter(app_id=apps_obj, release_id=act) + app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() + if app_obj: + app_release_objs = AppReleaseInfo.objects.filter(app_id=app_obj, release_id=act) data = request.data make_master = data.get("make_master", None) try: if make_master and make_master == act: - AppReleaseInfo.objects.filter(app_id=apps_obj).update(**{"is_master": False}) - appreleaseobj.update(**{"is_master": True}) + AppReleaseInfo.objects.filter(app_id=app_obj).update(**{"is_master": False}) + app_release_objs.update(**{"is_master": True}) else: - appreleaseobj.update( - **{"changelog": data.get("changelog", appreleaseobj.first().changelog)}) + app_release_objs.update( + **{"changelog": data.get("changelog", app_release_objs.first().changelog)}) binary_url = data.get("binary_url", None) if binary_url != '': if binary_url: if not binary_url.startswith('http'): binary_url = 'http://%s' % binary_url else: - binary_url = appreleaseobj.first().binary_url + binary_url = app_release_objs.first().binary_url - appreleaseobj.update(**{"binary_url": binary_url}) - logger.info("update app:%s release:%s data:%s" % (apps_obj, appreleaseobj, data)) + app_release_objs.update(**{"binary_url": binary_url}) + logger.info(f"update app:{app_obj} release:{app_release_objs} data:{data}") except Exception as e: - logger.error("update app:%s release:%s failed Exception:%s" % (apps_obj, appreleaseobj, e)) + logger.error(f"update app:{app_obj} release:{app_release_objs} failed Exception:{e}") res.code = 1006 res.msg = "更新失败" return Response(res.dict) - del_cache_response_by_short(apps_obj.app_id) - app_serializer = AppsSerializer(apps_obj) - res = get_release_apps(request, res, app_serializer, apps_obj, Storage(request.user)) + del_cache_response_by_short(app_obj.app_id) + app_serializer = AppsSerializer(app_obj) + res = get_release_apps(request, res, app_serializer, app_obj, Storage(request.user)) return Response(res.dict) diff --git a/fir_ser/api/views/domain.py b/fir_ser/api/views/domain.py index ab6c6be..e65339e 100644 --- a/fir_ser/api/views/domain.py +++ b/fir_ser/api/views/domain.py @@ -11,8 +11,7 @@ from api.utils.baseutils import is_valid_domain, get_cname_from_domain, get_user from api.utils.response import BaseResponse from api.utils.auth import ExpiringTokenAuthentication from rest_framework.response import Response -from api.models import UserDomainInfo, DomainCnameInfo, Apps -from django.db.models import Count +from api.models import UserDomainInfo, Apps import logging from api.utils.storage.caches import set_default_app_wx_easy, del_cache_response_by_short @@ -52,10 +51,10 @@ class DomainCnameView(APIView): res.code = 1001 res.msg = "该域名已经被绑定,请更换其他域名" else: - user_domian_obj = UserDomainInfo.objects.filter(**get_domain_filter(request), + user_domain_obj = UserDomainInfo.objects.filter(**get_domain_filter(request), domain_name=domain_name).first() - if user_domian_obj: - res.data = {'cname_domain': user_domian_obj.cname_id.domain_record} + if user_domain_obj: + res.data = {'cname_domain': user_domain_obj.cname_id.domain_record} else: UserDomainInfo.objects.filter(**get_domain_filter(request), is_enable=False).delete() min_domain_cname_info_obj = get_min_default_domain_cname_obj(False) @@ -80,13 +79,13 @@ class DomainCnameView(APIView): def put(self, request): res = BaseResponse() - user_domian_obj = UserDomainInfo.objects.filter(**get_domain_filter(request)).first() - if user_domian_obj: - cname = get_cname_from_domain(user_domian_obj.domain_name) - if cname == user_domian_obj.cname_id.domain_record + '.': - user_domian_obj.is_enable = True - user_domian_obj.save() - UserDomainInfo.objects.filter(domain_name=user_domian_obj.domain_name, is_enable=False).delete() + user_domain_obj = UserDomainInfo.objects.filter(**get_domain_filter(request)).first() + if user_domain_obj: + cname = get_cname_from_domain(user_domain_obj.domain_name) + if cname == user_domain_obj.cname_id.domain_record + '.': + user_domain_obj.is_enable = True + user_domain_obj.save() + UserDomainInfo.objects.filter(domain_name=user_domain_obj.domain_name, is_enable=False).delete() app_id = request.data.get("app_id", None) if app_id: app_obj = Apps.objects.filter(app_id=app_id).first() diff --git a/fir_ser/api/views/download.py b/fir_ser/api/views/download.py index ce18a59..3030a07 100644 --- a/fir_ser/api/views/download.py +++ b/fir_ser/api/views/download.py @@ -4,13 +4,14 @@ # author: liuyu # date: 2020/3/6 from rest_framework.views import APIView + +from api.utils.TokenManager import verify_token from api.utils.response import BaseResponse from rest_framework.response import Response from fir_ser import settings -from api.utils.TokenManager import DownloadToken from api.utils.app.randomstrings import make_random_uuid from api.utils.app.apputils import make_resigned -from api.utils.app.supersignutils import make_sign_udid_mobileconfig, get_post_udid_url, get_redirect_server_domain +from api.utils.app.supersignutils import make_sign_udid_mobile_config, get_post_udid_url, get_redirect_server_domain from api.utils.storage.storage import Storage, get_local_storage from api.utils.storage.caches import get_app_instance_by_cache, get_download_url_by_cache, set_app_download_by_cache, \ del_cache_response_by_short, consume_user_download_times, check_app_permission @@ -23,35 +24,36 @@ import logging from api.utils.baseutils import get_profile_full_path, get_app_domain_name from api.utils.throttle import VisitShortThrottle, InstallShortThrottle, InstallThrottle1, InstallThrottle2 -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class DownloadView(APIView): - ''' + """ 文件下载接口,适用于本地存储和所有plist文件下载 - ''' + """ def get(self, request, filename): res = BaseResponse() - downtoken = request.query_params.get(settings.DATA_DOWNLOAD_KEY, None) - ftype = filename.split(".")[-1] + down_token = request.query_params.get(settings.DATA_DOWNLOAD_KEY, None) + f_type = filename.split(".")[-1] flag = True storage_obj = get_local_storage() if storage_obj.download_auth_type == 1: - if not downtoken: + if not down_token: res.code = 1004 res.msg = "缺失token" + logger.error(f"file {filename} download failed lost down_token") return Response(res.dict) - dtoken = DownloadToken() - flag = dtoken.verify_token(downtoken, filename) + flag = verify_token(down_token, filename) if flag: - if ftype == 'plist': + if f_type == 'plist': release_id = filename.split('.')[0] - apptodev_obj = APPToDeveloper.objects.filter(binary_file=release_id).first() - if apptodev_obj: - release_obj = AppReleaseInfo.objects.filter(is_master=True, app_id=apptodev_obj.app_id).first() + app_to_developer_obj = APPToDeveloper.objects.filter(binary_file=release_id).first() + if app_to_developer_obj: + release_obj = AppReleaseInfo.objects.filter(is_master=True, + app_id=app_to_developer_obj.app_id).first() else: release_obj = AppReleaseInfo.objects.filter(release_id=release_id).first() if release_obj: @@ -67,32 +69,32 @@ class DownloadView(APIView): response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() return response res.msg = "plist release_id error" - elif ftype == 'mobileconifg': + elif f_type == 'mobileconifg': release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() if release_obj: bundle_id = release_obj.app_id.bundle_id udid_url = get_post_udid_url(request, release_obj.app_id.short) - ios_udid_mobileconfig = make_sign_udid_mobileconfig(udid_url, bundle_id, release_obj.app_id.name) - response = FileResponse(ios_udid_mobileconfig) + ios_udid_mobile_config = make_sign_udid_mobile_config(udid_url, bundle_id, release_obj.app_id.name) + response = FileResponse(ios_udid_mobile_config) response['Content-Type'] = "application/x-apple-aspen-config" response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() + '.mobileconfig' return response - res.msg = "mobileconifg release_id error" - elif ftype == 'mobileprovision': + res.msg = "mobile_config release_id error" + elif f_type == 'mobileprovision': release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() if release_obj: - appsuper_obj = APPSuperSignUsedInfo.objects.filter(app_id=release_obj.app_id).last() - if not appsuper_obj: - appsuper_obj = APPSuperSignUsedInfo.objects.last() + app_super_obj = APPSuperSignUsedInfo.objects.filter(app_id=release_obj.app_id).last() + if not app_super_obj: + app_super_obj = APPSuperSignUsedInfo.objects.last() - if not appsuper_obj: + if not app_super_obj: file_path = settings.DEFAULT_MOBILEPROVISION.get("supersign").get('path') if os.path.isfile(file_path): response = FileResponse(open(file_path, 'rb')) else: response = FileResponse() else: - developer_obj = appsuper_obj.developerid + developer_obj = app_super_obj.developerid file_path = get_profile_full_path(developer_obj, release_obj.app_id) if os.path.isfile(file_path): response = FileResponse(open(file_path, 'rb')) @@ -105,8 +107,8 @@ class DownloadView(APIView): response['Content-Type'] = "application/x-apple-aspen-config" response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() + '.mobileprovision' return response - res.msg = "mobileprovision release_id error" - elif ftype == 'dmobileprovision': + res.msg = "mobile_provision release_id error" + elif f_type == 'dmobileprovision': release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() if release_obj: file_path = settings.DEFAULT_MOBILEPROVISION.get("supersign").get('path') @@ -117,7 +119,7 @@ class DownloadView(APIView): response['Content-Type'] = "application/x-apple-aspen-config" response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() + '.mobileprovision' return response - res.msg = "dmobileprovision release_id error" + res.msg = "d_mobile_provision release_id error" else: file_path = os.path.join(settings.MEDIA_ROOT, filename) @@ -127,7 +129,7 @@ class DownloadView(APIView): else: response = FileResponse() except Exception as e: - logger.error("read %s failed Exception:%s" % (file_path, e)) + logger.error(f"read {file_path} failed Exception:{e}") response = FileResponse() response['content_type'] = "application/octet-stream" response['Content-Disposition'] = 'attachment; filename=' + filename @@ -135,6 +137,7 @@ class DownloadView(APIView): res.code = 1004 res.msg = "token校验失败" + logger.error(f"file {filename} download failed. down_token verify failed") return Response(res.dict) @@ -178,8 +181,7 @@ class ShortDownloadView(APIView): udid = time if not udid: udid = "" - logging.info( - "get or make cache_response short:%s release_id:%s udid:%s" % (kwargs.get("short", ''), release_id, udid)) + logging.info(f"get or make cache_response short:{kwargs.get('short', '')} release_id:{release_id} udid:{udid}") return "_".join( [settings.CACHE_KEY_TEMPLATE.get("download_short_key"), kwargs.get("short", ''), release_id, udid]) @@ -192,32 +194,32 @@ class InstallView(APIView): def get(self, request, app_id): res = BaseResponse() - downtoken = request.query_params.get("token", None) - short = request.query_params.get("short", None) - release_id = request.query_params.get("release_id", None) - isdownload = request.query_params.get("isdownload", None) - password = request.query_params.get("password", None) - udid = request.query_params.get("udid", None) + query_params = request.query_params + downtoken = query_params.get("token", None) + short = query_params.get("short", None) + release_id = query_params.get("release_id", None) + isdownload = query_params.get("isdownload", None) + password = query_params.get("password", None) + udid = query_params.get("udid", None) if not downtoken or not short or not release_id: res.code = 1004 res.msg = "参数丢失" return Response(res.dict) - dtoken = DownloadToken() - if dtoken.verify_token(downtoken, release_id): + if verify_token(downtoken, release_id): app_obj = get_app_instance_by_cache(app_id, password, 900, udid) if app_obj: if app_obj.get("type") == 0: - apptype = '.apk' - download_url, extra_url = get_download_url_by_cache(app_obj, release_id + apptype, 600) + app_type = '.apk' + download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600) else: - apptype = '.ipa' + app_type = '.ipa' if isdownload: - download_url, extra_url = get_download_url_by_cache(app_obj, release_id + apptype, 600, + download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, udid=udid) else: - download_url, extra_url = get_download_url_by_cache(app_obj, release_id + apptype, 600, + download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, isdownload, udid=udid) @@ -227,7 +229,7 @@ class InstallView(APIView): ip = request.META['HTTP_X_FORWARDED_FOR'] else: ip = request.META['REMOTE_ADDR'] - logger.info("remote ip %s short %s download_url %s app_obj %s" % (ip, short, download_url, app_obj)) + logger.info(f"remote ip {ip} short {short} download_url {download_url} app_obj {app_obj}") set_app_download_by_cache(app_id) amount = app_obj.get("d_count") # # 超级签需要多消耗2倍下载次数 diff --git a/fir_ser/api/views/login.py b/fir_ser/api/views/login.py index e10fcc2..433ff94 100644 --- a/fir_ser/api/views/login.py +++ b/fir_ser/api/views/login.py @@ -5,15 +5,13 @@ from rest_framework.response import Response from api.utils.serializer import UserInfoSerializer, CertificationSerializer, UserCertificationSerializer from django.core.cache import cache from rest_framework.views import APIView -import binascii -import os, datetime from api.utils.utils import get_captcha, valid_captcha, \ get_sender_sms_token, is_valid_sender_code, get_sender_email_token, get_random_username, \ - check_username_exists + check_username_exists, set_user_token from api.utils.baseutils import is_valid_phone, is_valid_email, get_min_default_domain_cname_obj from api.utils.auth import ExpiringTokenAuthentication from api.utils.response import BaseResponse -from fir_ser.settings import CACHE_KEY_TEMPLATE, REGISTER, LOGIN, CHANGER +from fir_ser.settings import REGISTER, LOGIN, CHANGER from api.utils.storage.caches import login_auth_failed import logging from api.utils.geetest.geetest_utils import first_register, second_validate @@ -31,17 +29,17 @@ def get_register_type(): return REGISTER.get("register_type") -def reset_user_pwd(user, surepassword, oldpassword=''): +def reset_user_pwd(user, sure_password, old_password=''): if user is not None: - user.set_password(surepassword) + user.set_password(sure_password) user.save() - logger.info("user:%s change password success,old %s new %s" % (user, oldpassword, surepassword)) + logger.info(f"user:{user} change password success,old {old_password} new {sure_password}") for token_obj in Token.objects.filter(user=user): cache.delete(token_obj.access_token) token_obj.delete() -def GetAuthenticate(target, password, act, allow_type): +def get_authenticate(target, password, act, allow_type): user_obj = None if act == 'email' and allow_type[act]: if is_valid_email(target): @@ -58,7 +56,7 @@ def GetAuthenticate(target, password, act, allow_type): return user_obj -def CheckRegisterUerinfo(target, act, key): +def check_register_userinfo(target, act, key): res = BaseResponse() res.data = {} times_key = "%s_%s_%s" % (key, act, target) @@ -121,7 +119,7 @@ def CheckRegisterUerinfo(target, act, key): return res -def CheckChangeUerinfo(target, act, key, user, ftype=None): +def check_change_userinfo(target, act, key, user, ftype=None): res = BaseResponse() res.data = {} @@ -186,9 +184,6 @@ def CheckChangeUerinfo(target, act, key, user, ftype=None): class LoginView(APIView): throttle_classes = [VisitRegister1Throttle, VisitRegister2Throttle] - def generate_key(self): - return binascii.hexlify(os.urandom(32)).decode() - def post(self, request): response = BaseResponse() receive = request.data @@ -217,7 +212,7 @@ class LoginView(APIView): msg = '您的新密码为 %s 请用新密码登录之后,及时修改密码' % password a, b = get_sender_email_token('email', username, 'msg', msg) if a and b: - reset_user_pwd(user_obj, password, oldpassword='') + reset_user_pwd(user_obj, password) login_auth_failed("del", username) else: response.code = 1002 @@ -228,20 +223,13 @@ class LoginView(APIView): return Response(response.dict) password = receive.get("password") - user = GetAuthenticate(username, password, login_type, get_login_type()) - logger.info("username:%s password:%s" % (username, password)) + user = get_authenticate(username, password, login_type, get_login_type()) + logger.info(f"username:{username} password:{password}") if user: if user.is_active: login_auth_failed("del", username) # update the token - key = self.generate_key() - now = datetime.datetime.now() - user_info = UserInfo.objects.get(pk=user.pk) - - auth_key = "_".join([CACHE_KEY_TEMPLATE.get('user_auth_token_key'), key]) - cache.set(auth_key, {'uid': user_info.uid, 'username': user_info.username}, 3600 * 24 * 7) - Token.objects.create(user=user, **{"access_token": key, "created": now}) - + key, user_info = set_user_token(user) serializer = UserInfoSerializer(user_info, ) data = serializer.data response.msg = "验证成功!" @@ -262,7 +250,7 @@ class LoginView(APIView): # response.code = 1003 else: response.code = 1006 - logger.error("username:%s failed too try , locked" % (username,)) + logger.error(f"username:{username} failed too try , locked") response.msg = "用户登录失败次数过多,已被锁定,请1小时之后再次尝试" else: response.code = 1001 @@ -298,9 +286,6 @@ class LoginView(APIView): class RegistView(APIView): throttle_classes = [VisitRegister1Throttle, VisitRegister2Throttle] - def generate_key(self): - return binascii.hexlify(os.urandom(32)).decode() - def post(self, request): response = BaseResponse() receive = request.data @@ -395,11 +380,11 @@ class UserInfoView(APIView): def put(self, request): res = BaseResponse() data = request.data - logger.info("user:%s update old data:%s" % (request.user, request.user.__dict__)) - logger.info("user:%s update new data:%s" % (request.user, data)) + logger.info(f"user:{request.user} update old data:{request.user.__dict__}") + logger.info(f"user:{request.user} update new data:{data}") - oldpassword = data.get("oldpassword", None) - surepassword = data.get("surepassword", None) + old_password = data.get("oldpassword", None) + sure_password = data.get("surepassword", None) mobile = data.get("mobile", None) email = data.get("email", None) @@ -411,13 +396,13 @@ class UserInfoView(APIView): res.msg = "图片验证码异常" return Response(res.dict) - if oldpassword and surepassword: - user = auth.authenticate(username=request.user.username, password=oldpassword) + if old_password and sure_password: + user = auth.authenticate(username=request.user.username, password=old_password) if user is not None: - user.set_password(surepassword) + user.set_password(sure_password) user.save() res.msg = "密码修改成功" - logger.info("user:%s change password success,old %s new %s" % (request.user, oldpassword, surepassword)) + logger.info(f"user:{request.user} change password success,old {old_password} new {sure_password}") auth_token = request.auth for token_obj in Token.objects.filter(user=user): @@ -435,7 +420,7 @@ class UserInfoView(APIView): if check_username_exists(username): res.msg = "用户名已经存在" res.code = 1005 - logger.error("User %s info save failed. Excepiton:%s" % (request.user, 'username already exists')) + logger.error(f"User {request.user} info save failed. username already exists") return Response(res.dict) if len(username) < 6: res.msg = "用户名至少6位" @@ -480,7 +465,7 @@ class UserInfoView(APIView): res.data = serializer.data res.code = 1004 res.msg = "信息保存失败" - logger.error("User %s info save failed. Excepiton:%s" % (request.user, e)) + logger.error(f"User {request.user} info save failed. Exception:{e}") return Response(res.dict) serializer = UserInfoSerializer(request.user) res.data = serializer.data @@ -525,7 +510,7 @@ class AuthorizationView(APIView): res.msg = "geetest验证有误" return Response(res.dict) - res = CheckRegisterUerinfo(target, act, 'register') + res = check_register_userinfo(target, act, 'register') return Response(res.dict) @@ -540,7 +525,7 @@ class ChangeAuthorizationView(APIView): act = request.data.get("act", None) target = request.data.get("target", None) ext = request.data.get("ext", None) - ftype = request.data.get("ftype", None) + f_type = request.data.get("ftype", None) if REGISTER.get("captcha"): if ext and valid_captcha(ext.get("cptch_key", None), ext.get("authcode", None), target): pass @@ -558,7 +543,7 @@ class ChangeAuthorizationView(APIView): res.msg = "geetest验证有误" return Response(res.dict) - res = CheckChangeUerinfo(target, act, 'change', request.user, ftype) + res = check_change_userinfo(target, act, 'change', request.user, f_type) return Response(res.dict) @@ -576,13 +561,13 @@ class UserApiTokenView(APIView): res = BaseResponse() data = request.data - oldtoken = data.get("token", None) - if oldtoken == request.user.api_token: + old_token = data.get("token", None) + if old_token == request.user.api_token: request.user.api_token = 'reset' try: request.user.save() except Exception as e: - logger.error("User %s api_token save failed. Excepiton:%s" % (request.user, e)) + logger.error(f"User {request.user} api_token save failed. Exception:{e}") res.code = 1002 res.msg = "token 生成失败" return Response(res.dict) @@ -616,7 +601,6 @@ class CertificationView(APIView): if 'certpic' in act: certification_obj = CertificationInfo.objects.filter(user_id=request.user).all() if certification_obj: - storage = Storage(request.user) certification_serializer = CertificationSerializer(certification_obj, many=True) res.data["certification"] = certification_serializer.data return Response(res.dict) @@ -655,7 +639,7 @@ class CertificationView(APIView): return Response(res.dict) else: res.code = 1006 - logger.error("username:%s failed too try , locked" % (request.user,)) + logger.error(f"username:{request.user} failed too try , locked") res.msg = "用户注册失败次数过多,已被锁定,请1小时之后再次尝试" else: res.code = 1001 @@ -670,7 +654,7 @@ class CertificationView(APIView): return Response(res.dict) return self.get(request) except Exception as e: - logger.error("%s UserCertificationInfo save %s failed Exception: %s" % (request.user, data, e)) + logger.error(f"{request.user} UserCertificationInfo save {data} failed Exception: {e}") res.msg = "数据异常,请检查" res.code = 1002 return Response(res.dict) diff --git a/fir_ser/api/views/logout.py b/fir_ser/api/views/logout.py index bf3681a..f3e6dc2 100644 --- a/fir_ser/api/views/logout.py +++ b/fir_ser/api/views/logout.py @@ -6,14 +6,14 @@ from rest_framework.response import Response from django.contrib import auth import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class LogoutView(APIView): authentication_classes = [ExpiringTokenAuthentication] def delete(self, request): - logger.info("user:%s logout" % (request.user)) + logger.info(f"user:{request.user} logout") user = request.user.pk auth_token = request.auth cache.delete(auth_token) diff --git a/fir_ser/api/views/order.py b/fir_ser/api/views/order.py index 8806bb4..ddda346 100644 --- a/fir_ser/api/views/order.py +++ b/fir_ser/api/views/order.py @@ -62,7 +62,7 @@ class OrderView(APIView): pay_url = pay_obj.get_pay_pc_url(order_number, int(order_obj.actual_amount), {'user_id': request.user.id}) res.data = pay_url - logger.info("%s 下单成功 %s" % (request.user, res.dict)) + logger.info(f"{request.user} 下单成功 {res.dict}") return Response(res.dict) if price_obj: try: @@ -75,14 +75,14 @@ class OrderView(APIView): actual_download_times=price_obj.package_size, payment_name=pay_obj.name, actual_download_gift_times=price_obj.download_count_gift) res.data = pay_url - logger.info("%s 下单成功 %s" % (request.user, res.dict)) + logger.info(f"{request.user} 下单成功 {res.dict}") return Response(res.dict) except Exception as e: - logger.error("%s 订单 %s 保存失败 Exception:%s" % (request.user, price_id, e)) + logger.error(f"{request.user} 订单 {price_id} 保存失败 Exception:{e}") res.code = 1003 res.msg = "订单保存失败" else: - logger.error("%s 价格 %s 获取失败" % (request.user, price_id)) + logger.error(f"{request.user} 价格 {price_id} 获取失败") res.code = 1002 res.msg = "价格获取失败,请稍后重试" else: @@ -107,11 +107,11 @@ class OrderView(APIView): # wxpay = Weixinpay() # wxpay.update_order_status(order_obj.order_number) except Exception as e: - logger.error("%s 订单 %s 更新失败 Exception:%s" % (request.user, order_number, e)) + logger.error(f"{request.user} 订单 {order_number} 更新失败 Exception:{e}") res.code = 1003 return Response(res.dict) else: - logger.error("%s 订单 %s 获取失败" % (request.user, order_number)) + logger.error(f"{request.user} 订单 {order_number} 获取失败") res.code = 1003 res.msg = "订单获取失败,或订单已经支付" else: @@ -130,11 +130,11 @@ class PriceView(APIView): res.pay_choices = get_enable_pay_choices() return Response(res.dict) - def delete(self, request, price_id): + def delete(self, request): res = BaseResponse() return Response(res.dict) - def put(self, request, price_id): + def put(self, request): res = BaseResponse() return Response(res.dict) @@ -149,8 +149,8 @@ class PaySuccess(APIView): pay_obj = get_pay_obj_form_name(name) msg = 'failure' if pay_obj: - logger.info("支付回调参数:%s" % request.body) - logger.info("支付回调头部:%s" % request.META) + logger.info(f"支付回调参数:{request.body}") + logger.info(f"支付回调头部:{request.META}") if pay_obj.p_type == 'ALI': if pay_obj.valid_order(request): msg = 'success' diff --git a/fir_ser/api/views/receiveudids.py b/fir_ser/api/views/receiveudids.py index 06c40f7..0737b1b 100644 --- a/fir_ser/api/views/receiveudids.py +++ b/fir_ser/api/views/receiveudids.py @@ -20,7 +20,7 @@ from rest_framework.views import APIView from api.utils.baseutils import get_app_domain_name from celery.exceptions import TimeoutError -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class IosUDIDView(View): @@ -29,7 +29,7 @@ class IosUDIDView(View): def post(self, request, short): stream_f = str(request.body) format_udid_info = udid_bytes_to_dict(stream_f) - logger.info("short %s get new udid %s" % (short, format_udid_info)) + logger.info(f"short {short} receive new udid {format_udid_info}") server_domain = get_redirect_server_domain(request) try: app_info = Apps.objects.filter(short=short).first() @@ -42,7 +42,7 @@ class IosUDIDView(View): else: c_task = run_sign_task.apply_async((format_udid_info, short)) task_id = c_task.id - logger.info("sign app %s task_id:%s" % (app_info, task_id)) + logger.info(f"sign app {app_info} task_id:{task_id}") try: result = c_task.get(propagate=False, timeout=2) except TimeoutError: @@ -60,7 +60,7 @@ class IosUDIDView(View): "%s/%s" % (server_domain, short)) except Exception as e: msg = "&msg=系统内部错误" - logger.error("short %s receive udid Exception:%s" % (short, e)) + logger.error(f"short {short} receive udid Exception:{e}") return HttpResponsePermanentRedirect( "%s/%s?udid=%s%s" % (server_domain, short, format_udid_info.get("udid"), msg)) @@ -75,7 +75,7 @@ class TaskView(APIView): app_info = Apps.objects.filter(short=short).first() if app_info: result = app.AsyncResult(task_id) - logger.info("app %s sign task state %s AA %s" % (app_info, result.state, result.successful())) + logger.info(f"app {app_info} sign task state {result.state} AA {result.successful()}") if result.successful(): res.msg = result.get(propagate=False) return Response(res.dict) diff --git a/fir_ser/api/views/storage.py b/fir_ser/api/views/storage.py index f84d984..5503b89 100644 --- a/fir_ser/api/views/storage.py +++ b/fir_ser/api/views/storage.py @@ -10,14 +10,12 @@ from api.base_views import storage_change from api.utils.response import BaseResponse from api.utils.auth import ExpiringTokenAuthentication, StoragePermission from rest_framework.response import Response -from api.utils.storage.caches import del_cache_storage from api.models import AppStorage, UserInfo -from api.utils.utils import upload_oss_default_head_img, \ - change_storage_and_change_head_img, migrating_storage_data, clean_storage_data, get_choices_dict +from api.utils.utils import upload_oss_default_head_img, get_choices_dict from api.utils.serializer import StorageSerializer import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class StorageView(APIView): @@ -65,25 +63,25 @@ class StorageView(APIView): def post(self, request): res = BaseResponse() data = request.data - logger.info("user %s add new storage data:%s" % (request.user, data)) + logger.info(f"user {request.user} add new storage data:{data}") serializer = StorageSerializer(data=data, context={'user_obj': request.user}) if serializer.is_valid(): storage_obj = serializer.save() if storage_obj: if upload_oss_default_head_img(request.user, storage_obj): res.msg = serializer.validated_data - logger.info("user %s add new storage success" % (request.user)) + logger.info(f"user {request.user} add new storage success") else: storage_obj.delete() - logger.error("user %s add new storage failed" % (request.user)) + logger.error(f"user {request.user} add new storage failed") res.msg = "文件上传校验失败,请检查参数是否正确" res.code = 1005 else: - logger.info("user %s add new storage failed" % (request.user)) + logger.info(f"user {request.user} add new storage failed") res.msg = serializer.errors res.code = 1005 else: - logger.info("user %s add new storage failed" % (request.user)) + logger.info(f"user {request.user} add new storage failed") res.msg = serializer.errors res.code = 1005 return Response(res.dict) @@ -91,7 +89,7 @@ class StorageView(APIView): def put(self, request): res = BaseResponse() data = request.data - logger.info("user %s update storage data:%s" % (request.user, data)) + logger.info(f"user {request.user} update storage data:{data}") use_storage_id = data.get("use_storage_id", None) force = data.get("force", None) if use_storage_id: @@ -115,14 +113,14 @@ class StorageView(APIView): if new_storage_obj: if upload_oss_default_head_img(request.user, new_storage_obj): res.msg = serializer.validated_data - logger.info("user %s update storage success" % (request.user)) + logger.info(f"user {request.user} update storage success") else: storage_obj_bak.save() - logger.error("user %s update storage failed" % (request.user)) + logger.error(f"user {request.user} update storage failed") res.msg = "文件上传校验失败,请检查参数是否正确" res.code = 1005 else: - logger.info("user %s update storage failed" % (request.user)) + logger.info(f"user {request.user} update storage failed") res.msg = serializer.errors res.code = 1005 else: @@ -139,9 +137,9 @@ class StorageView(APIView): if storage_id: try: AppStorage.objects.filter(user_id=request.user, id=storage_id).delete() - logger.error("user %s delete storage id:%s success" % (request.user, storage_id)) + logger.error(f"user {request.user} delete storage id:{storage_id} success") except Exception as e: - logger.error("user %s delete storage id:%s failed Exception:%s" % (request.user, storage_id, e)) + logger.error(f"user {request.user} delete storage id:{storage_id} failed Exception:{e}") else: res.code = 1004 res.msg = '该存储不存在' diff --git a/fir_ser/api/views/supersign.py b/fir_ser/api/views/supersign.py index 3896386..3527ff0 100644 --- a/fir_ser/api/views/supersign.py +++ b/fir_ser/api/views/supersign.py @@ -6,19 +6,17 @@ from django.http.response import FileResponse from rest_framework.views import APIView -from api.utils.app.iossignapi import ResignApp -from api.utils.baseutils import file_format_path from api.utils.response import BaseResponse from api.utils.auth import ExpiringTokenAuthentication, SuperSignPermission from rest_framework.response import Response from api.models import AppIOSDeveloperInfo, APPSuperSignUsedInfo, AppUDID from api.utils.serializer import DeveloperSerializer, SuperSignUsedSerializer, DeviceUDIDSerializer from rest_framework.pagination import PageNumberPagination -from api.utils.app.supersignutils import IosUtils, get_auth_form_developer +from api.utils.app.supersignutils import IosUtils from api.utils.utils import get_developer_devices, get_choices_dict import logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class PageNumber(PageNumberPagination): @@ -36,11 +34,11 @@ class DeveloperView(APIView): res = BaseResponse() - appid = request.query_params.get("appid", None) + app_id = request.query_params.get("appid", None) developer_obj = AppIOSDeveloperInfo.objects.filter(user_id=request.user) res.use_num = get_developer_devices(developer_obj) - if appid: - developer_obj = developer_obj.filter(issuer_id=appid) + if app_id: + developer_obj = developer_obj.filter(issuer_id=app_id) page_obj = PageNumber() app_page_serializer = page_obj.paginate_queryset(queryset=developer_obj.order_by("-updated_time"), @@ -66,7 +64,7 @@ class DeveloperView(APIView): act = data.get("act", None) if act: res = BaseResponse() - logger.info("user %s iosdeveloper %s act %s" % (request.user, developer_obj, act)) + logger.info(f"user {request.user} ios developer {developer_obj} act {act}") if act == "checkauth": status, result = IosUtils.active_developer(developer_obj) if status: @@ -112,16 +110,16 @@ class DeveloperView(APIView): res.msg = result.get("err_info") return Response(res.dict) else: - logger.info("user %s iosdeveloper %s update input data %s" % (request.user, developer_obj, data)) - logger.info("user %s iosdeveloper %s update old data %s" % ( - request.user, developer_obj, developer_obj.__dict__)) + logger.info(f"user {request.user} ios developer {developer_obj} update input data {data}") + logger.info( + f"user {request.user} ios developer {developer_obj} update old data {developer_obj.__dict__}") try: usable_number = int(data.get("usable_number", developer_obj.usable_number)) if 0 <= usable_number <= 100: developer_obj.usable_number = usable_number except Exception as e: - logger.error("developer %s usable_number %s get failed Exception:%s" % ( - developer_obj, data.get("usable_number", developer_obj.usable_number), e)) + logger.error( + f"developer {developer_obj} usable_number {data.get('usable_number', developer_obj.usable_number)} get failed Exception:{e}") developer_obj.description = data.get("description", developer_obj.description) private_key_id = data.get("private_key_id", developer_obj.private_key_id) p8key = data.get("p8key", developer_obj.p8key) @@ -133,19 +131,19 @@ class DeveloperView(APIView): developer_obj.is_actived = False try: developer_obj.save() - logger.info("user %s iosdeveloper %s update now data %s" % ( - request.user, developer_obj, developer_obj.__dict__)) + logger.info( + f"user {request.user} ios developer {developer_obj} update now data {developer_obj.__dict__}") except Exception as e: - logger.error("user %s iosdeveloper %s update error data %s Exception %s" % ( - request.user, developer_obj, data, e)) + logger.error( + f"user {request.user} ios developer {developer_obj} update error data {data} Exception {e}") return self.get(request) def post(self, request): data = request.data - datainfo = {} + data_info = {} if data.get("auth_type") == 0: - datainfo = { + data_info = { "usable_number": data.get("usable_number", ""), "description": data.get("description", ""), "issuer_id": data.get("issuer_id", ""), @@ -154,13 +152,11 @@ class DeveloperView(APIView): "auth_type": 0 } try: - logger.error("user %s add new developer %s data %s" % ( - request.user, data.get("issuer_id", ""), datainfo)) - developer_obj = AppIOSDeveloperInfo.objects.create(user_id=request.user, **datainfo) + logger.error(f"user {request.user} add new developer {data.get('issuer_id', '')} data {data_info}") + developer_obj = AppIOSDeveloperInfo.objects.create(user_id=request.user, **data_info) IosUtils.create_developer_space(developer_obj, request.user) except Exception as e: - logger.error("user %s create developer %s failed Exception:%s" % ( - request.user, datainfo, e)) + logger.error(f"user {request.user} create developer {data_info} failed Exception:{e}") res = BaseResponse() res.code = 1005 res.msg = "添加失败" @@ -176,8 +172,7 @@ class DeveloperView(APIView): return self.get(request) if developer_obj: - logger.error("user %s delete developer %s " % ( - request.user, developer_obj)) + logger.error(f"user {request.user} delete developer {developer_obj}") IosUtils.clean_developer(developer_obj, request.user) IosUtils.revoke_developer_cert(developer_obj, request.user) developer_obj.delete() @@ -193,25 +188,25 @@ class SuperSignUsedView(APIView): res = BaseResponse() udid = request.query_params.get("udid", None) - bundleid = request.query_params.get("bundleid", None) - developerid = request.query_params.get("appid", None) + bundle_id = request.query_params.get("bundleid", None) + developer_id = request.query_params.get("appid", None) - SuperSignUsed_obj = APPSuperSignUsedInfo.objects.filter(user_id=request.user, ) + super_sign_used_objs = APPSuperSignUsedInfo.objects.filter(user_id=request.user, ) - if developerid: - SuperSignUsed_obj = SuperSignUsed_obj.filter(developerid__issuer_id=developerid) + if developer_id: + super_sign_used_objs = super_sign_used_objs.filter(developerid__issuer_id=developer_id) if udid: - SuperSignUsed_obj = SuperSignUsed_obj.filter(udid__udid=udid) - if bundleid: - SuperSignUsed_obj = SuperSignUsed_obj.filter(app_id__bundle_id=bundleid) + super_sign_used_objs = super_sign_used_objs.filter(udid__udid=udid) + if bundle_id: + super_sign_used_objs = super_sign_used_objs.filter(app_id__bundle_id=bundle_id) page_obj = PageNumber() - app_page_serializer = page_obj.paginate_queryset(queryset=SuperSignUsed_obj.order_by("-created_time"), + app_page_serializer = page_obj.paginate_queryset(queryset=super_sign_used_objs.order_by("-created_time"), request=request, view=self) app_serializer = SuperSignUsedSerializer(app_page_serializer, many=True, ) res.data = app_serializer.data - res.count = SuperSignUsed_obj.count() + res.count = super_sign_used_objs.count() return Response(res.dict) @@ -223,29 +218,29 @@ class AppUDIDUsedView(APIView): res = BaseResponse() udid = request.query_params.get("udid", None) - bundleid = request.query_params.get("bundleid", None) - AppUDID_obj = AppUDID.objects.filter(app_id__user_id_id=request.user) + bundle_id = request.query_params.get("bundleid", None) + app_udid_objs = AppUDID.objects.filter(app_id__user_id_id=request.user) if udid: - AppUDID_obj = AppUDID_obj.filter(udid=udid) - if bundleid: - AppUDID_obj = AppUDID_obj.filter(app_id__bundle_id=bundleid) + app_udid_objs = app_udid_objs.filter(udid=udid) + if bundle_id: + app_udid_objs = app_udid_objs.filter(app_id__bundle_id=bundle_id) page_obj = PageNumber() - app_page_serializer = page_obj.paginate_queryset(queryset=AppUDID_obj.order_by("-created_time"), + app_page_serializer = page_obj.paginate_queryset(queryset=app_udid_objs.order_by("-created_time"), request=request, view=self) app_serializer = DeviceUDIDSerializer(app_page_serializer, many=True, ) res.data = app_serializer.data - res.count = AppUDID_obj.count() + res.count = app_udid_objs.count() return Response(res.dict) def delete(self, request): res = BaseResponse() - id = request.query_params.get("id", None) + pk = request.query_params.get("id", None) app_id = request.query_params.get("aid", None) - app_udid_obj = AppUDID.objects.filter(app_id__user_id_id=request.user, pk=id) + app_udid_obj = AppUDID.objects.filter(app_id__user_id_id=request.user, pk=pk) if app_udid_obj: - logger.error("user %s delete devices %s" % (request.user, app_udid_obj)) + logger.error(f"user {request.user} delete devices {app_udid_obj}") IosUtils.disable_udid(app_udid_obj.first(), app_id) app_udid_obj.delete() return Response(res.dict) @@ -281,12 +276,12 @@ class SuperSignCertView(APIView): status, result = resign_app_obj.make_cert_from_p12(request.data.get('cert_pwd', ''), request.data.get('cert_content', None)) if status: - status, result = IosUtils.auto_get_certid_by_p12(developer_obj, request.user) + status, result = IosUtils.auto_get_cert_id_by_p12(developer_obj, request.user) if status: resign_app_obj.write_cert() else: res.code = 1003 - res.msg = str('证书未在开发者账户找到,请检查推送证书是否属于该开发者') + res.msg = '证书未在开发者账户找到,请检查推送证书是否属于该开发者' else: res.code = 1002 res.msg = str(result['err_info']) diff --git a/fir_ser/api/views/uploads.py b/fir_ser/api/views/uploads.py index 6f79e9a..814e26d 100644 --- a/fir_ser/api/views/uploads.py +++ b/fir_ser/api/views/uploads.py @@ -3,10 +3,10 @@ # project: 3月 # author: liuyu # date: 2020/3/6 - -from api.utils.app.apputils import get_random_short, SaveAppInfos +from api.utils.TokenManager import verify_token +from api.utils.app.apputils import get_random_short, save_app_infos from api.utils.baseutils import get_app_domain_name -from api.utils.storage.storage import Storage, get_local_storage +from api.utils.storage.storage import Storage from api.utils.storage.caches import upload_file_tmp_name, del_cache_response_by_short from api.models import Apps, AppReleaseInfo, UserInfo, AppScreenShot, CertificationInfo from api.utils.app.randomstrings import make_app_uuid @@ -16,33 +16,32 @@ from api.utils.auth import ExpiringTokenAuthentication from api.utils.app.randomstrings import make_from_user_uuid from rest_framework.response import Response from fir_ser import settings -from api.utils.TokenManager import DownloadToken from api.utils.app.supersignutils import get_redirect_server_domain from api.tasks import run_resign_task import os, json, logging -logger = logging.getLogger(__file__) +logger = logging.getLogger(__name__) class AppAnalyseView(APIView): authentication_classes = [ExpiringTokenAuthentication, ] def post(self, request): - ''' + """ 应用上传前 分析数据,并返回应用上传信息 :param request: :return: - ''' + """ res = BaseResponse() # 1.接收 bundelid ,返回随机应用名称和短连接 - bundleid = request.data.get("bundleid", None) + bundle_id = request.data.get("bundleid", None) app_type = request.data.get("type", None) - if bundleid and app_type: + if bundle_id and app_type: ap = 'apk' if app_type.lower() == 'iOS'.lower(): ap = 'ipa' - app_uuid = make_app_uuid(request.user, bundleid + ap) + app_uuid = make_app_uuid(request.user, bundle_id + ap) release_id = make_from_user_uuid(request.user) png_id = make_from_user_uuid(request.user) app_obj = Apps.objects.filter(app_id=app_uuid).first() @@ -85,14 +84,14 @@ class AppAnalyseView(APIView): return Response(res.dict) def put(self, request): - ''' + """ 该方法就是 应用上传完成之后的回调方法,更新或者创建新应用信息 :param request: :return: - ''' + """ res = BaseResponse() data = request.data - appinfo = { + app_info = { "labelname": data.get("appname"), "version": data.get("buildversion"), "versioncode": data.get("version"), @@ -110,19 +109,19 @@ class AppAnalyseView(APIView): png_tmp_filename = data.get("png_key") png_new_filename = data.get("png_key").strip(settings.FILE_UPLOAD_TMP_KEY) - logger.info("user %s create or update app %s data:%s" % (request.user, data.get("bundleid"), data)) - if SaveAppInfos(app_new_filename, request.user, appinfo, - data.get("bundleid"), png_new_filename, data.get("short"), data.get('filesize')): + logger.info(f"user {request.user} create or update app {data.get('bundleid')} data:{data}") + if save_app_infos(app_new_filename, request.user, app_info, + data.get("bundleid"), png_new_filename, data.get("short"), data.get('filesize')): # 需要将tmp 文件修改为正式文件 storage.rename_file(app_tmp_filename, app_new_filename) storage.rename_file(png_tmp_filename, png_new_filename) - app_info = Apps.objects.filter(bundle_id=data.get("bundleid")).first() - if app_info: - if app_info.issupersign and app_info.user_id.supersign_active: - c_task = run_resign_task.apply_async((app_info.app_id, False)) + app_obj = Apps.objects.filter(bundle_id=data.get("bundleid")).first() + if app_obj: + if app_obj.issupersign and app_obj.user_id.supersign_active: + c_task = run_resign_task.apply_async((app_obj.app_id, False)) msg = c_task.get(propagate=False) - logger.info("app %s run_resign_task msg:%s" % (app_info, msg)) + logger.info(f"app {app_obj} run_resign_task msg:{msg}") if c_task.successful(): c_task.forget() else: @@ -133,7 +132,7 @@ class AppAnalyseView(APIView): upload_file_tmp_name("del", png_tmp_filename, request.user.id) except Exception as e: - logger.error("user %s %s save app info failed Exception:%s" % (request.user, data.get("bundleid"), e)) + logger.error(f"user {request.user} save app {data.get('bundleid')} info {app_info} failed Exception:{e}") res.code = 10003 res.msg = 'save app info failed' @@ -141,27 +140,27 @@ class AppAnalyseView(APIView): class UploadView(APIView): - ''' + """ 上传文件接口 - ''' + """ authentication_classes = [ExpiringTokenAuthentication, ] def get(self, request): - ''' + """ 该方法 主要是本地上传,通过该方法获取上传的 应用图片或者用户头像 的上传信息 :param request: :return: - ''' + """ res = BaseResponse() storage = Storage(request.user) request_upload_key = request.query_params.get("upload_key", None) app_id = request.query_params.get("app_id", None) - ftype = request.query_params.get("ftype", None) - if ftype and app_id and request_upload_key: - if ftype == 'app' or ftype == 'screen': + f_type = request.query_params.get("ftype", None) + if f_type and app_id and request_upload_key: + if f_type == 'app' or f_type == 'screen': app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() - elif ftype and ftype in ['head', 'certification']: + elif f_type and f_type in ['head', 'certification']: if request.user.uid != app_id: res.code = 1007 res.msg = '该用户不存在' @@ -177,7 +176,7 @@ class UploadView(APIView): res.code = 1006 res.msg = '类型不允许' else: - if ftype and ftype == 'certification': + if f_type and f_type == 'certification': storage = Storage(request.user, None, True) upload_key = make_from_user_uuid(request.user) + '.' + app_type + settings.FILE_UPLOAD_TMP_KEY upload_token = storage.get_upload_token(upload_key) @@ -188,7 +187,7 @@ class UploadView(APIView): "upload_key": upload_key, "storage": storage_type, "app_id": app_id, - "ftype": ftype + "ftype": f_type } else: res.code = 1006 @@ -198,43 +197,42 @@ class UploadView(APIView): return Response(res.dict) def post(self, request): - ''' + """ 该方法 主要是本地上传文件接口,负责上传 应用图片,应用文件或者用户头像 :param request: :return: - ''' + """ res = BaseResponse() # 获取多个file files = request.FILES.getlist('file', None) - certinfo = request.data.get('certinfo', None) + cert_info = request.data.get('certinfo', None) try: - certinfo = json.loads(certinfo) - if not certinfo: + cert_info = json.loads(cert_info) + if not cert_info: res.msg = "数据信息 校验失败" res.code = 1006 return Response(res.dict) except Exception as e: - logger.error("%s certinfo:%s get failed Exception:%s" % (request.user, certinfo, e)) + logger.error(f"{request.user} cert_info:{cert_info} get failed Exception:{e}") res.msg = "token 校验失败" res.code = 1006 return Response(res.dict) - token_obj = DownloadToken() - if token_obj.verify_token(token=certinfo.get("upload_token", None), - release_id=certinfo.get("upload_key", None)): + if verify_token(token=cert_info.get("upload_token", None), + release_id=cert_info.get("upload_key", None)): - app_id = certinfo.get("app_id", None) - ftype = certinfo.get("ftype", None) - if ftype and ftype in ['app', 'screen']: + app_id = cert_info.get("app_id", None) + f_type = cert_info.get("ftype", None) + if f_type and f_type in ['app', 'screen']: pass # app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() # if not app_obj: # res.code = 1006 # res.msg = '该应用不存在' # return Response(res.dict) - elif ftype and ftype in ['head', 'certification']: + elif f_type and f_type in ['head', 'certification']: if request.user.uid != app_id: res.code = 1007 res.msg = '该用户不存在' @@ -252,18 +250,18 @@ class UploadView(APIView): if app_type == "tmp": app_type = file_obj.name.split(".")[-2] if app_type not in ["apk", "ipa", 'png', 'jpeg', 'jpg']: - logger.error("user:%s upload file type error file:%s " % (request.user, file_obj.name)) + logger.error(f"user:{request.user} upload file type error file:{file_obj.name}") raise TypeError except Exception as e: - logger.error("user:%s upload file type error Exception:%s " % (request.user, e)) + logger.error(f"user:{request.user} upload file type error Exception:{e}") res.code = 1003 res.msg = "错误的类型" return Response(res.dict) random_file_name = make_from_user_uuid(request.user) - local_file = os.path.join(settings.MEDIA_ROOT, certinfo.get("upload_key", random_file_name)) + local_file = os.path.join(settings.MEDIA_ROOT, cert_info.get("upload_key", random_file_name)) # 读取传入的文件 - logger.info("user:%s save file:%s" % (request.user, local_file)) + logger.info(f"user:{request.user} save file:{local_file}") try: destination = open(local_file, 'wb+') for chunk in file_obj.chunks(): @@ -271,14 +269,14 @@ class UploadView(APIView): destination.close() except Exception as e: - logger.error("user:%s save file:%s error Exception:%s " % (request.user, local_file, e)) + logger.error(f"user:{request.user} save file:{local_file} error Exception:{e}") res.code = 1003 res.msg = "数据写入失败" try: if os.path.isfile(local_file): os.remove(local_file) except Exception as e: - logger.error("user:%s delete file:%s error Exception:%s " % (request.user, local_file, e)) + logger.error(f"user:{request.user} delete file:{local_file} error Exception:{e}") return Response(res.dict) else: res.msg = "token 校验失败" @@ -287,27 +285,27 @@ class UploadView(APIView): return Response(res.dict) def put(self, request): - ''' + """ 该方法就是 应用图片或者用户头像上传完成之后的回调方法,为了更新上传完成的信息 :param request: :return: - ''' + """ res = BaseResponse() - certinfo = request.data.get('certinfo', None) - if certinfo: - app_id = certinfo.get("app_id", None) - logger.info("user %s update img %s info" % (request.user, app_id)) + cert_info = request.data.get('certinfo', None) + if cert_info: + app_id = cert_info.get("app_id", None) + logger.info(f"user {request.user} update img {app_id} info") - ftype = certinfo.get('ftype', None) - upload_key = certinfo.get("upload_key", None) - if ftype and upload_key: + f_type = cert_info.get('ftype', None) + upload_key = cert_info.get("upload_key", None) + if f_type and upload_key: storage = Storage(request.user) new_upload_key = upload_key.strip(settings.FILE_UPLOAD_TMP_KEY) else: res.msg = '参数有误' res.code = 1008 return Response(res.dict) - if ftype and app_id and ftype == 'app': + if f_type and app_id and f_type == 'app': app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() if app_obj: release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first() @@ -319,11 +317,10 @@ class UploadView(APIView): del_cache_response_by_short(app_id) storage.delete_file(old_file_key) return Response(res.dict) - elif ftype and app_id and ftype == 'screen': + elif f_type and app_id and f_type == 'screen': app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() if app_obj: - scount = AppScreenShot.objects.filter(app_id=app_obj).count() - if scount >= 5: + if AppScreenShot.objects.filter(app_id=app_obj).count() >= 5: storage.delete_file(upload_key) res.msg = '最多支持五张截图' res.code = 1009 @@ -333,32 +330,32 @@ class UploadView(APIView): del_cache_response_by_short(app_id) return Response(res.dict) - elif ftype and app_id and ftype in ['head', 'certification']: + elif f_type and app_id and f_type in ['head', 'certification']: if request.user.uid != app_id: res.code = 1007 res.msg = '该用户不存在' return Response(res.dict) - if ftype == 'head': + if f_type == 'head': old_file_key = request.user.head_img UserInfo.objects.filter(pk=request.user.id).update(head_img=new_upload_key) if old_file_key != "" or old_file_key != 'head_img.jpeg': storage.delete_file(old_file_key) storage.rename_file(upload_key, new_upload_key) - elif ftype == 'certification': - ext = certinfo.get('ext', None) + elif f_type == 'certification': + ext = cert_info.get('ext', None) if ext: - ptype = ext.get('ptype', None) - if ptype is not None and ptype in [1, 2, 3]: + p_type = ext.get('ptype', None) + if p_type is not None and p_type in [1, 2, 3]: storage = Storage(request.user, None, True) certification_obj = CertificationInfo.objects.filter(user_id=request.user, - type=ptype).first() + type=p_type).first() if certification_obj: old_certification_url = certification_obj.certification_url certification_obj.certification_url = new_upload_key certification_obj.save() storage.delete_file(old_certification_url) else: - CertificationInfo.objects.create(user_id=request.user, type=ptype, + CertificationInfo.objects.create(user_id=request.user, type=p_type, certification_url=new_upload_key) storage.rename_file(upload_key, new_upload_key) diff --git a/fir_ser/cli/urls.py b/fir_ser/cli/urls.py index 8d06243..0c3ad17 100644 --- a/fir_ser/cli/urls.py +++ b/fir_ser/cli/urls.py @@ -16,13 +16,13 @@ Including another URLconf from django.urls import path, re_path, include from cli.views.login import CliUserInfoView -from cli.views.apps import CliAppsView, CliAppInfoView, CliAppReleaseinfoView +from cli.views.apps import CliAppsView, CliAppInfoView, CliAppReleaseInfoView from cli.views.uploads import CliAppAnalyseView, CliUploadView urlpatterns = [ re_path("^apps$", CliAppsView.as_view()), re_path("^apps/(?P\w+)", CliAppInfoView.as_view()), - re_path("^appinfos/(?P\w+)/(?P\w+)", CliAppReleaseinfoView.as_view()), + re_path("^appinfos/(?P\w+)/(?P\w+)", CliAppReleaseInfoView.as_view()), re_path("^upload$", CliUploadView.as_view()), re_path("^userinfo", CliUserInfoView.as_view()), re_path("^analyse$", CliAppAnalyseView.as_view()), diff --git a/fir_ser/cli/views/apps.py b/fir_ser/cli/views/apps.py index c6a4653..83b806d 100644 --- a/fir_ser/cli/views/apps.py +++ b/fir_ser/cli/views/apps.py @@ -5,7 +5,7 @@ # date: 2020/3/4 from api.utils.auth import ApiTokenAuthentication -from api.views.apps import AppsView, AppInfoView, AppReleaseinfoView +from api.views.apps import AppsView, AppInfoView, AppReleaseInfoView import logging logger = logging.getLogger(__name__) @@ -19,5 +19,5 @@ class CliAppInfoView(AppInfoView): authentication_classes = [ApiTokenAuthentication, ] -class CliAppReleaseinfoView(AppReleaseinfoView): +class CliAppReleaseInfoView(AppReleaseInfoView): authentication_classes = [ApiTokenAuthentication, ]