diff --git a/fir_ser/api/migrations/0016_developerappid_developerdevicesid.py b/fir_ser/api/migrations/0016_developerappid_developerdevicesid.py new file mode 100644 index 0000000..1c8415a --- /dev/null +++ b/fir_ser/api/migrations/0016_developerappid_developerdevicesid.py @@ -0,0 +1,43 @@ +# Generated by Django 3.0.3 on 2021-01-31 19:55 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0015_auto_20210129_1730'), + ] + + operations = [ + migrations.CreateModel( + name='DeveloperDevicesID', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('did', models.CharField(max_length=64)), + ('app_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Apps', verbose_name='属于哪个APP')), + ('developerid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.AppIOSDeveloperInfo', verbose_name='所使用苹果开发者账户')), + ('udid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.AppUDID', verbose_name='所消耗的udid')), + ], + options={ + 'verbose_name': '超级签Devices id', + 'verbose_name_plural': '超级签Devices id', + 'unique_together': {('did', 'developerid', 'app_id')}, + }, + ), + migrations.CreateModel( + name='DeveloperAppID', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('aid', models.CharField(max_length=64)), + ('app_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Apps', verbose_name='属于哪个APP')), + ('developerid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.AppIOSDeveloperInfo', verbose_name='所使用苹果开发者账户')), + ], + options={ + 'verbose_name': '超级签APP id', + 'verbose_name_plural': '超级签APP id', + 'unique_together': {('aid', 'developerid', 'app_id')}, + }, + ), + ] diff --git a/fir_ser/api/migrations/0017_auto_20210131_2108.py b/fir_ser/api/migrations/0017_auto_20210131_2108.py new file mode 100644 index 0000000..ef0050f --- /dev/null +++ b/fir_ser/api/migrations/0017_auto_20210131_2108.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2021-01-31 21:08 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0016_developerappid_developerdevicesid'), + ] + + operations = [ + migrations.AlterField( + model_name='developerdevicesid', + name='udid', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.UDIDsyncDeveloper', verbose_name='所消耗的udid'), + ), + ] diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index cac5bed..33b335c 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -296,3 +296,32 @@ class UDIDsyncDeveloper(models.Model): def __str__(self): return "%s-%s-%s" % (self.product, self.udid, self.developerid) + + +class DeveloperAppID(models.Model): + aid = models.CharField(max_length=64, null=False) # ,apple APP 唯一标识 + developerid = models.ForeignKey(to="AppIOSDeveloperInfo", on_delete=models.CASCADE, verbose_name="所使用苹果开发者账户") + app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP") + + class Meta: + verbose_name = '超级签APP id' + verbose_name_plural = "超级签APP id" + unique_together = ('aid', 'developerid', 'app_id') + + def __str__(self): + return "%s-%s-%s" % (self.aid, self.app_id, self.developerid) + + +class DeveloperDevicesID(models.Model): + did = models.CharField(max_length=64, null=False) # ,apple 设备唯一标识 + udid = models.ForeignKey(to="UDIDsyncDeveloper", on_delete=models.CASCADE, verbose_name="所消耗的udid") + developerid = models.ForeignKey(to="AppIOSDeveloperInfo", on_delete=models.CASCADE, verbose_name="所使用苹果开发者账户") + app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP") + + class Meta: + verbose_name = '超级签Devices id' + verbose_name_plural = "超级签Devices id" + unique_together = ('did', 'developerid', 'app_id') + + def __str__(self): + return "%s-%s-%s-%s" % (self.id, self.app_id, self.developerid, self.udid) diff --git a/fir_ser/api/utils/app/iossignapi.py b/fir_ser/api/utils/app/iossignapi.py index 48f23ab..de1ec70 100644 --- a/fir_ser/api/utils/app/iossignapi.py +++ b/fir_ser/api/utils/app/iossignapi.py @@ -75,7 +75,8 @@ class AppDeveloperApi(object): self.cmd = self.cmd + " cert add '%s'" % (self.file_format_path_name(user_obj)) return exec_shell(self.cmd) - def get_profile(self, bundleId, app_id, device_udid, device_name, provisionName, auth=None): + def get_profile(self, bundleId, app_id, device_udid, device_name, provisionName, auth=None, first_sign=None, + device_id_list=None): self.cmd = self.cmd + " profile add '%s' '%s' '%s' '%s' '%s' '%s'" % ( bundleId, app_id, device_udid, device_name, self.certid, provisionName) return exec_shell(self.cmd) @@ -204,20 +205,32 @@ class AppDeveloperApiV2(object): result['return_info'] = "%s" % e return False, result - def get_profile(self, bundleId, app_id, device_udid, device_name, provisionName, auth): + def get_profile(self, bundleId, app_id, device_udid, device_name, provisionName, auth, developer_app_id, device_id_list): 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) - apple_obj.register_device(device_name, device_udid) - profile_obj = apple_obj.create_profile(bundle_obj.id, auth.get('certid'), provisionName.split("/")[-1]) - if profile_obj: - n = base64.b64decode(profile_obj.profileContent) - if not os.path.isdir(os.path.dirname(provisionName)): - os.makedirs(os.path.dirname(provisionName)) - with open(provisionName, 'wb') as f: - f.write(n) - return True, profile_obj.profileContent + if developer_app_id: + pass + # 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) + bundle_obj = apple_obj.register_bundle_id_enable_capability(app_id, bundleId + app_id) + developer_app_id = bundle_obj.id + result['aid'] = developer_app_id + + device_obj = apple_obj.register_device(device_name, device_udid) + if device_obj: + result['did'] = device_obj.id + device_id_list.append(device_obj.id) + profile_obj = apple_obj.create_profile(developer_app_id, auth.get('certid'), provisionName.split("/")[-1], + device_id_list) + if profile_obj: + n = base64.b64decode(profile_obj.profileContent) + if not os.path.isdir(os.path.dirname(provisionName)): + os.makedirs(os.path.dirname(provisionName)) + with open(provisionName, 'wb') as f: + f.write(n) + return True, result except Exception as e: logger.error("ios developer make profile Failed Exception:%s" % e) result['return_info'] = "%s" % e diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py index dbb6fde..9fbbdcb 100644 --- a/fir_ser/api/utils/app/supersignutils.py +++ b/fir_ser/api/utils/app/supersignutils.py @@ -8,7 +8,7 @@ import uuid, xmltodict, os, re, logging, time 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, \ - UDIDsyncDeveloper + UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID from api.utils.app.randomstrings import make_app_uuid, make_from_user_uuid from api.utils.serializer import get_developer_udided from api.utils.storage.localApi import LocalStorage @@ -234,14 +234,14 @@ class IosUtils(object): return None return developer_obj - def download_profile(self): + def download_profile(self, developer_app_id, device_id_list): bundleId = self.app_obj.bundle_id app_id = self.app_obj.app_id device_udid = self.udid_info.get('udid') device_name = self.udid_info.get('product') return get_api_obj(self.auth).get_profile(bundleId, app_id, device_udid, device_name, self.get_profile_full_path(), - self.auth) + self.auth, developer_app_id, device_id_list) def get_profile_full_path(self): cert_dir_name = make_app_uuid(self.user_obj, get_apple_udid_key(self.auth)) @@ -262,7 +262,19 @@ class IosUtils(object): logger.info("udid %s not exists app_id %s ,need sign" % (self.udid_info.get('udid'), self.app_obj)) fcount = 3 while fcount > 0: - status, result = self.download_profile() + # apptodev_obj = APPToDeveloper.objects.filter(developerid=self.developer_obj, app_id=self.app_obj).first() + device_id_list = DeveloperDevicesID.objects.filter(app_id=self.app_obj, + developerid=self.developer_obj).values_list('did') + + # first_sign = True + # if apptodev_obj: + # first_sign = False + developer_app_id = None + developer_appid_obj = DeveloperAppID.objects.filter(developerid=self.developer_obj, + app_id=self.app_obj).first() + if developer_appid_obj: + developer_app_id = developer_appid_obj.aid + status, result = self.download_profile(developer_app_id, [did[0] for did in device_id_list]) if not status: fcount -= 1 logger.warning("udid %s app %s developer %s sign failed %s .try again " % ( @@ -319,13 +331,22 @@ class IosUtils(object): 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')) + app_udid_obj = UDIDsyncDeveloper.objects.filter(developerid=self.developer_obj, udid=self.udid_info.get('udid')).first() if not app_udid_obj: - device = AppUDID.objects.filter(app_id=self.app_obj, udid=self.udid_info.get('udid')).values("serial", - 'product', - 'udid', - 'version').first() - UDIDsyncDeveloper.objects.create(developerid=self.developer_obj, **device) + 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) # 创建 apptodev_obj = APPToDeveloper.objects.filter(developerid=self.developer_obj, app_id=self.app_obj).first() @@ -340,6 +361,9 @@ class IosUtils(object): APPToDeveloper.objects.create(developerid=self.developer_obj, app_id=self.app_obj, binary_file=random_file_name, release_file=release_obj.release_id) + if not developer_app_id and result.get("aid", None): + DeveloperAppID.objects.create(aid=result["aid"], developerid=self.developer_obj, app_id=self.app_obj) + @staticmethod def disable_udid(udid_obj, app_id): @@ -367,9 +391,15 @@ class IosUtils(object): app_api_obj.del_profile(app_obj.bundle_id, app_obj.app_id) app_api_obj2 = get_api_obj(auth) app_api_obj2.del_app(app_obj.bundle_id, app_obj.app_id) + DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete() delete_app_to_dev_and_file(developer_obj, app_id) delete_app_profile_file(developer_obj, app_obj) + app_udid_obj = UDIDsyncDeveloper.objects.filter(developerid=developer_obj, + udid=udid_obj.udid).first() + DeveloperDevicesID.objects.filter(udid=app_udid_obj, developerid=developer_obj, app_id_id=app_id).delete() + UDIDsyncDeveloper.objects.filter(udid=udid_obj.udid, developerid=developer_obj).delete() + @staticmethod def clean_udid_by_app_obj(app_obj, developer_obj): @@ -414,7 +444,7 @@ class IosUtils(object): @staticmethod def clean_app_by_developer_obj(app_obj, developer_obj): auth = get_auth_form_developer(developer_obj) - + DeveloperAppID.objects.filter(developerid=developer_obj, app_id=app_obj).delete() app_api_obj = get_api_obj(auth) app_api_obj.del_profile(app_obj.bundle_id, app_obj.app_id) app_api_obj2 = get_api_obj(auth)