diff --git a/fir_client/src/components/apps/FirAppInfosBase.vue b/fir_client/src/components/apps/FirAppInfosBase.vue index e26acc8..4908d07 100644 --- a/fir_client/src/components/apps/FirAppInfosBase.vue +++ b/fir_client/src/components/apps/FirAppInfosBase.vue @@ -115,7 +115,7 @@ margin: 20 }, icon_url: "", - appinfos: {}, + appinfos: {status:1}, master_release: {}, allapp: [], activity: { diff --git a/fir_client/src/components/apps/FirAppInfossupersign.vue b/fir_client/src/components/apps/FirAppInfossupersign.vue index af566ee..d40f984 100644 --- a/fir_client/src/components/apps/FirAppInfossupersign.vue +++ b/fir_client/src/components/apps/FirAppInfossupersign.vue @@ -2,10 +2,10 @@
- + - @@ -25,8 +25,7 @@ - + @@ -49,8 +48,7 @@ - + - + - + 该用户暂未开通超级签权限,请联系管理员申请开通
diff --git a/fir_ser/api/migrations/0003_auto_20210526_1645.py b/fir_ser/api/migrations/0003_auto_20210526_1645.py new file mode 100644 index 0000000..d63de70 --- /dev/null +++ b/fir_ser/api/migrations/0003_auto_20210526_1645.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.3 on 2021-05-26 16:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0002_domaincnameinfo_is_https'), + ] + + operations = [ + migrations.AlterModelOptions( + name='domaincnameinfo', + options={'verbose_name': '系统分发域名配置', 'verbose_name_plural': '系统分发域名配置'}, + ), + migrations.AlterModelOptions( + name='userdomaininfo', + options={'verbose_name': '用户分发域名绑定', 'verbose_name_plural': '用户分发域名绑定'}, + ), + migrations.AlterField( + model_name='apps', + name='supersign_type', + field=models.SmallIntegerField( + choices=[(0, '普通权限'), (1, '推送权限,请上传adhoc包'), (2, 'network、vpn、推送权限,请上传adhoc包'), (3, '特殊权限')], default=1, + verbose_name='签名类型'), + ), + ] diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index 669b9d5..081fc87 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -115,8 +115,8 @@ class Apps(models.Model): password = models.CharField(verbose_name="访问密码", blank=True, help_text='默认 没有密码', max_length=32) isshow = models.BooleanField(verbose_name="下载页可见", default=True) issupersign = models.BooleanField(verbose_name="是否超级签名包", default=False) - supersign_type_choices = ((0, '普通权限'), (1, '特殊权限(包含network、vpn)')) - supersign_type = models.SmallIntegerField(choices=supersign_type_choices, default=0, verbose_name="签名类型") + supersign_type_choices = ((0, '普通权限'), (1, '推送权限,请上传adhoc包'), (2, 'network、vpn、推送权限,请上传adhoc包'), (3, '特殊权限')) + supersign_type = models.SmallIntegerField(choices=supersign_type_choices, default=1, verbose_name="签名类型") new_bundle_id = models.CharField(max_length=64, blank=True, null=True, verbose_name="new_bundle_id", help_text="用于超级签某些因素下需要修改包名") supersign_limit_number = models.IntegerField(verbose_name="签名使用限额", default=0) diff --git a/fir_ser/api/utils/app/iossignapi.py b/fir_ser/api/utils/app/iossignapi.py index b983a70..3202bdd 100644 --- a/fir_ser/api/utils/app/iossignapi.py +++ b/fir_ser/api/utils/app/iossignapi.py @@ -217,6 +217,7 @@ class AppDeveloperApiV2(object): result = {} bundle_id = app_obj.bundle_id app_id = app_obj.app_id + s_type = app_obj.supersign_type try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) if developer_app_id: @@ -224,10 +225,10 @@ class AppDeveloperApiV2(object): # bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundleId + app_id) else: # bundle_obj = apple_obj.list_bundle_ids_by_identifier(bundleId + app_id) - if app_obj.supersign_type == 0: + if s_type == 0: bundle_obj = apple_obj.register_bundle_id(app_id, bundle_id + app_id) else: - bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundle_id + app_id) + bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundle_id + app_id, s_type) developer_app_id = bundle_obj.id result['aid'] = developer_app_id if udid_info: @@ -306,11 +307,12 @@ class AppDeveloperApiV2(object): result['return_info'] = "%s" % e return False, result - def create_app(self, bundleId, app_id): + # 该方法未使用 + def create_app(self, bundleId, app_id, s_type): result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) - bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundleId + app_id) + bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundleId + app_id, s_type) developer_app_id = bundle_obj.id result['aid'] = developer_app_id return True, result @@ -323,19 +325,20 @@ class AppDeveloperApiV2(object): def modify_capability(self, app_obj, developer_app_id): bundle_id = app_obj.bundle_id app_id = app_obj.app_id + s_type = app_obj.supersign_type result = {} try: apple_obj = AppStoreConnectApi(self.issuer_id, self.private_key_id, self.p8key) if developer_app_id: - if app_obj.supersign_type == 0: - result['code'] = apple_obj.disable_push_vpn_capability(developer_app_id) + if s_type == 0: + result['code'] = apple_obj.disable_capability_by_s_type(developer_app_id) else: - result['code'] = apple_obj.enable_push_vpn_capability(developer_app_id) + result['code'] = apple_obj.enable_capability_by_s_type(developer_app_id, s_type) else: - if app_obj.supersign_type == 0: + if s_type == 0: bundle_obj = apple_obj.register_bundle_id(app_id, bundle_id + app_id) else: - bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundle_id + app_id) + bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundle_id + app_id, s_type) developer_app_id = bundle_obj.id result['aid'] = developer_app_id return True, result diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index 4b54453..7177d25 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -286,7 +286,8 @@ class IosUtils(object): def create_app(self, app_obj): bundleId = self.app_obj.bundle_id app_id = self.app_obj.app_id - return get_api_obj(self.auth).create_app(bundleId, app_id) + s_type = self.app_obj.supersign_type + return get_api_obj(self.auth).create_app(bundleId, app_id, s_type) @staticmethod def modify_capability(developer_obj, app_obj, developer_app_id): diff --git a/fir_ser/api/utils/apple/appleapiv3.py b/fir_ser/api/utils/apple/appleapiv3.py index d7c1b35..aec4a08 100644 --- a/fir_ser/api/utils/apple/appleapiv3.py +++ b/fir_ser/api/utils/apple/appleapiv3.py @@ -25,6 +25,45 @@ def request_format_log(req): return req +# 需要和model里面的对应起来 +capability = [ + [], + ["PUSH_NOTIFICATIONS"], + [ + "PERSONAL_VPN", + "PUSH_NOTIFICATIONS", + "NETWORK_EXTENSIONS", + ], + [ + "PERSONAL_VPN", + "PUSH_NOTIFICATIONS", + "NETWORK_EXTENSIONS", + "WALLET", + "ICLOUD", + "INTER_APP_AUDIO", + "ASSOCIATED_DOMAINS", + "APP_GROUPS", + "HEALTHKIT", + "HOMEKIT", + "WIRELESS_ACCESSORY_CONFIGURATION", + "APPLE_PAY", + "DATA_PROTECTION", + "SIRIKIT", + "MULTIPATH", + "HOT_SPOT", + "NFC_TAG_READING", + "CLASSKIT", + "AUTOFILL_CREDENTIAL_PROVIDER", + "ACCESS_WIFI_INFORMATION", + "COREMEDIA_HLS_LOW_LATENCY", + ] +] + + +def get_capability(s_type): + return capability[s_type] + + class DevicesAPI(object): # https://developer.apple.com/documentation/appstoreconnectapi/devices def __init__(self, base_uri, jwt_headers): @@ -741,8 +780,30 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi return True return False + def enable_capability_by_s_type(self, bundle_id, s_type): + capability_list = get_capability(s_type) + if capability_list: + 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)) + else: + logger.warning("%s enable_capability %s failed %s" % (bundle_id, capability, req.content)) + return True + + def disable_capability_by_s_type(self, bundle_id, s_type=len(capability) - 1): + capability_list = get_capability(s_type) + if capability_list: + 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)) + else: + logger.warning("%s enable_capability %s failed %s" % (bundle_id, capability, req.content)) + return True + def enable_push_vpn_capability(self, bundle_id): - # 'PUSH_NOTIFICATIONS', # PERSONAL_VPN + # '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') @@ -768,10 +829,11 @@ class AppStoreConnectApi(DevicesAPI, BundleIDsAPI, BundleIDsCapabilityAPI, Profi req = super().register_bundle_id(bundle_id_name, bundle_id_identifier, platform, seed_id) return self.__bundle_ids_store(req, 201) - def register_bundle_id_enable_capability(self, bundle_id_name, bundle_id_identifier, platform="IOS", seed_id=''): + def register_bundle_id_enable_capability(self, bundle_id_name, bundle_id_identifier, s_type, platform="IOS", + seed_id=''): bundle_ids = self.register_bundle_id(bundle_id_name, bundle_id_identifier, platform, seed_id) if isinstance(bundle_ids, BundleIds): - if self.enable_push_vpn_capability(bundle_ids.id): + if self.enable_capability_by_s_type(bundle_ids.id, s_type): return bundle_ids def delete_bundle_by_identifier(self, identifier): diff --git a/fir_ser/api/utils/storage/aliyunApi.py b/fir_ser/api/utils/storage/aliyunApi.py index 38c66ab..b3b6ec8 100644 --- a/fir_ser/api/utils/storage/aliyunApi.py +++ b/fir_ser/api/utils/storage/aliyunApi.py @@ -189,3 +189,9 @@ class AliYunOss(object): # # current = fileobj.tell() # self.bucket.put_object(os.path.basename(local_file_full_path), fileobj) return True + + def download_file(self, name, local_file_full_path): + dir_path = os.path.dirname(local_file_full_path) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + return self.bucket.get_object_to_file(name, local_file_full_path) diff --git a/fir_ser/api/utils/storage/qiniuApi.py b/fir_ser/api/utils/storage/qiniuApi.py index c6f6c6e..7dc9dae 100644 --- a/fir_ser/api/utils/storage/qiniuApi.py +++ b/fir_ser/api/utils/storage/qiniuApi.py @@ -8,7 +8,10 @@ ''' from qiniu import Auth, put_file, etag from qiniu import BucketManager -import os +import os, requests +import logging + +logger = logging.getLogger(__file__) class QiNiuOss(object): @@ -63,3 +66,22 @@ class QiNiuOss(object): ret, info = put_file(token, filename, local_file_full_path) if ret['key'] == filename and ret['hash'] == etag(local_file_full_path): return True + + def download_file(self, name, local_file_full_path): + dir_path = os.path.dirname(local_file_full_path) + if not os.path.exists(dir_path): + 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)) + 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) + return True + except Exception as e: + logger.error("check download file and move file %s failed Exception %s" % (local_file_full_path, e)) + return False diff --git a/fir_ser/api/utils/storage/storage.py b/fir_ser/api/utils/storage/storage.py index f7db80b..8862146 100644 --- a/fir_ser/api/utils/storage/storage.py +++ b/fir_ser/api/utils/storage/storage.py @@ -72,6 +72,13 @@ class Storage(object): except Exception as e: logger.error("oss upload %s failed Exception %s" % (local_file_full_path, 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)) + def get_storage(self, user, storage_obj, use_default_storage): if storage_obj: self.storage_obj = storage_obj diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py index c30978e..04b0f0a 100644 --- a/fir_ser/api/utils/utils.py +++ b/fir_ser/api/utils/utils.py @@ -177,26 +177,13 @@ def change_storage_and_change_head_img(user_obj, new_storage_obj): def download_files_form_oss(storage_obj, org_file): - 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) - if req.status_code == 200: - logger.info("download file %s success" % org_file) - else: - logger.error("download file %s failed %s" % (org_file, req.content)) - return False - try: - with open(org_file + ".check.tmp", "wb") as f: - for chunk in req.iter_content(chunk_size=5120): - if chunk: - f.write(chunk) - logger.info("save download file %s success" % org_file) - if os.path.isfile(org_file): + if storage_obj.download_file(os.path.basename(org_file), org_file + ".check.tmp"): + if os.path.isfile(org_file) and os.path.exists(org_file + ".check.tmp"): os.remove(org_file) - os.rename(os.path.join(org_file + ".check.tmp"), org_file) - return True - except Exception as e: - logger.error("check download file and move file %s failed Exception %s" % (org_file, e)) - return False + if os.path.exists(org_file + ".check.tmp"): + os.rename(os.path.join(org_file + ".check.tmp"), org_file) + return True + return False def check_storage_is_new_storage(user_obj, new_storage_obj):