From 4d856bf5c06313886cc64384451e01b1e5b8b0ee Mon Sep 17 00:00:00 2001 From: youngS Date: Thu, 11 Mar 2021 18:32:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AD=98=E5=82=A8=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fir_client/src/components/FirApps.vue | 7 ++ fir_ser/api/utils/app/iossignapi.py | 2 +- fir_ser/api/utils/app/supersignutils.py | 129 ++++++++++++++---------- fir_ser/api/utils/utils.py | 18 +++- fir_ser/api/views/apps.py | 12 ++- 5 files changed, 108 insertions(+), 60 deletions(-) diff --git a/fir_client/src/components/FirApps.vue b/fir_client/src/components/FirApps.vue index 0daf6d0..7ad05b9 100644 --- a/fir_client/src/components/FirApps.vue +++ b/fir_client/src/components/FirApps.vue @@ -701,8 +701,15 @@ return false; }, delApp() { + let loadingobj = this.$loading({ + lock: true, + text: '操作中,请耐心等待', + spinner: 'el-icon-loading', + // background: 'rgba(0, 0, 0, 0.7)' + }); this.willDeleteApp = false; apputils(data => { + loadingobj.close(); if (data.code === 1000) { for (let i = 0; i < this.applists.length; i++) { if (this.delapp.app_id === this.applists[i].app_id) { diff --git a/fir_ser/api/utils/app/iossignapi.py b/fir_ser/api/utils/app/iossignapi.py index d85cfea..b983a70 100644 --- a/fir_ser/api/utils/app/iossignapi.py +++ b/fir_ser/api/utils/app/iossignapi.py @@ -267,9 +267,9 @@ class AppDeveloperApiV2(object): return False, result def set_device_status(self, status, device_udid): - apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) result = {} try: + apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) if status == "enable": device_obj = apple_obj.enabled_device(device_udid) else: diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index bd3b64b..b41b594 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -4,7 +4,7 @@ # author: liuyu # date: 2020/3/6 -import uuid, xmltodict, os, re, logging, time +import uuid, xmltodict, os, re, logging, time, requests from fir_ser.settings import SUPER_SIGN_ROOT, MEDIA_ROOT, SERVER_DOMAIN, MOBILECONFIG_SIGN_SSL from api.utils.app.iossignapi import AppDeveloperApi, ResignApp, AppDeveloperApiV2 from api.models import APPSuperSignUsedInfo, AppUDID, AppIOSDeveloperInfo, AppReleaseInfo, Apps, APPToDeveloper, \ @@ -14,11 +14,36 @@ from api.utils.serializer import get_developer_udided from api.utils.storage.localApi import LocalStorage from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_limit from api.utils.utils import file_format_path, delete_app_to_dev_and_file, delete_app_profile_file, \ - send_ios_developer_active_status, get_profile_full_path + send_ios_developer_active_status, get_profile_full_path, delete_local_files +from api.utils.storage.storage import Storage logger = logging.getLogger(__file__) +def check_org_file(user_obj, org_file): + if not os.path.isdir(os.path.dirname(org_file)): + os.makedirs(os.path.dirname(org_file)) + + if os.path.isfile(org_file): + return + + storage_obj = Storage(user_obj) + download_url = storage_obj.get_download_url(os.path.basename(org_file), 600, key='check_org_file', force_new=True) + req = requests.get(download_url) + logger.info("download user %s file %s success" % (user_obj, org_file)) + + with open(org_file + ".check.tmp", "wb") as f: + f.write(req.content) + try: + if os.path.isfile(org_file): + os.remove(org_file) + os.rename(os.path.join(org_file + ".check.tmp"), org_file) + return True + except Exception as e: + logger.error("check org file and mv file %s failed Exception %s" % (org_file, e)) + return False + + def resign_by_app_obj(app_obj, need_download_profile=True): user_obj = app_obj.user_id if app_obj.issupersign and user_obj.supersign_active: @@ -327,6 +352,7 @@ class IosUtils(object): auth, developer_app_id, device_id_lists) if add_did_flag: 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)) @@ -355,6 +381,7 @@ class IosUtils(object): app_dev_pem = file_format_path_name + ".pem" resign_app_obj = ResignApp(my_local_key, app_dev_pem) org_file = os.path.join(MEDIA_ROOT, release_obj.release_id + ".ipa") + check_org_file(user_obj, org_file) new_file = os.path.join(MEDIA_ROOT, random_file_name + ".ipa") properties_info = {} if app_obj.new_bundle_id: @@ -370,20 +397,22 @@ class IosUtils(object): return False @staticmethod - def update_sign_file_name(app_obj, developer_obj, release_obj, random_file_name): + def update_sign_file_name(user_obj, app_obj, developer_obj, release_obj, random_file_name): apptodev_obj = APPToDeveloper.objects.filter(developerid=developer_obj, app_id=app_obj).first() + storage_obj = Storage(user_obj) if apptodev_obj: - storage = LocalStorage("localhost", False) - storage.del_file(apptodev_obj.binary_file + ".ipa") + delete_local_files(apptodev_obj.binary_file + ".ipa") + storage_obj.delete_file(apptodev_obj.binary_file + ".ipa") apptodev_obj.binary_file = random_file_name apptodev_obj.release_file = release_obj.release_id apptodev_obj.save() - else: APPToDeveloper.objects.create(developerid=developer_obj, app_id=app_obj, binary_file=random_file_name, release_file=release_obj.release_id) - def update_sign_data(self, random_file_name, release_obj, result): + storage_obj.upload_file(os.path.join(MEDIA_ROOT, random_file_name + ".ipa")) + + def update_sign_data(self, random_file_name, release_obj): newdata = { "is_signed": True, "binary_file": random_file_name @@ -405,30 +434,11 @@ class IosUtils(object): developerid=self.developer_obj, udid=AppUDID.objects.filter(app_id=self.app_obj, udid=self.udid_info.get('udid')).first()) + # 更新新签名的ipa包 + IosUtils.update_sign_file_name(self.user_obj, self.app_obj, self.developer_obj, release_obj, random_file_name) del_cache_response_by_short(self.app_obj.app_id, udid=self.udid_info.get('udid')) - app_udid_obj = UDIDsyncDeveloper.objects.filter(developerid=self.developer_obj, - udid=self.udid_info.get('udid')).first() - if not app_udid_obj: - appudid_obj = AppUDID.objects.filter(app_id=self.app_obj, udid=self.udid_info.get('udid')) - device = appudid_obj.values("serial", - 'product', - 'udid', - 'version').first() - if result.get("did", None): - device['serial'] = result["did"] - app_udid_obj = UDIDsyncDeveloper.objects.create(developerid=self.developer_obj, **device) - DeveloperDevicesID.objects.create(did=result["did"], udid=app_udid_obj, developerid=self.developer_obj, - app_id=self.app_obj) - else: - if result.get("did", None): - DeveloperDevicesID.objects.create(did=result["did"], udid=app_udid_obj, developerid=self.developer_obj, - app_id=self.app_obj) - - # 更新新签名的ipa包 - IosUtils.update_sign_file_name(self.app_obj, self.developer_obj, release_obj, random_file_name) - @staticmethod def run_sign(user_obj, app_obj, developer_obj, download_flag, obj, d_time, result, resign=False): d_result = {'code': 0, 'msg': 'success'} @@ -441,9 +451,9 @@ class IosUtils(object): s_time1 = time.time() logger.info("app_id %s exec sign ipa success. time:%s" % (app_obj, s_time1 - start_time)) if resign: - IosUtils.update_sign_file_name(app_obj, developer_obj, release_obj, random_file_name) + IosUtils.update_sign_file_name(user_obj, app_obj, developer_obj, release_obj, random_file_name) else: - obj.update_sign_data(random_file_name, release_obj, result) + obj.update_sign_data(random_file_name, release_obj) else: msg = "app_id %s download profile failed. %s time:%s" % (app_obj, result, time.time() - start_time) d_result['code'] = 1002 @@ -504,6 +514,27 @@ class IosUtils(object): if download_flag: AppUDID.objects.update_or_create(app_id=self.app_obj, udid=self.udid_info.get('udid'), defaults=self.udid_info) + if not result.get("did_exists", None): + app_udid_obj = UDIDsyncDeveloper.objects.filter(developerid=self.developer_obj, + udid=self.udid_info.get('udid')).first() + if not app_udid_obj: + appudid_obj = AppUDID.objects.filter(app_id=self.app_obj, udid=self.udid_info.get('udid')) + device = appudid_obj.values("serial", + 'product', + 'udid', + 'version').first() + if result.get("did", None): + device['serial'] = result["did"] + app_udid_obj = UDIDsyncDeveloper.objects.create(developerid=self.developer_obj, **device) + DeveloperDevicesID.objects.create(did=result["did"], udid=app_udid_obj, + developerid=self.developer_obj, + app_id=self.app_obj) + else: + if result.get("did", None): + DeveloperDevicesID.objects.create(did=result["did"], udid=app_udid_obj, + developerid=self.developer_obj, + app_id=self.app_obj) + return IosUtils.run_sign(self.user_obj, self.app_obj, self.developer_obj, download_flag, self, start_time, result) @@ -517,17 +548,7 @@ class IosUtils(object): # 需要判断该设备在同一个账户下 的多个应用,若存在,则不操作 udid_lists = list(APPSuperSignUsedInfo.objects.values_list("udid__udid").filter(developerid=developer_obj)) - if udid_lists.count((udid_obj.udid,)) == 1: - app_api_obj = get_api_obj(auth) - app_api_obj.set_device_status("disable", udid_obj.udid) - UDIDsyncDeveloper.objects.filter(udid=udid_obj.udid, developerid=developer_obj).delete() - - if developer_obj.use_number > 0: - developer_obj.use_number = developer_obj.use_number - 1 - developer_obj.save() - - usedeviceobj.delete() - + IosUtils.do_disable_device(developer_obj, udid_lists, udid_obj, auth) # 通过开发者id判断 app_id 是否多个,否则删除profile 文件 if APPSuperSignUsedInfo.objects.filter(developerid=developer_obj, app_id_id=app_id).count() == 0: app_api_obj = get_api_obj(auth) @@ -543,6 +564,19 @@ class IosUtils(object): udid=udid_obj.udid).first() DeveloperDevicesID.objects.filter(udid=app_udid_obj, developerid=developer_obj, app_id_id=app_id).delete() + @staticmethod + def do_disable_device(developer_obj, udid_lists, udid_obj, auth): + if udid_lists.count((udid_obj.udid,)) == 1: + app_api_obj = get_api_obj(auth) + app_api_obj.set_device_status("disable", udid_obj.udid) + UDIDsyncDeveloper.objects.filter(udid=udid_obj.udid, developerid=developer_obj).delete() + + if developer_obj.use_number > 0: + developer_obj.use_number = developer_obj.use_number - 1 + developer_obj.save() + + udid_obj.delete() + @staticmethod def clean_udid_by_app_obj(app_obj, developer_obj): @@ -553,18 +587,7 @@ class IosUtils(object): for SuperSignUsed_obj in APPSuperSignUsedInfo.objects.filter(app_id=app_obj, developerid=developer_obj): udid_obj = SuperSignUsed_obj.udid - - if udid_lists.count((udid_obj.udid,)) == 1: - app_api_obj = get_api_obj(auth) - app_api_obj.set_device_status("disable", udid_obj.udid) - UDIDsyncDeveloper.objects.filter(udid=udid_obj.udid, developerid=developer_obj).delete() - - if developer_obj.use_number > 0: - developer_obj.use_number = developer_obj.use_number - 1 - developer_obj.save() - - udid_obj.delete() - + IosUtils.do_disable_device(developer_obj, udid_lists, udid_obj, auth) SuperSignUsed_obj.delete() @staticmethod diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py index 59015c2..3ca18ae 100644 --- a/fir_ser/api/utils/utils.py +++ b/fir_ser/api/utils/utils.py @@ -52,8 +52,9 @@ def delete_app_to_dev_and_file(developer_obj, app_id): APPToDeveloper_obj = APPToDeveloper.objects.filter(developerid=developer_obj, app_id_id=app_id) if APPToDeveloper_obj: binary_file = APPToDeveloper_obj.first().binary_file + ".ipa" - lsobj = LocalStorage("localhost", False) - lsobj.del_file(binary_file) + delete_local_files(binary_file) + storage = Storage(developer_obj.user_id) + storage.delete_file(binary_file) APPToDeveloper_obj.delete() @@ -203,3 +204,16 @@ def send_ios_developer_active_status(user_info, msg): get_sender_email_token(act, email, 'msg', msg) else: logger.warning("user %s has no email. so %s can't send!" % (user_info, msg)) + + +def delete_local_files(filename, apptype=None): + storage = LocalStorage("localhost", False) + if apptype is not None: + if apptype == 0: + filename = filename + '.apk' + else: + filename = filename + '.ipa' + try: + return storage.del_file(filename) + except Exception as e: + logger.error("delete file %s failed Exception %s" % (filename, e)) diff --git a/fir_ser/api/views/apps.py b/fir_ser/api/views/apps.py index 157bf77..5ed5c69 100644 --- a/fir_ser/api/views/apps.py +++ b/fir_ser/api/views/apps.py @@ -18,7 +18,7 @@ from rest_framework.pagination import PageNumberPagination import logging from fir_ser.settings import SERVER_DOMAIN from api.utils.storage.caches import set_default_app_wx_easy -from api.utils.utils import is_valid_domain +from api.utils.utils import is_valid_domain, delete_local_files logger = logging.getLogger(__name__) @@ -120,7 +120,8 @@ class AppInfoView(APIView): if app_id: apps_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() if apps_obj: - if apps_obj.issupersign: + 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) @@ -137,6 +138,7 @@ class AppInfoView(APIView): logger.info("delete app_id:%s need clean all release,release_id:%s" % ( app_id, appreleaseobj.release_id)) 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() apps_obj.delete() @@ -327,17 +329,19 @@ class AppReleaseinfoView(APIView): 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)) - - if apps_obj.issupersign: + 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)