超级签名并发优化,签名余额还未限制,下个版本限制

qrnn
youngS 3 years ago
parent a2c5d1bd3f
commit bd8c8d00cc
  1. 14
      fir_ser/api/utils/app/iossignapi.py
  2. 43
      fir_ser/api/utils/app/supersignutils.py
  3. 4
      fir_ser/api/utils/storage/caches.py
  4. 4
      fir_ser/api/views/apps.py
  5. 2
      fir_ser/api/views/receiveudids.py

@ -15,6 +15,7 @@ from OpenSSL.crypto import (load_pkcs12, dump_certificate_request, dump_privatek
from api.utils.app.shellcmds import shell_command, use_user_pass from api.utils.app.shellcmds import shell_command, use_user_pass
from api.utils.apple.appleapiv3 import AppStoreConnectApi from api.utils.apple.appleapiv3 import AppStoreConnectApi
from api.utils.baseutils import get_format_time, format_apple_date, make_app_uuid from api.utils.baseutils import get_format_time, format_apple_date, make_app_uuid
from api.utils.storage.caches import CleanErrorBundleIdSignDataState
from fir_ser.settings import SUPER_SIGN_ROOT from fir_ser.settings import SUPER_SIGN_ROOT
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -306,7 +307,8 @@ class AppDeveloperApiV2(object):
result['return_info'] = "%s" % e result['return_info'] = "%s" % e
return False, result return False, result
def set_device_status(self, status, device_id, device_name, device_udid, device_err_callback=None): def set_device_status(self, status, device_id, device_name, device_udid, failed_call_prefix,
device_err_callback=None):
result = {} result = {}
try: try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
@ -321,7 +323,9 @@ class AppDeveloperApiV2(object):
logger.error("ios developer set devices status Failed Exception:%s" % e) logger.error("ios developer set devices status Failed Exception:%s" % e)
result['return_info'] = "%s" % e result['return_info'] = "%s" % e
if device_err_callback and ("There are no current ios devices" in str(e) or "Device obj is None" in str(e)): if device_err_callback and ("There are no current ios devices" in str(e) or "Device obj is None" in str(e)):
CleanErrorBundleIdSignDataState.set_state(failed_call_prefix)
device_err_callback() device_err_callback()
CleanErrorBundleIdSignDataState.del_state(failed_call_prefix)
return False, result return False, result
def get_device(self): def get_device(self):
@ -372,7 +376,7 @@ class AppDeveloperApiV2(object):
call_fun() call_fun()
return False, result return False, result
def register_device(self, device_udid, device_name, device_err_callback=None): def register_device(self, device_udid, device_name, failed_call_prefix, device_err_callback=None):
result = {} result = {}
try: try:
apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key)
@ -381,11 +385,13 @@ class AppDeveloperApiV2(object):
logger.error("ios developer register device Failed Exception:%s" % e) logger.error("ios developer register device Failed Exception:%s" % e)
result['return_info'] = "%s" % e result['return_info'] = "%s" % e
if device_err_callback and "There are no current ios devices" in str(e): if device_err_callback and "There are no current ios devices" in str(e):
CleanErrorBundleIdSignDataState.set_state(failed_call_prefix)
device_err_callback() device_err_callback()
CleanErrorBundleIdSignDataState.del_state(failed_call_prefix)
return False, result return False, result
def make_and_download_profile(self, app_obj, provision_name, auth, developer_app_id, device_id_list, profile_id, def make_and_download_profile(self, app_obj, provision_name, auth, developer_app_id, device_id_list, profile_id,
app_id_err_callback=None): failed_call_prefix, app_id_err_callback=None):
if app_id_err_callback is None: if app_id_err_callback is None:
app_id_err_callback = [] app_id_err_callback = []
result = {} result = {}
@ -406,8 +412,10 @@ class AppDeveloperApiV2(object):
logger.error(f"app_id {app_obj.app_id} ios developer make profile Failed Exception:{e}") logger.error(f"app_id {app_obj.app_id} ios developer make profile Failed Exception:{e}")
result['return_info'] = "%s" % e result['return_info'] = "%s" % e
if app_id_err_callback and "There is no App ID with ID" in str(e): if app_id_err_callback and "There is no App ID with ID" in str(e):
CleanErrorBundleIdSignDataState.set_state(failed_call_prefix)
for call_fun in app_id_err_callback: for call_fun in app_id_err_callback:
call_fun() call_fun()
CleanErrorBundleIdSignDataState.del_state(failed_call_prefix)
return False, result return False, result
def modify_capability(self, app_obj, developer_app_id): def modify_capability(self, app_obj, developer_app_id):

@ -23,7 +23,8 @@ from api.utils.modelutils import get_ios_developer_public_num, check_ipa_is_late
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
from api.utils.serializer import BillAppInfoSerializer, BillDeveloperInfoSerializer from api.utils.serializer import BillAppInfoSerializer, BillDeveloperInfoSerializer
from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_limit, check_app_permission, \ from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_limit, check_app_permission, \
consume_user_download_times_by_app_obj, add_udid_cache_queue, get_and_clean_udid_cache_queue consume_user_download_times_by_app_obj, add_udid_cache_queue, get_and_clean_udid_cache_queue, \
CleanErrorBundleIdSignDataState
from api.utils.storage.storage import Storage from api.utils.storage.storage import Storage
from api.utils.utils import delete_app_to_dev_and_file, send_ios_developer_active_status, delete_local_files, \ from api.utils.utils import delete_app_to_dev_and_file, send_ios_developer_active_status, delete_local_files, \
download_files_form_oss, get_developer_udided download_files_form_oss, get_developer_udided
@ -51,6 +52,9 @@ def resign_by_app_id(app_obj, need_download_profile=True, force=True):
developer_obj = developer_app_id_obj.developerid developer_obj = developer_app_id_obj.developerid
if check_ipa_is_latest_sign(app_obj, developer_obj) and not force: if check_ipa_is_latest_sign(app_obj, developer_obj) and not force:
continue continue
add_new_bundles_prefix = f"check_or_add_new_bundles_{developer_obj.issuer_id}_{app_obj.app_id}"
if CleanErrorBundleIdSignDataState.get_state(add_new_bundles_prefix):
return False, '清理执行中,请等待'
developer_app_id = developer_app_id_obj.aid developer_app_id = developer_app_id_obj.aid
d_time = time.time() d_time = time.time()
if need_download_profile: if need_download_profile:
@ -59,6 +63,7 @@ def resign_by_app_id(app_obj, need_download_profile=True, force=True):
IosUtils.modify_capability(developer_obj, app_obj, developer_app_id) IosUtils.modify_capability(developer_obj, app_obj, developer_app_id)
status, download_profile_result = IosUtils.make_and_download_profile(app_obj, status, download_profile_result = IosUtils.make_and_download_profile(app_obj,
developer_obj, developer_obj,
add_new_bundles_prefix,
developer_app_id_obj) developer_app_id_obj)
else: else:
status = True status = True
@ -486,8 +491,9 @@ class IosUtils(object):
@staticmethod @staticmethod
@call_function_try_attempts() @call_function_try_attempts()
def check_or_register_devices(app_obj, developer_obj, udid_info): def check_or_register_devices(app_obj, developer_obj, udid_info, failed_call_prefix):
""" """
:param failed_call_prefix:
:param app_obj: :param app_obj:
:param developer_obj: :param developer_obj:
:param udid_info: :param udid_info:
@ -508,6 +514,7 @@ class IosUtils(object):
# 库里面存在,并且设备是禁用状态,需要调用api启用 # 库里面存在,并且设备是禁用状态,需要调用api启用
status, result = get_api_obj(auth).set_device_status("enable", sync_device_obj.serial, status, result = get_api_obj(auth).set_device_status("enable", sync_device_obj.serial,
sync_device_obj.product, sync_device_obj.udid, sync_device_obj.product, sync_device_obj.udid,
failed_call_prefix,
err_callback(IosUtils.get_device_from_developer, err_callback(IosUtils.get_device_from_developer,
developer_obj)) developer_obj))
if not status: # 已经包含异常操作,暂定 if not status: # 已经包含异常操作,暂定
@ -516,7 +523,7 @@ class IosUtils(object):
sync_device_obj.save(update_fields=['status']) sync_device_obj.save(update_fields=['status'])
else: else:
# 库里面不存在,注册设备,新设备注册默认就是启用状态 # 库里面不存在,注册设备,新设备注册默认就是启用状态
status, device_obj = get_api_obj(auth).register_device(device_udid, device_name, status, device_obj = get_api_obj(auth).register_device(device_udid, device_name, failed_call_prefix,
err_callback(IosUtils.get_device_from_developer, err_callback(IosUtils.get_device_from_developer,
developer_obj)) developer_obj))
if not status: if not status:
@ -572,7 +579,8 @@ class IosUtils(object):
@staticmethod @staticmethod
@call_function_try_attempts() @call_function_try_attempts()
def make_and_download_profile(app_obj, developer_obj, developer_app_id_obj=None, new_device_id_list=None, def make_and_download_profile(app_obj, developer_obj, failed_call_prefix, developer_app_id_obj=None,
new_device_id_list=None,
failed_callback=None): failed_callback=None):
if new_device_id_list is None: if new_device_id_list is None:
new_device_id_list = [] new_device_id_list = []
@ -598,7 +606,9 @@ class IosUtils(object):
status, result = get_api_obj(auth).make_and_download_profile(app_obj, status, result = get_api_obj(auth).make_and_download_profile(app_obj,
get_profile_full_path(developer_obj, app_obj), get_profile_full_path(developer_obj, app_obj),
auth, developer_app_id, auth, developer_app_id,
device_id_lists, profile_id, failed_callback) device_id_lists, profile_id,
failed_call_prefix, failed_callback,
)
if not status: if not status:
return False, result return False, result
@ -642,19 +652,22 @@ class IosUtils(object):
logger.warning( logger.warning(
"call_loop download_profile appid:%s developer:%s count:%s" % (self.app_obj, self.developer_obj, count)) "call_loop download_profile appid:%s developer:%s count:%s" % (self.app_obj, self.developer_obj, count))
if self.developer_obj: if self.developer_obj:
with cache.lock("%s_%s_%s" % ('check_or_register_devices', self.developer_obj.issuer_id, self.udid), register_devices_prefix = f"check_or_register_devices_{self.developer_obj.issuer_id}_{self.udid}"
timeout=60): add_new_bundles_prefix = f"check_or_add_new_bundles_{self.developer_obj.issuer_id}_{self.app_obj.app_id}"
download_profile_prefix = f"make_and_download_profile_{self.developer_obj.issuer_id}_{self.app_obj.app_id}"
with cache.lock(register_devices_prefix, timeout=60):
if CleanErrorBundleIdSignDataState.get_state(add_new_bundles_prefix):
return True, True # 程序错误,进行清理的时候,拦截多余的设备注册
status, did_udid_result = IosUtils.check_or_register_devices(self.app_obj, self.developer_obj, status, did_udid_result = IosUtils.check_or_register_devices(self.app_obj, self.developer_obj,
self.udid_info) self.udid_info, add_new_bundles_prefix)
if not status: if not status:
msg = f"app_id {self.app_obj} register devices failed. {did_udid_result}" msg = f"app_id {self.app_obj} register devices failed. {did_udid_result}"
self.sign_failed_fun(d_result, msg) self.sign_failed_fun(d_result, msg)
continue continue
if status and 'continue' in [str(did_udid_result)]: if status and 'continue' in [str(did_udid_result)]:
return True, True return True, True
with cache.lock("%s_%s_%s" % ( with cache.lock(add_new_bundles_prefix, timeout=60):
'check_or_add_new_bundles', self.developer_obj.issuer_id, self.app_obj.app_id),
timeout=60):
status, bundle_result = IosUtils.check_or_add_new_bundles(self.app_obj, self.developer_obj) status, bundle_result = IosUtils.check_or_add_new_bundles(self.app_obj, self.developer_obj)
if not status: if not status:
msg = f"app_id {self.app_obj} create bundles failed. {bundle_result}" msg = f"app_id {self.app_obj} create bundles failed. {bundle_result}"
@ -665,9 +678,7 @@ class IosUtils(object):
add_udid_cache_queue(prefix_key, did_udid_result) add_udid_cache_queue(prefix_key, did_udid_result)
time.sleep(5) time.sleep(5)
with cache.lock("%s_%s_%s" % ( with cache.lock(download_profile_prefix, timeout=60 * 10):
'make_and_download_profile', self.developer_obj.issuer_id, self.app_obj.app_id),
timeout=60 * 10):
did_udid_lists = get_and_clean_udid_cache_queue(prefix_key) did_udid_lists = get_and_clean_udid_cache_queue(prefix_key)
if not did_udid_lists: if not did_udid_lists:
return True, True return True, True
@ -675,6 +686,7 @@ class IosUtils(object):
f'app {self.app_obj} receive {len(did_udid_lists)} did_udid_result: {did_udid_lists}') f'app {self.app_obj} receive {len(did_udid_lists)} did_udid_result: {did_udid_lists}')
status, download_profile_result = IosUtils.make_and_download_profile(self.app_obj, status, download_profile_result = IosUtils.make_and_download_profile(self.app_obj,
self.developer_obj, self.developer_obj,
add_new_bundles_prefix,
new_device_id_list=[did_udid[0] new_device_id_list=[did_udid[0]
for for
did_udid in did_udid in
@ -754,7 +766,8 @@ class IosUtils(object):
if udid_lists.count((udid_obj.udid.udid,)) == 1: if udid_lists.count((udid_obj.udid.udid,)) == 1:
auth = get_auth_form_developer(developer_obj) auth = get_auth_form_developer(developer_obj)
app_api_obj = get_api_obj(auth) app_api_obj = get_api_obj(auth)
app_api_obj.set_device_status("disable", udid_obj.udid.serial, udid_obj.udid.product, udid_obj.udid.udid) app_api_obj.set_device_status("disable", udid_obj.udid.serial, udid_obj.udid.product, udid_obj.udid.udid,
udid_obj.udid.udid)
UDIDsyncDeveloper.objects.filter(udid=udid_obj.udid.udid, developerid=developer_obj).update(status=False) UDIDsyncDeveloper.objects.filter(udid=udid_obj.udid.udid, developerid=developer_obj).update(status=False)
@staticmethod @staticmethod

@ -532,6 +532,10 @@ class CleanAppSignDataState(CacheBaseState):
... ...
class CleanErrorBundleIdSignDataState(CacheBaseState):
...
def add_download_times_free_base(user_obj, amount, payment_name, description, order_type=1): def add_download_times_free_base(user_obj, amount, payment_name, description, order_type=1):
order_number = get_order_num() order_number = get_order_num()
order_obj = Order.objects.create(payment_type=2, order_number=order_number, payment_number=order_number, order_obj = Order.objects.create(payment_type=2, order_number=order_number, payment_number=order_number,

@ -138,6 +138,10 @@ class AppInfoView(APIView):
clean = data.get("clean", None) clean = data.get("clean", None)
if clean: if clean:
if CleanAppSignDataState.get_state(request.user.uid):
res.code = 1008
res.msg = "数据清理中,请耐心等待"
return Response(res.dict)
logger.info(f"app_id:{app_id} clean:{clean} ,close super_sign should clean_app_by_user_obj") logger.info(f"app_id:{app_id} clean:{clean} ,close super_sign should clean_app_by_user_obj")
CleanAppSignDataState.set_state(request.user.uid, timeout=60 * 10) CleanAppSignDataState.set_state(request.user.uid, timeout=60 * 10)
app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first() app_obj = Apps.objects.filter(user_id=request.user, app_id=app_id).first()

@ -8,6 +8,7 @@ import logging
from celery.exceptions import TimeoutError from celery.exceptions import TimeoutError
from django.http import HttpResponsePermanentRedirect, FileResponse, HttpResponse from django.http import HttpResponsePermanentRedirect, FileResponse, HttpResponse
from django.views import View from django.views import View
from rest_framework import exceptions
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
@ -22,7 +23,6 @@ from api.utils.throttle import ReceiveUdidThrottle1, ReceiveUdidThrottle2
from fir_ser.celery import app from fir_ser.celery import app
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from rest_framework import exceptions
class UdidView(View): class UdidView(View):

Loading…
Cancel
Save