From cf14dcb0a595673cfbd204b9c4b119390f616c48 Mon Sep 17 00:00:00 2001 From: MMXX Date: Wed, 9 Mar 2022 17:04:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E8=8B=B9=E6=9E=9C=E5=BC=80=E5=8F=91=E8=80=85=E8=B4=A6=E6=88=B7?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fir_ser/common/libs/apple/appleapiv3.py | 118 +++++++----- fir_ser/common/libs/sendmsg/emailApi.py | 2 +- .../sendmsg/templates/check_developer.html | 177 +++++++++++++++++ fir_ser/fir_ser/settings.py | 2 +- fir_ser/tests/django_test.py | 25 +++ fir_ser/xsign/utils/ctasks.py | 15 +- fir_ser/xsign/utils/iossignapi.py | 180 +++++++++++------- fir_ser/xsign/utils/supersignutils.py | 12 +- 8 files changed, 403 insertions(+), 128 deletions(-) create mode 100644 fir_ser/common/libs/sendmsg/templates/check_developer.html create mode 100644 fir_ser/tests/django_test.py diff --git a/fir_ser/common/libs/apple/appleapiv3.py b/fir_ser/common/libs/apple/appleapiv3.py index a6b6675..ac730ed 100644 --- a/fir_ser/common/libs/apple/appleapiv3.py +++ b/fir_ser/common/libs/apple/appleapiv3.py @@ -30,11 +30,12 @@ logger = logging.getLogger(__name__) # timeout = settings.APPLE_DEVELOPER_API_TIMEOUT if settings.APPLE_DEVELOPER_API_TIMEOUT else 120 -def request_format_log(req): +def request_format_log(self, req): try: - logger.info(f"url:{req.url} header:{req.headers} code:{req.status_code} body:{req.content}") + logger.info( + f"issuer_id:{self.issuer_id} url:{req.url} method:{req.request.method} header:{req.headers} code:{req.status_code} body:{req.content}") except Exception as e: - logger.error(e) + logger.error(f"issuer_id:{self.issuer_id} url:{req.url} method:{req.request.method} Exception:{e}") return req @@ -100,9 +101,10 @@ class DevicesAPI(object): if query_parameters: for k, v in query_parameters.items(): params[k] = v - return request_format_log( - requests.get(self.devices_url, params=params, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.get(self.devices_url, params=params, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def list_enabled_devices(self): return self.list_devices({"filter[status]": "ENABLED"}) @@ -135,9 +137,9 @@ class DevicesAPI(object): } } } - return request_format_log( - requests.post(self.devices_url, json=json, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.post(self.devices_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) def read_device_information(self, device_id): """ @@ -152,8 +154,9 @@ class DevicesAPI(object): params = { "fields[devices]": "addedDate, deviceClass, model, name, platform, status, udid", } - return request_format_log( - requests.get(base_url, params=params, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.get(base_url, params=params, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) def enabled_device(self, device_id, device_name): return self.modify_registered_device(device_id, device_name, 'ENABLED') @@ -184,8 +187,9 @@ class DevicesAPI(object): } } } - return request_format_log( - requests.patch(base_url, json=json, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.patch(base_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) class BundleIDsAPI(object): @@ -217,9 +221,10 @@ class BundleIDsAPI(object): } } } - return request_format_log( - requests.post(self.bundle_ids_url, json=json, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.post(self.bundle_ids_url, json=json, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def delete_bundle_id_by_id(self, bundle_id): """ @@ -233,8 +238,9 @@ class BundleIDsAPI(object): """ base_url = '%s/%s' % (self.bundle_ids_url, bundle_id) json = {} - return request_format_log( - requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) def list_bundle_ids(self, query_parameters=None): """ @@ -252,9 +258,10 @@ class BundleIDsAPI(object): if query_parameters: for k, v in query_parameters.items(): params[k] = v - return request_format_log( - requests.get(self.bundle_ids_url, params=params, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.get(self.bundle_ids_url, params=params, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def list_bundle_id_by_identifier(self, identifier): return self.list_bundle_ids({"filter[identifier]": identifier}) @@ -283,8 +290,9 @@ class BundleIDsAPI(object): } } } - return request_format_log( - requests.patch(base_url, json=json, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.patch(base_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) class BundleIDsCapabilityAPI(object): @@ -306,8 +314,9 @@ class BundleIDsCapabilityAPI(object): """ base_url = '%s/%s_%s' % (self.bundle_ids_capability_url, bundle_id, capability_type) json = {} - return request_format_log( - requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) def enable_capability(self, bundle_id, capability_type): """ @@ -336,9 +345,10 @@ class BundleIDsCapabilityAPI(object): } } } - return request_format_log( - requests.post(self.bundle_ids_capability_url, json=json, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.post(self.bundle_ids_capability_url, json=json, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) class ProfilesAPI(object): @@ -390,9 +400,10 @@ class ProfilesAPI(object): } } } - return request_format_log( - requests.post(self.profiles_url, json=json, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.post(self.profiles_url, json=json, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def delete_profile(self, profile_id): """ @@ -406,8 +417,9 @@ class ProfilesAPI(object): """ base_url = '%s/%s' % (self.profiles_url, profile_id) json = {} - return request_format_log( - requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) def download_profile(self, profile_id): # n=base64.b64decode(profileContent) @@ -432,9 +444,10 @@ class ProfilesAPI(object): if query_parameters: for k, v in query_parameters.items(): params[k] = v - return request_format_log( - requests.get(self.profiles_url, params=params, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.get(self.profiles_url, params=params, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def list_profile_by_profile_id(self, profile_id): return self.list_profiles({"filter[id]": profile_id, "include": ""}) @@ -469,9 +482,10 @@ class CertificatesAPI(object): } } } - return request_format_log( - requests.post(self.certificates_url, json=json, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.post(self.certificates_url, json=json, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def download_certificate(self, certificate_id): # req.json()['data'][0]['attributes']['certificateContent'] @@ -496,9 +510,10 @@ class CertificatesAPI(object): if query_parameters: for k, v in query_parameters.items(): params[k] = v - return request_format_log( - requests.get(self.certificates_url, params=params, headers=self.headers, proxies=self.proxies, - timeout=self.timeout)) + return request_format_log(self, + requests.get(self.certificates_url, params=params, headers=self.headers, + proxies=self.proxies, + timeout=self.timeout)) def list_certificate_by_certificate_id(self, certificate_id): return self.list_certificate({"filter[id]": certificate_id, }) @@ -515,8 +530,9 @@ class CertificatesAPI(object): """ base_url = '%s/%s' % (self.certificates_url, certificate_id) json = {} - return request_format_log( - requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, timeout=self.timeout)) + return request_format_log(self, + requests.delete(base_url, json=json, headers=self.headers, proxies=self.proxies, + timeout=self.timeout)) class BaseInfoObj(object): @@ -745,6 +761,18 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi CertificatesAPI.__init__(self, self.BASE_URI, self.headers) self.rate_limit_info = {} + def __getattribute__(self, name): + attr = object.__getattribute__(self, name) + if hasattr(attr, '__call__'): + def func(*args, **kwargs): + res = attr(*args, **kwargs) + logger.info(f"issuer_id:{self.issuer_id} calling {attr.__name__} result:{res}") + return res + + return func + else: + return attr + def __set_rate_limit_info(self, req_headers): for par in req_headers.get('X-Rate-Limit').split(";"): if par: @@ -796,6 +824,8 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi obj = Certificates.from_json_list(data) if len(obj) == 1: return obj[0] + if obj is None: + raise Exception(f'None object: {req.text}') return obj else: # self.__init_jwt_headers() diff --git a/fir_ser/common/libs/sendmsg/emailApi.py b/fir_ser/common/libs/sendmsg/emailApi.py index bf8fc49..f1d8eb9 100644 --- a/fir_ser/common/libs/sendmsg/emailApi.py +++ b/fir_ser/common/libs/sendmsg/emailApi.py @@ -43,7 +43,7 @@ class EmailMsgSender(object): def send_email_msg(self, email, text): try: - response = send_mail("重要消息通知", text, self.form, [email], ) + response = send_mail("重要消息通知", text, self.form, [email], html_message=text) except Exception as e: return -1, e return response, text diff --git a/fir_ser/common/libs/sendmsg/templates/check_developer.html b/fir_ser/common/libs/sendmsg/templates/check_developer.html new file mode 100644 index 0000000..5ac4f71 --- /dev/null +++ b/fir_ser/common/libs/sendmsg/templates/check_developer.html @@ -0,0 +1,177 @@ + + + + + 开发者状态监测报告 + + + +
+
+

+ 尊敬的用户 {{ username }} 你好,苹果开发者状态监测如下: +

+ + + + + + + + + + {% for developer_obj in developer_obj_list %} + + + + + + + {% endfor %} + +
+ 苹果开发者ID + + 苹果开发者备注 + + 苹果开发者状态 +
+ {{ developer_obj.issuer_id }} + + {{ developer_obj.description }} + + {{ developer_obj.get_status_display }} +
+
+
+ + diff --git a/fir_ser/fir_ser/settings.py b/fir_ser/fir_ser/settings.py index 57447e9..f43dec0 100644 --- a/fir_ser/fir_ser/settings.py +++ b/fir_ser/fir_ser/settings.py @@ -65,7 +65,7 @@ ROOT_URLCONF = 'fir_ser.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, 'templates')] + 'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'common/libs/sendmsg/templates')] , 'APP_DIRS': True, 'OPTIONS': { diff --git a/fir_ser/tests/django_test.py b/fir_ser/tests/django_test.py new file mode 100644 index 0000000..de099ba --- /dev/null +++ b/fir_ser/tests/django_test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# project: 3月 +# author: NinEveN +# date: 2022/3/9 + +import os + +import django + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'fir_ser.settings') +django.setup() + +from xsign.utils.ctasks import auto_check_ios_developer_active + +# userinfo = UserInfo.objects.first() +# developer_obj_list = AppIOSDeveloperInfo.objects.all() +# aa = [] +# for i in range(22): +# aa.append(developer_obj_list.first()) +# content = loader.render_to_string('check_developer.html', +# {'username': userinfo.first_name, 'developer_obj_list': aa}) +# +# send_ios_developer_active_status(userinfo, content) +auto_check_ios_developer_active() diff --git a/fir_ser/xsign/utils/ctasks.py b/fir_ser/xsign/utils/ctasks.py index d35a93c..c9123b3 100644 --- a/fir_ser/xsign/utils/ctasks.py +++ b/fir_ser/xsign/utils/ctasks.py @@ -8,6 +8,8 @@ import logging import os import time +from django.template import loader + from common.core.sysconfig import Config from fir_ser.settings import SUPER_SIGN_ROOT, SYNC_CACHE_TO_DATABASE from xsign.models import UserInfo, AppIOSDeveloperInfo @@ -41,14 +43,17 @@ def auto_check_ios_developer_active(): if userinfo.supersign_active: status, result = IosUtils.active_developer(ios_developer) msg = f"auto_check_ios_developer_active user:{userinfo} ios.developer:{ios_developer} status:{status} result:{result}" + err_issuer_id.append(ios_developer) + error_issuer_id[userinfo.uid] = list(set(err_issuer_id)) + if status: IosUtils.get_device_from_developer(ios_developer) logger.info(msg) else: - err_issuer_id.append(ios_developer.issuer_id) logger.error(msg) - error_issuer_id[userinfo.uid] = list(set(err_issuer_id)) - for uid, val in error_issuer_id.items(): + + for uid, developer_obj_list in error_issuer_id.items(): userinfo = UserInfo.objects.filter(uid=uid).first() - send_ios_developer_active_status(userinfo, Config.MSG_AUTO_CHECK_DEVELOPER % ( - userinfo.first_name, ",".join(val))) + content = loader.render_to_string('check_developer.html', + {'username': userinfo.first_name, 'developer_obj_list': developer_obj_list}) + send_ios_developer_active_status(userinfo, content) diff --git a/fir_ser/xsign/utils/iossignapi.py b/fir_ser/xsign/utils/iossignapi.py index 8258135..39cc0a2 100644 --- a/fir_ser/xsign/utils/iossignapi.py +++ b/fir_ser/xsign/utils/iossignapi.py @@ -18,7 +18,7 @@ from OpenSSL.crypto import (load_pkcs12, dump_certificate_request, dump_privatek from common.base.baseutils import get_format_time, format_apple_date, make_app_uuid from common.cache.state import CleanErrorBundleIdSignDataState from common.core.sysconfig import Config -from common.libs.apple.appleapiv3 import AppStoreConnectApi +from common.libs.apple.appleapiv3 import AppStoreConnectApi, Certificates, Devices, BundleIds, Profiles from fir_ser.settings import SUPER_SIGN_ROOT from xsign.models import AppIOSDeveloperInfo @@ -260,60 +260,78 @@ class AppDeveloperApiV2(object): if AppIOSDeveloperInfo.objects.filter(pk=self.developer_pk, status__in=Config.DEVELOPER_WRITE_STATUS).first(): start_time = time.time() - logger.info(f'{self.issuer_id} calling {attr.__name__} time:{start_time}') + logger.info(f'issuer_id:{self.issuer_id} calling {attr.__name__} time:{start_time}') result = attr(*args, **kwargs) - logger.info(f'{self.issuer_id} done {attr.__name__} used time:{time.time() - start_time}') + logger.info( + f'issuer_id:{self.issuer_id} done {attr.__name__} used time:{time.time() - start_time}') return result else: result = False, {'return_info': '开发者状态异常'} - logger.warning(f'{self.issuer_id} can not calling {attr.__name__} {result}') + logger.warning(f'issuer_id:{self.issuer_id} can not calling {attr.__name__} {result}') return result return func else: return attr + def __file_format_path_name(self, user_obj): + cert_dir_name = make_app_uuid(user_obj, self.issuer_id) + cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name) + if not os.path.isdir(cert_dir_path): + os.makedirs(cert_dir_path) + return os.path.join(cert_dir_path, cert_dir_name) + + def __result_format(self, result, is_instance): + return_flag = False + if isinstance(result, list): + if len(result) == 0: + return_flag = True + else: + if isinstance(result[0], is_instance): + return_flag = True + else: + if isinstance(result, is_instance): + result = [result] + return_flag = True + if return_flag: + logger.info(f"issuer_id:{self.issuer_id} {is_instance} result:{result}") + return True, result + raise Exception(f'{result} is not {is_instance}') + def active(self): - result = {'data': []} + """ + :return: 结果为空列表,或者是 object 或者是 [object,object] 其他为 false + """ + result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) certificates = apple_obj.get_all_certificates() - if not isinstance(certificates, list): - certificates = [certificates] - result['data'] = certificates - logger.info(f"ios developer active result:{certificates}") - if len(certificates) >= 0: - return True, result + return self.__result_format(certificates, Certificates) except Exception as e: - logger.error(f"ios developer active Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} ios developer active Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result - def file_format_path_name(self, user_obj): - cert_dir_name = make_app_uuid(user_obj, self.issuer_id) - cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name) - if not os.path.isdir(cert_dir_path): - os.makedirs(cert_dir_path) - return os.path.join(cert_dir_path, cert_dir_name) - def create_cert(self, user_obj): result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) - csr_path = self.file_format_path_name(user_obj) + 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 = make_csr_content(csr_path + ".csr", csr_path + ".key") certificates = apple_obj.create_certificate(csr_content.decode("utf-8")) - if certificates: + if certificates and isinstance(certificates, Certificates): n = base64.b64decode(certificates.certificateContent) with open(csr_path + ".cer", 'wb') as f: f.write(n) make_pem(n, csr_path + ".pem") - logger.info(f"ios developer create cert result:{certificates.certificateContent}") + logger.info( + f"issuer_id:{self.issuer_id} ios developer create cert result:{certificates.certificateContent}") return True, certificates + raise Exception(str(certificates)) except Exception as e: - logger.error(f"ios developer create cert Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} ios developer create cert Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -322,13 +340,13 @@ class AppDeveloperApiV2(object): try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) cert_obj = apple_obj.get_certificate_by_cid(self.cert_id) - if cert_obj and cert_obj.id: - return True, result + if cert_obj and isinstance(cert_obj, Certificates): + return True, cert_obj else: - logger.info(f"ios developer get cert {self.cert_id} failed") + logger.info(f"issuer_id:{self.issuer_id} ios developer get cert {self.cert_id} failed") return False, result except Exception as e: - logger.error(f"ios developer get cert {self.cert_id} Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} ios developer get cert {self.cert_id} Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -337,17 +355,19 @@ class AppDeveloperApiV2(object): try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) cert_obj = apple_obj.get_certificate_by_cid(self.cert_id) - if cert_obj: + if cert_obj and isinstance(cert_obj, Certificates): s_date = format_apple_date(cert_obj.expirationDate) if s_date.timestamp() - datetime.datetime.now().timestamp() < 3600 * 24 * 3: if apple_obj.revoke_certificate(self.cert_id): - logger.info(f"ios developer cert {self.cert_id} revoke") + logger.info(f"issuer_id:{self.issuer_id} ios developer cert {self.cert_id} revoke") return True, result else: - logger.info(f"ios developer cert {self.cert_id} not revoke.because expire time < 3 day ") + logger.info( + f"issuer_id:{self.issuer_id} ios developer cert {self.cert_id} not revoke.because expire time < 3 day ") return True, result + raise Exception(str(cert_obj)) except Exception as e: - logger.error(f"ios developer cert {self.cert_id} revoke Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} ios developer cert {self.cert_id} revoke Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -358,16 +378,17 @@ class AppDeveloperApiV2(object): not_after = datetime.datetime.strptime(cer.get_notAfter().decode('utf-8'), "%Y%m%d%H%M%SZ") apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) certificates = apple_obj.get_all_certificates() - if not isinstance(certificates, list): - certificates = [certificates] - for cert_obj in certificates: - f_date = format_apple_date(cert_obj.expirationDate) - 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 + status, result = self.__result_format(certificates, Certificates) + if status: + for cert_obj in result: + f_date = format_apple_date(cert_obj.expirationDate) + logger.info( + f"issuer_id:{self.issuer_id} {cert_obj.id}-{not_after.timestamp()} - {f_date.timestamp()} ") + if not_after.timestamp() == f_date.timestamp(): + return True, cert_obj + raise Exception(str(certificates)) except Exception as e: - logger.error(f"ios developer cert {app_dev_pem} auto get Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} ios developer cert {app_dev_pem} auto get Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -378,7 +399,7 @@ class AppDeveloperApiV2(object): if apple_obj.delete_profile_by_id(profile_id, profile_name): return True except Exception as e: - logger.error(f"ios developer delete profile Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} ios developer delete profile Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -391,18 +412,20 @@ class AppDeveloperApiV2(object): device_obj = apple_obj.enabled_device(device_id, device_name, device_udid) else: device_obj = apple_obj.disabled_device(device_id, device_name, device_udid) - logger.info("device_obj %s result:%s" % (device_obj, status)) - if device_obj and device_obj.id: + logger.info(f"issuer_id:{self.issuer_id} device_obj:{device_obj} result:{status}") + if device_obj and isinstance(device_obj, Devices): return True, result + raise Exception(str(device_obj)) except Exception as e: - logger.error("ios developer set devices status Failed Exception:%s" % e) + logger.error(f"issuer_id:{self.issuer_id} ios developer set devices status Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) if device_err_callback and ("There are no current ios devices" in str(e) or "Device obj is None" in str(e)): with CleanErrorBundleIdSignDataState(failed_call_prefix) as state: if state: device_err_callback() else: - logger.warning(f'{device_err_callback}-{failed_call_prefix} is running') + logger.warning( + f'issuer_id:{self.issuer_id} {device_err_callback}-{failed_call_prefix} is running') return False, result def get_device(self): @@ -410,12 +433,9 @@ class AppDeveloperApiV2(object): try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) devices_obj_list = apple_obj.get_all_devices() - if not isinstance(devices_obj_list, list): - devices_obj_list = [devices_obj_list] - if devices_obj_list is not None: - return True, devices_obj_list + return self.__result_format(devices_obj_list, Devices) except Exception as e: - logger.error("ios developer get device Failed Exception:%s" % e) + logger.error(f"issuer_id:{self.issuer_id} ios developer get device Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -424,10 +444,10 @@ class AppDeveloperApiV2(object): try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) if apple_obj.delete_bundle_by_identifier(identifier_id, f"{bundle_id}.{self.issuer_id}.{app_id}"): - return True, {} + return True, result except Exception as e: - logger.error("ios developer delete app Failed Exception:%s" % e) + logger.error(f"issuer_id:{self.issuer_id} ios developer delete app Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result @@ -444,11 +464,12 @@ class AppDeveloperApiV2(object): bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, f"{bundle_id}.{self.issuer_id}.{app_id}", s_type) - result['aid'] = bundle_obj.id - return True, result - + if bundle_obj and isinstance(bundle_obj, BundleIds): + result['aid'] = bundle_obj.id + return True, result + raise Exception(str(bundle_obj)) except Exception as e: - logger.error("ios developer create app Failed Exception:%s" % e) + logger.error(f"issuer_id:{self.issuer_id} ios developer create app Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) if app_id_err_callback and "There is no App ID with ID" in str(e): for call_fun in app_id_err_callback: @@ -459,18 +480,27 @@ class AppDeveloperApiV2(object): result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) - return True, apple_obj.register_device(device_name, device_udid) + device_obj = apple_obj.register_device(device_name, device_udid) + if device_obj and isinstance(device_obj, Devices): + return True, device_obj + raise Exception(str(device_obj)) except Exception as e: - logger.error("ios developer register device Failed Exception:%s" % e) + logger.error(f"issuer_id:{self.issuer_id} ios developer register device Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) - if device_err_callback and "There are no current ios devices" in str(e): - - with CleanErrorBundleIdSignDataState(failed_call_prefix) as state: - if state: - device_err_callback() - else: - logger.warning(f'{device_err_callback}-{failed_call_prefix} is running') - + err_msg_list = [ + "There are no current ios devices", + "Your development team has reached the maximum number of registered iPhone devices" + ] + if device_err_callback: + for err_msg in err_msg_list: + if err_msg in str(e): + with CleanErrorBundleIdSignDataState(failed_call_prefix) as state: + if state: + device_err_callback() + else: + logger.warning( + f'issuer_id:{self.issuer_id} {device_err_callback}-{failed_call_prefix} is running') + break return False, result def make_and_download_profile(self, app_obj, provision_name, auth, developer_app_id, device_id_list, profile_id, @@ -483,7 +513,7 @@ class AppDeveloperApiV2(object): profile_obj = apple_obj.create_profile(profile_id, developer_app_id, auth.get('cert_id'), provision_name.split("/")[-1], device_id_list) - if profile_obj: + if profile_obj and isinstance(profile_obj, Profiles): result['profile_id'] = profile_obj.id n = base64.b64decode(profile_obj.profileContent) if not os.path.isdir(os.path.dirname(provision_name)): @@ -491,8 +521,10 @@ class AppDeveloperApiV2(object): with open(provision_name, 'wb') as f: f.write(n) return True, result + raise Exception(str(profile_obj)) except Exception as e: - logger.error(f"app_id {app_obj.app_id} ios developer make profile Failed Exception:{e}") + logger.error(f"issuer_id:{self.issuer_id} app_id {app_obj.app_id} ios developer make profile Failed " + f"Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) if app_id_err_callback and "There is no App ID with ID" in str(e): with CleanErrorBundleIdSignDataState(failed_call_prefix) as state: @@ -500,7 +532,8 @@ class AppDeveloperApiV2(object): for call_fun in app_id_err_callback: call_fun() else: - logger.warning(f'{app_id_err_callback}-{failed_call_prefix} is running') + logger.warning( + f'issuer_id:{self.issuer_id} {app_id_err_callback}-{failed_call_prefix} is running') return False, result def modify_capability(self, app_obj, developer_app_id): @@ -522,10 +555,13 @@ class AppDeveloperApiV2(object): bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, f"{bundle_id}.{self.issuer_id}.{app_id}", s_type) - developer_app_id = bundle_obj.id - result['aid'] = developer_app_id + if bundle_obj and isinstance(bundle_obj, BundleIds): + developer_app_id = bundle_obj.id + result['aid'] = developer_app_id + else: + raise Exception(str(bundle_obj)) return True, result except Exception as e: - logger.error("ios developer modify_capability Failed Exception:%s" % e) + logger.error(f"issuer_id:{self.issuer_id} ios developer modify_capability Failed Exception:{e}") result['return_info'] = check_error_call_back(str(e), self.developer_pk) return False, result diff --git a/fir_ser/xsign/utils/supersignutils.py b/fir_ser/xsign/utils/supersignutils.py index fedf6ad..9f3ef50 100644 --- a/fir_ser/xsign/utils/supersignutils.py +++ b/fir_ser/xsign/utils/supersignutils.py @@ -986,9 +986,10 @@ class IosUtils(object): return False, {'err_info': str(e)} @staticmethod - def active_developer(developer_obj): + def active_developer(developer_obj, auto_clean=True): """ 激活开发者账户 + :param auto_clean: :param developer_obj: :return: """ @@ -996,15 +997,16 @@ class IosUtils(object): status, result = app_api_obj.active() if status: cert_is_exists = True - for cert_obj in result.get('data', []): + for cert_obj in result: if cert_obj.id == developer_obj.certid: developer_obj.cert_expire_time = format_apple_date(cert_obj.expirationDate) cert_is_exists = False break - if developer_obj.certid and len(developer_obj.certid) > 3 and cert_is_exists and len( - result.get('data', [])) > 0: + if developer_obj.certid and len(developer_obj.certid) > 3 and cert_is_exists and len(result) > 0: # 数据库证书id和苹果开发id不一致,可认为被用户删掉,需要执行清理开发者操作 - IosUtils.clean_developer(developer_obj, developer_obj.user_id) + if auto_clean: + logger.warning(f"clean developer {developer_obj}") + IosUtils.clean_developer(developer_obj, developer_obj.user_id) developer_obj.certid = None developer_obj.cert_expire_time = None developer_obj.status = 1