From 81db86b9efa525e99de06055fe4dcd93b64bf3eb Mon Sep 17 00:00:00 2001 From: nineven Date: Thu, 17 Feb 2022 10:59:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fir_ser/admin/views/app.py | 3 +- fir_ser/api/urls.py | 5 +- fir_ser/api/views/download.py | 3 +- fir_ser/common/core/singals.py | 43 +++++- fir_ser/common/libs/storage/localApi.py | 4 +- fir_ser/common/utils/caches.py | 178 +----------------------- fir_ser/common/utils/download.py | 151 ++++++++++++++++++++ fir_ser/fir_ser/urls.py | 29 ++-- fir_ser/xsign/singals/downloadapp.py | 52 ------- fir_ser/xsign/urls.py | 19 ++- fir_ser/xsign/views/download.py | 4 +- fir_ser/xsign/views/supersign.py | 2 +- 12 files changed, 241 insertions(+), 252 deletions(-) create mode 100644 fir_ser/common/utils/download.py delete mode 100644 fir_ser/xsign/singals/downloadapp.py diff --git a/fir_ser/admin/views/app.py b/fir_ser/admin/views/app.py index 15ec151..fe2ce89 100644 --- a/fir_ser/admin/views/app.py +++ b/fir_ser/admin/views/app.py @@ -16,7 +16,8 @@ from api.base_views import app_delete from api.models import AppReleaseInfo, Apps from common.core.auth import AdminTokenAuthentication from common.core.response import ApiResponse -from common.utils.caches import del_cache_response_by_short, get_download_url_by_cache +from common.utils.caches import del_cache_response_by_short +from common.utils.download import get_download_url_by_cache from common.utils.token import verify_token logger = logging.getLogger(__name__) diff --git a/fir_ser/api/urls.py b/fir_ser/api/urls.py index 65d1918..5256eef 100644 --- a/fir_ser/api/urls.py +++ b/fir_ser/api/urls.py @@ -18,7 +18,7 @@ from django.urls import re_path from api.views.advert import UserAdInfoView from api.views.apps import AppsView, AppInfoView, AppReleaseInfoView, AppsQrcodeShowView from api.views.domain import DomainCnameView, DomainInfoView -from api.views.download import ShortDownloadView +from api.views.download import ShortDownloadView, InstallView, DownloadView from api.views.login import LoginView, UserInfoView, RegistView, AuthorizationView, ChangeAuthorizationView, \ UserApiTokenView, CertificationView, ChangeInfoView, WeChatLoginView, WeChatLoginCheckView from api.views.logout import LogoutView @@ -62,5 +62,6 @@ urlpatterns = [ re_path("^third.wx.login$", WeChatLoginView.as_view()), re_path("^third.wx.sync$", WeChatLoginCheckView.as_view()), re_path("^twx/info$", ThirdWxAccount.as_view()), - + re_path(r"^install/(?P\w+)$", InstallView.as_view(), name="install"), + re_path(r"^download/(?P\w+\.\w+)$", DownloadView.as_view(), name="download"), ] diff --git a/fir_ser/api/views/download.py b/fir_ser/api/views/download.py index 5bef819..40233b0 100644 --- a/fir_ser/api/views/download.py +++ b/fir_ser/api/views/download.py @@ -21,7 +21,8 @@ from common.core.decorators import cache_response # 本来使用的是 drf-exte 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 +from common.utils.caches import check_app_permission +from common.utils.download import get_app_download_url from common.utils.storage import Storage, get_local_storage from common.utils.token import verify_token from fir_ser import settings diff --git a/fir_ser/common/core/singals.py b/fir_ser/common/core/singals.py index 835a579..a005ad5 100644 --- a/fir_ser/common/core/singals.py +++ b/fir_ser/common/core/singals.py @@ -6,8 +6,11 @@ import logging from django.dispatch import Signal, receiver +from api.models import AppReleaseInfo from api.models import Apps -from xsign.models import AppUDID, APPToDeveloper +from common.core.sysconfig import Config +from common.libs.storage.localApi import LocalStorage +from xsign.models import AppUDID, APPToDeveloper, APPSuperSignUsedInfo from xsign.tasks import run_resign_task from xsign.utils.supersignutils import IosUtils @@ -45,3 +48,41 @@ def delete_app_callback(sender, **kwargs): if app_obj.issupersign or count > 0: logger.info(f"app_id:{app_obj.app_id} is supersign ,delete this app need clean IOS developer") IosUtils.clean_app_by_user_obj(app_obj) + + +""" +下载超级签名数据 +""" +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/common/libs/storage/localApi.py b/fir_ser/common/libs/storage/localApi.py index 8c5a38d..caaa542 100644 --- a/fir_ser/common/libs/storage/localApi.py +++ b/fir_ser/common/libs/storage/localApi.py @@ -9,6 +9,8 @@ import logging import os +from django.urls import reverse + from common.libs.storage.aliyunApi import AliYunCdn from common.utils.token import make_token from fir_ser import settings @@ -35,7 +37,7 @@ class LocalStorage(object): d_dir = 'download' if name.endswith('.mobileconifg') or is_xsign: d_dir = 'xdownload' - download_url = '/'.join([self.get_base_url(), d_dir, name]) + download_url = f'{self.get_base_url()}{reverse(d_dir, kwargs={"filename": 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 4f8d0e9..5a95932 100644 --- a/fir_ser/common/utils/caches.py +++ b/fir_ser/common/utils/caches.py @@ -5,7 +5,6 @@ # date: 2020/4/7 import logging -import os import time from django.core.cache import cache @@ -13,18 +12,15 @@ from django.db.models import F from django.utils import timezone 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 +from api.utils.modelutils import get_app_d_count_by_app_id, get_app_domain_name, get_user_domain_name +from common.base.baseutils import get_order_num from common.cache.invalid import invalid_app_cache, invalid_short_cache, invalid_app_download_times_cache, \ invalid_head_img_cache -from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCache, DownloadUrlCache, AppInstanceCache, \ +from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCache, \ UploadTmpFileNameCache, RedisCacheBase, UserCanDownloadCache, UserFreeDownloadTimesCache, WxTicketCache, \ SignUdidQueueCache, CloudStorageCache 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__) @@ -36,133 +32,10 @@ def sync_download_times_by_app_id(app_ids): logger.info(f"sync_download_times_by_app_id app_id:{app_id} count_hits:{v}") -def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', udid=None): - now = time.time() - if isdownload is None: - local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN) - download_url_type = 'plist' - if not udid: - if app_obj.get('issupersign', None): - download_url_type = 'mobileconifg' - else: - 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 = "" - - if download_url_type == 'plist': - enterprise = Config.DEFAULT_MOBILEPROVISION.get("enterprise") - mpath = enterprise.get('path', None) - murl = enterprise.get('url', None) - else: - mpath = supersign.get('path', None) - murl = supersign.get('url', None) - - if murl and len(murl) > 5: - mobileconifg = murl - - if mpath and os.path.isfile(mpath): - mobileconifg = local_storage.get_download_url(filename.split(".")[0] + "." + "dmobileprovision", limit) - - if download_url_type == 'mobileconifg' and supersign.get("self"): - mobileconifg = local_storage.get_download_url(filename.split(".")[0] + "." + "mobileprovision", limit) - - return local_storage.get_download_url(filename.split(".")[0] + "." + download_url_type, limit), mobileconifg - download_val = DownloadUrlCache(key, filename).get_storage_cache() - if download_val: - if download_val.get("time") > now - 60: - return download_val.get("download_url"), "" - else: - user_obj = UserInfo.objects.filter(pk=app_obj.get("user_id")).first() - storage = Storage(user_obj) - return storage.get_download_url(filename, limit), "" - - -def get_app_instance_by_cache(app_id, password, limit, udid): - if udid: - app_info = Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password', 'issupersign', - 'user_id__certification__status').first() - if app_info: - app_info['d_count'] = get_app_d_count_by_app_id(app_id) - app_password = app_info.get("password") - if not check_app_password(app_password, password): - return None - return app_info - app_instance_cache = AppInstanceCache(app_id) - app_obj_cache = app_instance_cache.get_storage_cache() - if not app_obj_cache: - app_obj_cache = Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password', - 'issupersign', - 'user_id__certification__status').first() - if app_obj_cache: - app_obj_cache['d_count'] = get_app_d_count_by_app_id(app_id) - app_instance_cache.set_storage_cache(app_obj_cache, limit) - if not app_obj_cache: - return None - app_password = app_obj_cache.get("password") - - if not check_app_password(app_password, password): - return None - - return app_obj_cache - - -def set_app_download_by_cache(app_id, limit=900): - app_download_cache = AppDownloadTimesCache(app_id) - download_times = app_download_cache.get_storage_cache() - if not download_times: - download_times = Apps.objects.filter(app_id=app_id).values("count_hits").first().get('count_hits') - app_download_cache.set_storage_cache(download_times + 1, limit) - else: - app_download_cache.incr() - app_download_cache.expire(limit) - set_app_today_download_times(app_id) - return download_times + 1 - - def del_cache_response_by_short(app_id, udid=''): app_obj = Apps.objects.filter(app_id=app_id).first() invalid_app_cache(app_obj) invalid_app_cache(app_obj.has_combo) - # apps_dict = Apps.objects.filter(app_id=app_id).values("id", "short", "app_id", "has_combo").first() - # if apps_dict: - # del_cache_response_by_short_util(apps_dict.get("short"), apps_dict.get("app_id"), udid) - # if apps_dict.get("has_combo"): - # combo_dict = Apps.objects.filter(pk=apps_dict.get("has_combo")).values("id", "short", "app_id").first() - # if combo_dict: - # del_cache_response_by_short_util(combo_dict.get("short"), combo_dict.get("app_id"), udid) - - -# def del_short_cache(short): -# key = "_".join([CACHE_KEY_TEMPLATE.get("download_short_key"), short, '*']) -# for app_download_key in cache.iter_keys(key): -# cache.delete(app_download_key) - - -# def del_make_token_key_cache(release_id): -# key = "_".join(['', CACHE_KEY_TEMPLATE.get("make_token_key"), f"{release_id}*"]) -# for make_token_key in cache.iter_keys(key): -# cache.delete(make_token_key) - - -# def del_cache_response_by_short_util(short, app_id, udid): -# logger.info(f"del_cache_response_by_short short:{short} app_id:{app_id} udid:{udid}") -# del_short_cache(short) -# -# cache.delete("_".join([CACHE_KEY_TEMPLATE.get("app_instance_key"), app_id])) -# -# key = 'ShortDownloadView'.lower() -# master_release_dict = AppReleaseInfo.objects.filter(app_id__app_id=app_id, is_master=True).values('icon_url', -# 'release_id').first() -# if master_release_dict: -# download_val = CACHE_KEY_TEMPLATE.get('download_url_key') -# cache.delete("_".join([key, download_val, os.path.basename(master_release_dict.get("icon_url")), udid])) -# cache.delete("_".join([key, download_val, master_release_dict.get('release_id'), udid])) -# cache.delete( -# "_".join([key, CACHE_KEY_TEMPLATE.get("make_token_key"), master_release_dict.get('release_id'), udid])) -# del_make_token_key_cache(master_release_dict.get('release_id')) def del_cache_by_delete_app(app_id): @@ -186,14 +59,6 @@ def del_cache_storage(user_obj): invalid_head_img_cache(user_obj) -def set_app_today_download_times(app_id): - cache_obj = AppDownloadTodayTimesCache(app_id) - if cache_obj.get_storage_cache(): - cache_obj.incr() - else: - cache_obj.set_storage_cache(1, 3600 * 24) - - def get_app_today_download_times(app_ids): sync_download_times_by_app_id(app_ids) download_times_count = 0 @@ -517,40 +382,3 @@ def get_and_clean_udid_cache_queue(prefix_key): data = [] cache_obj.del_storage_cache() return data - - -def get_app_download_url(request, res, app_id, short, password, release_id, isdownload, udid): - app_obj = get_app_instance_by_cache(app_id, password, 900, udid) - if app_obj: - if app_obj.get("type") == 0: - app_type = '.apk' - download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600) - else: - app_type = '.ipa' - if isdownload: - download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, udid=udid) - else: - download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, isdownload, - udid=udid) - - res.data = {"download_url": download_url, "extra_url": extra_url} - if download_url != "" and "mobileconifg" not in download_url: - ip = get_real_ip_address(request) - msg = f"remote ip {ip} short {short} download_url {download_url} app_obj {app_obj}" - logger.info(msg) - add_remote_info_from_request(request, msg) - set_app_download_by_cache(app_id) - amount = app_obj.get("d_count") - auth_status = False - status = app_obj.get('user_id__certification__status', None) - if status and status == 1: - auth_status = True - if not consume_user_download_times(app_obj.get("user_id"), app_id, amount, auth_status): - res.code = 1009 - res.msg = "可用下载额度不足" - del res.data - return res - return res - res.code = 1006 - res.msg = "该应用不存在" - return res diff --git a/fir_ser/common/utils/download.py b/fir_ser/common/utils/download.py new file mode 100644 index 0000000..c308e4e --- /dev/null +++ b/fir_ser/common/utils/download.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# project: 4月 +# author: liuyu +# date: 2020/4/7 + +import logging +import os +import time + +from api.models import Apps, UserInfo +from api.utils.modelutils import get_app_d_count_by_app_id, add_remote_info_from_request +from common.base.baseutils import check_app_password, get_real_ip_address +from common.cache.storage import AppDownloadTodayTimesCache, AppDownloadTimesCache, DownloadUrlCache, AppInstanceCache +from common.core.singals import xsign_app_download_url_signal +from common.core.sysconfig import Config +from common.utils.caches import consume_user_download_times +from common.utils.storage import Storage, LocalStorage + +logger = logging.getLogger(__name__) + + +def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='', udid=None): + now = time.time() + if isdownload is None: + local_storage = LocalStorage(**Config.IOS_PMFILE_DOWNLOAD_DOMAIN) + download_url_type = 'plist' + if not udid: + if app_obj.get('issupersign', None): + download_url_type = 'mobileconifg' + else: + 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 = "" + + if download_url_type == 'plist': + enterprise = Config.DEFAULT_MOBILEPROVISION.get("enterprise") + mpath = enterprise.get('path', None) + murl = enterprise.get('url', None) + else: + mpath = supersign.get('path', None) + murl = supersign.get('url', None) + + if murl and len(murl) > 5: + mobileconifg = murl + + if mpath and os.path.isfile(mpath): + mobileconifg = local_storage.get_download_url(filename.split(".")[0] + "." + "dmobileprovision", limit) + + if download_url_type == 'mobileconifg' and supersign.get("self"): + mobileconifg = local_storage.get_download_url(filename.split(".")[0] + "." + "mobileprovision", limit) + + return local_storage.get_download_url(filename.split(".")[0] + "." + download_url_type, limit), mobileconifg + download_val = DownloadUrlCache(key, filename).get_storage_cache() + if download_val: + if download_val.get("time") > now - 60: + return download_val.get("download_url"), "" + else: + user_obj = UserInfo.objects.filter(pk=app_obj.get("user_id")).first() + storage = Storage(user_obj) + return storage.get_download_url(filename, limit), "" + + +def get_app_instance_by_cache(app_id, password, limit, udid): + if udid: + app_info = Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password', 'issupersign', + 'user_id__certification__status').first() + if app_info: + app_info['d_count'] = get_app_d_count_by_app_id(app_id) + app_password = app_info.get("password") + if not check_app_password(app_password, password): + return None + return app_info + app_instance_cache = AppInstanceCache(app_id) + app_obj_cache = app_instance_cache.get_storage_cache() + if not app_obj_cache: + app_obj_cache = Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password', + 'issupersign', + 'user_id__certification__status').first() + if app_obj_cache: + app_obj_cache['d_count'] = get_app_d_count_by_app_id(app_id) + app_instance_cache.set_storage_cache(app_obj_cache, limit) + if not app_obj_cache: + return None + app_password = app_obj_cache.get("password") + + if not check_app_password(app_password, password): + return None + + return app_obj_cache + + +def set_app_today_download_times(app_id): + cache_obj = AppDownloadTodayTimesCache(app_id) + if cache_obj.get_storage_cache(): + cache_obj.incr() + else: + cache_obj.set_storage_cache(1, 3600 * 24) + + +def set_app_download_by_cache(app_id, limit=900): + app_download_cache = AppDownloadTimesCache(app_id) + download_times = app_download_cache.get_storage_cache() + if not download_times: + download_times = Apps.objects.filter(app_id=app_id).values("count_hits").first().get('count_hits') + app_download_cache.set_storage_cache(download_times + 1, limit) + else: + app_download_cache.incr() + app_download_cache.expire(limit) + set_app_today_download_times(app_id) + return download_times + 1 + + +def get_app_download_url(request, res, app_id, short, password, release_id, isdownload, udid): + app_obj = get_app_instance_by_cache(app_id, password, 900, udid) + if app_obj: + if app_obj.get("type") == 0: + app_type = '.apk' + download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600) + else: + app_type = '.ipa' + if isdownload: + download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, udid=udid) + else: + download_url, extra_url = get_download_url_by_cache(app_obj, release_id + app_type, 600, isdownload, + udid=udid) + + res.data = {"download_url": download_url, "extra_url": extra_url} + if download_url != "" and "mobileconifg" not in download_url: + ip = get_real_ip_address(request) + msg = f"remote ip {ip} short {short} download_url {download_url} app_obj {app_obj}" + logger.info(msg) + add_remote_info_from_request(request, msg) + set_app_download_by_cache(app_id) + amount = app_obj.get("d_count") + auth_status = False + status = app_obj.get('user_id__certification__status', None) + if status and status == 1: + auth_status = True + if not consume_user_download_times(app_obj.get("user_id"), app_id, amount, auth_status): + res.code = 1009 + res.msg = "可用下载额度不足" + del res.data + return res + return res + res.code = 1006 + res.msg = "该应用不存在" + return res diff --git a/fir_ser/fir_ser/urls.py b/fir_ser/fir_ser/urls.py index d4dab91..f7cfa05 100644 --- a/fir_ser/fir_ser/urls.py +++ b/fir_ser/fir_ser/urls.py @@ -15,27 +15,30 @@ Including another URLconf """ from django.contrib import admin from django.urls import re_path, include -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 + +# from django.views.static import serve +# from fir_ser import settings urlpatterns = [ re_path('fly.admin/', admin.site.urls), + # web api 请求地址 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"), + # client 脚本请求地址 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(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()), + + # 该配置暂时无用 + # media路径配置 如果未开启token 授权,可以启动下面配置,直接让nginx读取资源,无需 uwsgi 进行转发 + # re_path('^files/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}), + + # 任务监控 re_path(r'flower/(?P.*)', CeleryFlowerView.as_view()), + + # 超级签名 + re_path("api/v1/fir/xsign/", include('xsign.urls')), ] diff --git a/fir_ser/xsign/singals/downloadapp.py b/fir_ser/xsign/singals/downloadapp.py deleted file mode 100644 index 41d902a..0000000 --- a/fir_ser/xsign/singals/downloadapp.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/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/urls.py b/fir_ser/xsign/urls.py index 9d36188..92e4760 100644 --- a/fir_ser/xsign/urls.py +++ b/fir_ser/xsign/urls.py @@ -16,13 +16,12 @@ Including another URLconf from django.urls import re_path from xsign.views.appinfo import AppCanSignView, AppSignInfoView -from xsign.views.receiveudids import IosUDIDView, TaskView +from xsign.views.download import XsignDownloadView +from xsign.views.receiveudids import IosUDIDView, TaskView, ShowUdidView from xsign.views.supersign import DeveloperView, SuperSignUsedView, AppUDIDUsedView, SuperSignCertView, \ DeviceUsedBillView, DeveloperDeviceView, DeviceUsedRankInfoView, AppleDeveloperBindAppsView, DeviceTransferBillView urlpatterns = [ - re_path(r"^udid/(?P\w+)$", IosUDIDView.as_view()), - re_path(r"^task/(?P\w+)$", TaskView.as_view()), re_path(r"^developer$", DeveloperView.as_view()), re_path(r"^devices$", SuperSignUsedView.as_view()), re_path(r"^udid$", AppUDIDUsedView.as_view()), @@ -32,6 +31,20 @@ urlpatterns = [ re_path(r"^devicebill$", DeviceTransferBillView.as_view()), re_path(r"^rank$", DeviceUsedRankInfoView.as_view()), re_path(r"^bind$", AppleDeveloperBindAppsView.as_view()), + + # app 应用相关 re_path(r"^cansign$", AppCanSignView.as_view()), re_path(r"^signinfo/(?P\w+)$", AppSignInfoView.as_view()), + + # 获取苹果设备udid + re_path("^show_udid$", ShowUdidView.as_view()), + + # ipa应用接收udid + re_path(r"^udid/(?P\w+)$", IosUDIDView.as_view(), name="xudid"), + + # 检测签名任务状态 + re_path(r"^task/(?P\w+)$", TaskView.as_view()), + + # ipa应用签名下载 + re_path(r"^xdownload/(?P\w+\.\w+)$", XsignDownloadView.as_view(), name="xdownload"), ] diff --git a/fir_ser/xsign/views/download.py b/fir_ser/xsign/views/download.py index 30a7797..3001ded 100644 --- a/fir_ser/xsign/views/download.py +++ b/fir_ser/xsign/views/download.py @@ -7,6 +7,7 @@ import logging import os +from django.urls import reverse from rest_framework.views import APIView from api.models import AppReleaseInfo @@ -24,8 +25,7 @@ logger = logging.getLogger(__name__) def get_post_udid_url(request, short): server_domain = get_server_domain_from_request(request, Config.POST_UDID_DOMAIN) - path_info_lists = [server_domain, "udid", short] - return "/".join(path_info_lists) + return f'{server_domain}{reverse("xudid", kwargs={"short": short})}' class XsignDownloadView(APIView): diff --git a/fir_ser/xsign/views/supersign.py b/fir_ser/xsign/views/supersign.py index 8cbaa72..358854a 100644 --- a/fir_ser/xsign/views/supersign.py +++ b/fir_ser/xsign/views/supersign.py @@ -19,7 +19,7 @@ from common.base.baseutils import get_choices_dict, get_choices_name_from_key, A from common.cache.state import CleanSignDataState, MigrateStorageState from common.core.auth import ExpiringTokenAuthentication, SuperSignPermission from common.core.sysconfig import Config -from common.utils.caches import get_app_download_url +from common.utils.download import get_app_download_url from xsign.models import AppIOSDeveloperInfo, APPSuperSignUsedInfo, AppUDID, IosDeveloperPublicPoolBill, \ UDIDsyncDeveloper, AppleDeveloperToAppUse, DeveloperAppID, APPToDeveloper, DeveloperDevicesID, \ IosDeveloperBill