From f00135a6a47e52abb4ebdeb6894ce640b8f02f10 Mon Sep 17 00:00:00 2001 From: nineven Date: Wed, 16 Feb 2022 21:30:09 +0800 Subject: [PATCH] =?UTF-8?q?xsign=20=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/apps/FirAppInfossupersign.vue | 4 +- fir_client/src/restful/download.js | 27 ++++++---- fir_client/src/restful/index.js | 35 +++++++------ fir_ser/api/utils/serializer.py | 9 ++-- fir_ser/api/views/download.py | 20 +++++-- fir_ser/api/views/uploads.py | 2 +- fir_ser/common/base/baseutils.py | 51 ++++++++++++++++++ fir_ser/common/core/singals.py | 1 + fir_ser/common/core/sysconfig.py | 4 ++ fir_ser/common/libs/storage/localApi.py | 7 ++- fir_ser/common/utils/caches.py | 28 ++-------- fir_ser/fir_ser/urls.py | 8 +-- fir_ser/xsign/singals/downloadapp.py | 52 +++++++++++++++++++ fir_ser/xsign/utils/utils.py | 51 ------------------ fir_ser/xsign/views/download.py | 5 +- 15 files changed, 184 insertions(+), 120 deletions(-) create mode 100644 fir_ser/xsign/singals/downloadapp.py diff --git a/fir_client/src/components/apps/FirAppInfossupersign.vue b/fir_client/src/components/apps/FirAppInfossupersign.vue index 3d50b28..47d1abb 100644 --- a/fir_client/src/components/apps/FirAppInfossupersign.vue +++ b/fir_client/src/components/apps/FirAppInfossupersign.vue @@ -179,7 +179,7 @@ export default { "data": data }); }, - getappinfo(){ + getappinfo() { appSignInfo(data => { if (data.code === 1000) { for (let name of Object.keys(data.data)) { @@ -244,7 +244,7 @@ export default { }, appinit() { this.currentapp = this.$store.state.currentapp; - if(this.currentapp.app_id){ + if (this.currentapp.app_id) { this.getappinfo(); } this.set_default_flag(); diff --git a/fir_client/src/restful/download.js b/fir_client/src/restful/download.js index bb2e590..1df5d96 100644 --- a/fir_client/src/restful/download.js +++ b/fir_client/src/restful/download.js @@ -113,17 +113,6 @@ export function getdownloadurl(callBack, params) { ); } -/**获取签名任务状态 */ -export function gettask(callBack, params) { - getData( - 'GET', - USERSEVER + '/task/' + params.short, - params.data, - data => { - callBack(data); - }, - ); -} /**应用举报 */ export function appReport(callBack, params) { @@ -202,3 +191,19 @@ export function geetest(self, uid, params, callback) { "data": {user_id: uid} }); } + +/** 超级签名************************************************相关api */ + +/**获取签名任务状态 */ +let SIGNSEVER = DOMAIN + '/api/v1/fir/xsign'; + +export function gettask(callBack, params) { + getData( + 'GET', + SIGNSEVER + '/task/' + params.short, + params.data, + data => { + callBack(data); + }, + ); +} \ No newline at end of file diff --git a/fir_client/src/restful/index.js b/fir_client/src/restful/index.js index dc439f2..9069993 100644 --- a/fir_client/src/restful/index.js +++ b/fir_client/src/restful/index.js @@ -589,21 +589,6 @@ export function domainFun(callBack, params, load = true) { ); } -/**获取签名任务状态 */ -export function gettask(callBack, params, load = true) { - getData( - 'GET', - USERSEVER + '/task/' + params.short, - params.data, - data => { - callBack(data); - }, - load, - true, - true - ); -} - /**微信用户绑定 */ export function wxutils(callBack, params, load = true) { @@ -681,7 +666,7 @@ export function appReport(callBack, params, load = true) { ); } -// 超级签名相关api +/** 超级签名************************************************相关api */ let SIGNSEVER = DOMAIN + '/api/v1/fir/xsign'; @@ -851,4 +836,20 @@ export function developercert(callBack, params, load = true) { true, true ); -} \ No newline at end of file +} + +/**获取签名任务状态 */ +export function gettask(callBack, params, load = true) { + getData( + 'GET', + SIGNSEVER + '/task/' + params.short, + params.data, + data => { + callBack(data); + }, + load, + true, + true + ); +} + diff --git a/fir_ser/api/utils/serializer.py b/fir_ser/api/utils/serializer.py index c2b53c4..f9ca69c 100644 --- a/fir_ser/api/utils/serializer.py +++ b/fir_ser/api/utils/serializer.py @@ -111,12 +111,13 @@ class AppsSerializer(serializers.ModelSerializer): def get_preview_url(self, obj): return get_app_download_uri(None, obj.user_id, obj) - # private_developer_number = serializers.SerializerMethodField() + private_developer_number = serializers.IntegerField(default=0) + count = serializers.IntegerField(default=0) # # def get_private_developer_number(self, obj): # return models.AppleDeveloperToAppUse.objects.filter(app_id=obj).count() # - # private_developer_used_number = serializers.SerializerMethodField() + private_developer_used_number = serializers.IntegerField(default=0) # # def get_private_developer_used_number(self, obj): # return models.DeveloperDevicesID.objects.filter(app_id=obj, @@ -132,12 +133,12 @@ class AppsSerializer(serializers.ModelSerializer): def get_sign_type_choice(self, obj): return get_choices_dict(obj.supersign_type_choices) - # supersign_used_number = serializers.SerializerMethodField() + supersign_used_number = serializers.IntegerField(default=0) # # def get_supersign_used_number(self, obj): # return models.APPSuperSignUsedInfo.objects.filter(app_id=obj).all().count() # - # developer_used_count = serializers.SerializerMethodField() + developer_used_count = serializers.IntegerField(default=0) # # def get_developer_used_count(self, obj): # return models.DeveloperAppID.objects.filter(app_id=obj).all().count() diff --git a/fir_ser/api/views/download.py b/fir_ser/api/views/download.py index 0b49ae3..5bef819 100644 --- a/fir_ser/api/views/download.py +++ b/fir_ser/api/views/download.py @@ -16,9 +16,9 @@ from api.utils.modelutils import get_filename_form_file, check_app_domain_name_a ad_random_weight, get_app_download_uri from api.utils.response import BaseResponse from api.utils.serializer import AppsShortSerializer, AppAdInfoSerializer -from common.base.baseutils import get_origin_domain_name, format_get_uri +from common.base.baseutils import get_origin_domain_name, format_get_uri, make_random_uuid, make_resigned from common.core.decorators import cache_response # 本来使用的是 drf-extensions==0.7.0 但是还未支持该版本Django -from common.core.response import mobileprovision_file_response +from common.core.response import mobileprovision_file_response, file_response, ApiResponse from common.core.sysconfig import Config from common.core.throttle import VisitShortThrottle, InstallShortThrottle, InstallThrottle1, InstallThrottle2 from common.utils.caches import check_app_permission, get_app_download_url @@ -50,7 +50,21 @@ class DownloadView(APIView): flag = verify_token(down_token, filename) if flag: - if f_type == 'dmobileprovision': # 企业签名安装信任跳转 + if f_type == 'plist': + release_id = filename.split('.')[0] + release_obj = AppReleaseInfo.objects.filter(release_id=release_id).first() + if release_obj: + app_obj = release_obj.app_id + storage = Storage(app_obj.user_id) + bundle_id = app_obj.bundle_id + app_version = release_obj.app_version + name = app_obj.name + ios_plist_bytes = make_resigned(storage.get_download_url(filename.split('.')[0] + ".ipa"), + storage.get_download_url(release_obj.icon_url), bundle_id, + app_version, name) + return file_response(ios_plist_bytes, make_random_uuid(), "application/x-plist") + return ApiResponse(code=1004, msg="plist release_id error") + elif f_type == 'dmobileprovision': # 企业签名安装信任跳转 release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() if release_obj: file_path = Config.DEFAULT_MOBILEPROVISION.get("enterprise").get('path') diff --git a/fir_ser/api/views/uploads.py b/fir_ser/api/views/uploads.py index fe5cd38..6a80eaf 100644 --- a/fir_ser/api/views/uploads.py +++ b/fir_ser/api/views/uploads.py @@ -138,7 +138,7 @@ class AppAnalyseView(APIView): storage.rename_file(app_tmp_filename, app_new_filename) storage.rename_file(png_tmp_filename, png_new_filename) - app_obj = Apps.objects.filter(bundle_id=data.get("bundleid"), user_id=request.user, type=4).first() + app_obj = Apps.objects.filter(bundle_id=data.get("bundleid"), user_id=request.user, type=1).first() if app_obj: run_resign_task_signal.send(sender=None, app_pk=app_obj.pk) else: diff --git a/fir_ser/common/base/baseutils.py b/fir_ser/common/base/baseutils.py index 8eb1a51..654f4d7 100644 --- a/fir_ser/common/base/baseutils.py +++ b/fir_ser/common/base/baseutils.py @@ -324,3 +324,54 @@ def get_choices_name_from_key(choices, key): if choice[0] == key: return choice[1] return '' + + +def make_resigned(bin_url, img_url, bundle_id, app_version, name): + ios_plist_tem = """ + + items + + + assets + + + kind + software-package + url + + + + kind + display-image + needs-shine + 0 + url + + + + kind + full-size-image + needs-shine + + url + + + + metadata + + bundle-identifier + {bundle_id} + bundle-version + + kind + software + title + + + + + +""".format(bin_url=bin_url, img_url=img_url, bundle_id=bundle_id, app_version=app_version, name=name) + logger.info( + f"make_resigned bin_url {bin_url} ,img_url {img_url}, bundle_id {bundle_id}, app_version {app_version}, name {name}") + return ios_plist_tem diff --git a/fir_ser/common/core/singals.py b/fir_ser/common/core/singals.py index 9848c00..835a579 100644 --- a/fir_ser/common/core/singals.py +++ b/fir_ser/common/core/singals.py @@ -27,6 +27,7 @@ def run_resign_task_callback(sender, **kwargs): if app_obj.change_auto_sign: c_task = run_resign_task(app_obj.pk, False, False) logger.info(f"app {app_obj} run_resign_task end msg:{c_task}") + return 'success' """ diff --git a/fir_ser/common/core/sysconfig.py b/fir_ser/common/core/sysconfig.py index 6c57446..2da50ac 100644 --- a/fir_ser/common/core/sysconfig.py +++ b/fir_ser/common/core/sysconfig.py @@ -323,6 +323,10 @@ class AppleDeveloperConfCache(ConfigCacheBase): def DEVELOPER_DISABLED_STATUS(self): return super().get_value('DEVELOPER_DISABLED_STATUS', APPLEDEVELOPERCONF.DEVELOPER_DISABLED_STATUS) + @property + def DEVELOPER_UID_KEY(self): + return super().get_value('DEVELOPER_UID_KEY', APPLEDEVELOPERCONF.DEVELOPER_UID_KEY) + class ConfigCache(BaseConfCache, IpaConfCache, AuthConfCache, EmailMsgCache, UserDownloadTimesCache, GeeTestConfCache, PayConfCache, ThirdPartConfCache, AppleDeveloperConfCache): diff --git a/fir_ser/common/libs/storage/localApi.py b/fir_ser/common/libs/storage/localApi.py index 315b1fd..8c5a38d 100644 --- a/fir_ser/common/libs/storage/localApi.py +++ b/fir_ser/common/libs/storage/localApi.py @@ -31,8 +31,11 @@ class LocalStorage(object): uri = 'https://' if self.is_https else 'http://' return f"{uri}{self.domain_name}" - def get_download_url(self, name, expires=600, force_new=False): - download_url = '/'.join([self.get_base_url(), 'download', name]) + def get_download_url(self, name, expires=600, force_new=False, is_xsign=False): + d_dir = 'download' + if name.endswith('.mobileconifg') or is_xsign: + d_dir = 'xdownload' + download_url = '/'.join([self.get_base_url(), d_dir, name]) if self.download_auth_type == 1: download_url = f"{download_url}?{settings.DATA_DOWNLOAD_KEY}={make_token(name, expires, force_new=force_new)}" elif self.download_auth_type == 2: diff --git a/fir_ser/common/utils/caches.py b/fir_ser/common/utils/caches.py index 8af5612..4f8d0e9 100644 --- a/fir_ser/common/utils/caches.py +++ b/fir_ser/common/utils/caches.py @@ -12,7 +12,7 @@ from django.core.cache import cache from django.db.models import F from django.utils import timezone -from api.models import Apps, UserInfo, AppReleaseInfo, UserCertificationInfo, Order +from api.models import Apps, UserInfo, UserCertificationInfo, Order from api.utils.modelutils import get_app_d_count_by_app_id, get_app_domain_name, get_user_domain_name, \ add_remote_info_from_request from common.base.baseutils import check_app_password, get_order_num, get_real_ip_address @@ -24,6 +24,7 @@ from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCac from common.core.sysconfig import Config from common.utils.storage import Storage, LocalStorage from fir_ser.settings import CACHE_KEY_TEMPLATE, SYNC_CACHE_TO_DATABASE +from xsign.singals.downloadapp import xsign_app_download_url_signal logger = logging.getLogger(__name__) @@ -44,28 +45,9 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', if app_obj.get('issupersign', None): download_url_type = 'mobileconifg' else: - appudid_obj = AppUDID.objects.filter(app_id_id=app_obj.get("pk"), udid__udid=udid, sign_status=4).last() - if appudid_obj: - super_sign_obj = APPSuperSignUsedInfo.objects.filter(udid__udid__udid=udid, - app_id_id=app_obj.get("pk"), - developerid__status__in=Config.DEVELOPER_USE_STATUS).last() - if super_sign_obj and super_sign_obj.user_id.supersign_active: - app_to_developer_obj = APPToDeveloper.objects.filter(app_id_id=app_obj.get("pk"), - developerid=super_sign_obj.developerid).last() - if app_to_developer_obj: - release_obj = AppReleaseInfo.objects.filter(app_id_id=app_obj.get("pk"), is_master=True).last() - if release_obj.release_id == app_to_developer_obj.release_file: - binary_file = app_to_developer_obj.binary_file - else: - binary_file = app_to_developer_obj.release_file - return local_storage.get_download_url( - binary_file + "." + download_url_type, limit), "" - else: - return "", "" - else: - return "", "" - else: - return "", "" + result = xsign_app_download_url_signal.send(None, app_pk=app_obj.get('pk'), udid=udid, + download_url_type=download_url_type, limit=limit) + return result[0][1] supersign = Config.DEFAULT_MOBILEPROVISION.get("supersign") mobileconifg = "" diff --git a/fir_ser/fir_ser/urls.py b/fir_ser/fir_ser/urls.py index faf74ea..d4dab91 100644 --- a/fir_ser/fir_ser/urls.py +++ b/fir_ser/fir_ser/urls.py @@ -20,20 +20,22 @@ from django.views.static import serve from admin.views.celery_flower import CeleryFlowerView from api.views.download import DownloadView, InstallView from fir_ser import settings +from xsign.views.download import XsignDownloadView from xsign.views.receiveudids import IosUDIDView, ShowUdidView urlpatterns = [ re_path('fly.admin/', admin.site.urls), re_path("api/v1/fir/server/", include('api.urls')), re_path("api/v1/fir/xsign/", include('xsign.urls')), + re_path(r"xdownload/(?P\w+\.\w+)$", XsignDownloadView.as_view(), name="xdownload"), re_path("api/v2/fir/server/", include('cli.urls')), re_path("api/v3/fir/server/", include('admin.urls')), re_path('^captcha/', include('captcha.urls')), # media路径配置 re_path('files/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}), - re_path("download/(?P\w+\.\w+)$", DownloadView.as_view(), name="download"), - re_path("install/(?P\w+)$", InstallView.as_view(), name="install"), - re_path("^udid/(?P\w+)$", IosUDIDView.as_view()), + re_path(r"download/(?P\w+\.\w+)$", DownloadView.as_view(), name="download"), + re_path(r"install/(?P\w+)$", InstallView.as_view(), name="install"), + re_path(r"^udid/(?P\w+)$", IosUDIDView.as_view()), re_path("^show_udid$", ShowUdidView.as_view()), re_path(r'flower/(?P.*)', CeleryFlowerView.as_view()), ] diff --git a/fir_ser/xsign/singals/downloadapp.py b/fir_ser/xsign/singals/downloadapp.py new file mode 100644 index 0000000..41d902a --- /dev/null +++ b/fir_ser/xsign/singals/downloadapp.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# author: NinEveN +# date: 2022/2/15 +import logging + +from django.dispatch import Signal, receiver + +from api.models import AppReleaseInfo +from common.core.sysconfig import Config +from common.libs.storage.localApi import LocalStorage +from xsign.models import AppUDID, APPToDeveloper, APPSuperSignUsedInfo + +logger = logging.getLogger(__name__) + +""" +xsign 下载连接 +""" + +xsign_app_download_url_signal = Signal(providing_args=["app_pk", "udid", "download_url_type", "limit"]) + + +@receiver(xsign_app_download_url_signal) +def xsign_app_download_url_callback(sender, **kwargs): + udid = kwargs.get('udid') + download_url_type = kwargs.get('download_url_type') + limit = kwargs.get('limit') + app_pk = kwargs.get('app_pk') + + local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN) + appudid_obj = AppUDID.objects.filter(app_id_id=app_pk, udid__udid=udid, sign_status=4).last() + if appudid_obj: + super_sign_obj = APPSuperSignUsedInfo.objects.filter(udid__udid__udid=udid, + app_id_id=app_pk, + developerid__status__in=Config.DEVELOPER_USE_STATUS).last() + if super_sign_obj and super_sign_obj.user_id.supersign_active: + app_to_developer_obj = APPToDeveloper.objects.filter(app_id_id=app_pk, + developerid=super_sign_obj.developerid).last() + if app_to_developer_obj: + release_obj = AppReleaseInfo.objects.filter(app_id_id=app_pk, is_master=True).last() + if release_obj.release_id == app_to_developer_obj.release_file: + binary_file = app_to_developer_obj.binary_file + else: + binary_file = app_to_developer_obj.release_file + return local_storage.get_download_url( + binary_file + "." + download_url_type, limit, is_xsign=True), "" + else: + return "", "" + else: + return "", "" + else: + return "", "" diff --git a/fir_ser/xsign/utils/utils.py b/fir_ser/xsign/utils/utils.py index e4d14d2..cf57006 100644 --- a/fir_ser/xsign/utils/utils.py +++ b/fir_ser/xsign/utils/utils.py @@ -20,54 +20,3 @@ def delete_app_to_dev_and_file(developer_obj, app_id): storage = Storage(developer_obj.user_id) storage.delete_file(binary_file) app_to_developer_obj.delete() - - -def make_resigned(bin_url, img_url, bundle_id, app_version, name): - ios_plist_tem = """ - - items - - - assets - - - kind - software-package - url - - - - kind - display-image - needs-shine - 0 - url - - - - kind - full-size-image - needs-shine - - url - - - - metadata - - bundle-identifier - {bundle_id} - bundle-version - - kind - software - title - - - - - -""".format(bin_url=bin_url, img_url=img_url, bundle_id=bundle_id, app_version=app_version, name=name) - logger.info( - f"make_resigned bin_url {bin_url} ,img_url {img_url}, bundle_id {bundle_id}, app_version {app_version}, name {name}") - return ios_plist_tem diff --git a/fir_ser/xsign/views/download.py b/fir_ser/xsign/views/download.py index 9e8aa0b..30a7797 100644 --- a/fir_ser/xsign/views/download.py +++ b/fir_ser/xsign/views/download.py @@ -10,7 +10,7 @@ import os from rest_framework.views import APIView from api.models import AppReleaseInfo -from common.base.baseutils import get_profile_full_path, make_random_uuid, get_server_domain_from_request +from common.base.baseutils import get_profile_full_path, make_random_uuid, get_server_domain_from_request, make_resigned from common.core.response import ApiResponse, file_response, mobileprovision_file_response from common.core.sysconfig import Config from common.utils.storage import Storage, get_local_storage @@ -18,7 +18,6 @@ from common.utils.token import verify_token from fir_ser import settings from xsign.models import APPToDeveloper, APPSuperSignUsedInfo from xsign.utils.supersignutils import make_sign_udid_mobile_config -from xsign.utils.utils import make_resigned logger = logging.getLogger(__name__) @@ -29,7 +28,7 @@ def get_post_udid_url(request, short): return "/".join(path_info_lists) -class DownloadView(APIView): +class XsignDownloadView(APIView): """ 文件下载接口,适用于本地存储和所有plist文件下载 """