优化描述文件签名逻辑,修复清理临时文件bug

dependabot/npm_and_yarn/fir_admin/tmpl-1.0.5
youngS 3 years ago
parent 1dc6e84ba7
commit e8931df00f
  1. 43
      fir_ser/api/utils/app/iossignapi.py
  2. 34
      fir_ser/api/utils/app/supersignutils.py
  3. 2
      fir_ser/api/utils/crontab/ctasks.py
  4. 5
      fir_ser/api/views/download.py
  5. 27
      fir_ser/api/views/receiveudids.py
  6. 3
      fir_ser/fir_ser/urls.py

@ -9,6 +9,7 @@ from api.utils.app.shellcmds import shell_command, use_user_pass
from api.utils.baseutils import get_format_time, format_apple_date from api.utils.baseutils import get_format_time, format_apple_date
from fir_ser.settings import SUPER_SIGN_ROOT from fir_ser.settings import SUPER_SIGN_ROOT
import os import os
import re
from api.utils.app.randomstrings import make_app_uuid from api.utils.app.randomstrings import make_app_uuid
import logging import logging
from api.utils.apple.appleapiv3 import AppStoreConnectApi from api.utils.apple.appleapiv3 import AppStoreConnectApi
@ -49,18 +50,46 @@ class ResignApp(object):
self.cmd = "zsign -c '%s' -k '%s' " % (self.app_dev_pem, self.my_local_key) self.cmd = "zsign -c '%s' -k '%s' " % (self.app_dev_pem, self.my_local_key)
@staticmethod @staticmethod
def sign_mobile_config(mobile_config_path, sign_mobile_config_path, ssl_pem_path, ssl_key_path): def sign_mobile_config(sign_data, ssl_pem_path, ssl_key_path):
""" """
:param mobile_config_path: 描述文件绝对路径 :param sign_data: 签名的数据
:param sign_mobile_config_path: 签名之后的文件绝对路径
:param ssl_pem_path: pem证书的绝对路径 :param ssl_pem_path: pem证书的绝对路径
:param ssl_key_path: key证书的绝对路径 :param ssl_key_path: key证书的绝对路径
:return: :return:
""" """
cmd = "openssl smime -sign -in %s -out %s -signer %s " \ #
"-inkey %s -certfile %s -outform der -nodetach " % ( # cmd = "openssl smime -sign -in %s -out %s -signer %s " \
mobile_config_path, sign_mobile_config_path, ssl_pem_path, ssl_key_path, ssl_pem_path) # "-inkey %s -certfile %s -outform der -nodetach " % (
return exec_shell(cmd) # mobile_config_path, sign_mobile_config_path, ssl_pem_path, ssl_key_path, ssl_pem_path)
# return exec_shell(cmd)
result = {}
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.serialization import pkcs7
from cryptography import x509
try:
cert_list = re.findall('-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----',
open(ssl_pem_path, 'r').read(), re.S)
if len(cert_list) == 0:
raise Exception('load cert failed')
else:
cert = x509.load_pem_x509_certificate(cert_list[0].encode('utf-8'))
cas = [cert]
if len(cert_list) > 1:
cas.extend([x509.load_pem_x509_certificate(x.encode('utf-8')) for x in cert_list[1:]])
key = serialization.load_pem_private_key(open(ssl_key_path, 'rb').read(), None)
result['data'] = pkcs7.PKCS7SignatureBuilder(
data=sign_data,
signers=[
(cert, key, hashes.SHA512()),
],
additional_certs=cas,
).sign(
serialization.Encoding.DER, options=[],
)
except Exception as e:
result['err_info'] = str(e)
return False, result
return True, result
def make_p12_from_cert(self, password): def make_p12_from_cert(self, password):
result = {} result = {}

@ -81,7 +81,7 @@ def udid_bytes_to_dict(xml_stream):
return new_uuid_info return new_uuid_info
def make_sign_udid_mobile_config(udid_url, payload_organization, app_name): def make_sign_udid_mobile_config(udid_url, app_id, bundle_id, app_name):
if MOBILECONFIG_SIGN_SSL.get("open"): if MOBILECONFIG_SIGN_SSL.get("open"):
ssl_key_path = MOBILECONFIG_SIGN_SSL.get("ssl_key_path", None) ssl_key_path = MOBILECONFIG_SIGN_SSL.get("ssl_key_path", None)
ssl_pem_path = MOBILECONFIG_SIGN_SSL.get("ssl_pem_path", None) ssl_pem_path = MOBILECONFIG_SIGN_SSL.get("ssl_pem_path", None)
@ -91,30 +91,31 @@ def make_sign_udid_mobile_config(udid_url, payload_organization, app_name):
if not os.path.exists(mobile_config_tmp_dir): if not os.path.exists(mobile_config_tmp_dir):
os.makedirs(mobile_config_tmp_dir) os.makedirs(mobile_config_tmp_dir)
mobile_config_filename = payload_organization + str(uuid.uuid1()) sign_mobile_config_path = os.path.join(mobile_config_tmp_dir, 'sign_' + app_id)
mobile_config_path = os.path.join(mobile_config_tmp_dir, mobile_config_filename) logger.info(f"make sing mobile config {sign_mobile_config_path}")
if os.path.isfile(sign_mobile_config_path):
return open(sign_mobile_config_path, 'rb')
sign_mobile_config_path = os.path.join(mobile_config_tmp_dir, 'sign_' + mobile_config_filename) status, result = ResignApp.sign_mobile_config(
with open(mobile_config_path, "w") as f: make_udid_mobile_config(udid_url, bundle_id, app_name),
f.write(make_udid_mobile_config(udid_url, payload_organization, app_name)) ssl_pem_path,
status, result = ResignApp.sign_mobile_config(mobile_config_path, sign_mobile_config_path, ssl_pem_path,
ssl_key_path) ssl_key_path)
if status:
mobile_config_body = open(sign_mobile_config_path, 'rb') if status and result.get('data'):
with open(sign_mobile_config_path, 'wb') as f:
f.write(result.get('data'))
return open(sign_mobile_config_path, 'rb')
else: else:
logger.error( logger.error(
f"{payload_organization} {app_name} sign_mobile_config failed ERROR:{result.get('err_info')}") f"{bundle_id} {app_name} sign_mobile_config failed ERROR:{result.get('err_info')}")
return make_udid_mobile_config(udid_url, payload_organization, app_name) return make_udid_mobile_config(udid_url, bundle_id, app_name)
return mobile_config_body
else: else:
logger.error(f"sign_mobile_config {ssl_key_path} or {ssl_pem_path} is not exists") logger.error(f"sign_mobile_config {ssl_key_path} or {ssl_pem_path} is not exists")
return make_udid_mobile_config(udid_url, payload_organization, app_name) return make_udid_mobile_config(udid_url, bundle_id, app_name)
else: else:
return make_udid_mobile_config(udid_url, payload_organization, app_name) return make_udid_mobile_config(udid_url, bundle_id, app_name)
def make_udid_mobile_config(udid_url, payload_organization, app_name, payload_uuid=uuid.uuid1(), def make_udid_mobile_config(udid_url, payload_organization, app_name, payload_uuid=uuid.uuid1(),
@ -627,7 +628,6 @@ class IosUtils(object):
""" """
该APP为超级签删除app的时候需要清理一下开发者账户里面的profile bundleid 该APP为超级签删除app的时候需要清理一下开发者账户里面的profile bundleid
:param app_obj: :param app_obj:
:param user_obj:
:return: :return:
""" """

@ -49,7 +49,7 @@ def auto_clean_upload_tmp_file():
def auto_delete_ios_mobile_tmp_file(): def auto_delete_ios_mobile_tmp_file():
mobile_config_tmp_dir = os.path.join(SUPER_SIGN_ROOT, 'tmp', 'mobileconfig') mobile_config_tmp_dir = os.path.join(SUPER_SIGN_ROOT, 'tmp', 'mobile_config')
for root, dirs, files in os.walk(mobile_config_tmp_dir, topdown=False): for root, dirs, files in os.walk(mobile_config_tmp_dir, topdown=False):
now_time = time.time() now_time = time.time()
for name in files: for name in files:

@ -72,9 +72,10 @@ class DownloadView(APIView):
elif f_type == 'mobileconifg': elif f_type == 'mobileconifg':
release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first() release_obj = AppReleaseInfo.objects.filter(release_id=filename.split('.')[0]).first()
if release_obj: if release_obj:
bundle_id = release_obj.app_id.bundle_id
udid_url = get_post_udid_url(request, release_obj.app_id.short) udid_url = get_post_udid_url(request, release_obj.app_id.short)
ios_udid_mobile_config = make_sign_udid_mobile_config(udid_url, bundle_id, release_obj.app_id.name) app_obj = release_obj.app_id
ios_udid_mobile_config = make_sign_udid_mobile_config(udid_url, app_obj.app_id, app_obj.bundle_id,
app_obj.app_name)
response = FileResponse(ios_udid_mobile_config) response = FileResponse(ios_udid_mobile_config)
response['Content-Type'] = "application/x-apple-aspen-config" response['Content-Type'] = "application/x-apple-aspen-config"
response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() + '.mobileconfig' response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() + '.mobileconfig'

@ -3,11 +3,12 @@
# project: 3月 # project: 3月
# author: liuyu # author: liuyu
# date: 2020/3/6 # date: 2020/3/6
from api.utils.app.randomstrings import make_random_uuid
from api.utils.app.supersignutils import udid_bytes_to_dict, get_redirect_server_domain from api.utils.app.supersignutils import udid_bytes_to_dict, get_redirect_server_domain, make_sign_udid_mobile_config, \
get_post_udid_url, get_http_server_domain
from api.models import Apps from api.models import Apps
from django.views import View from django.views import View
from django.http import HttpResponsePermanentRedirect from django.http import HttpResponsePermanentRedirect, FileResponse
from rest_framework.response import Response from rest_framework.response import Response
from api.tasks import run_sign_task from api.tasks import run_sign_task
from api.utils.response import BaseResponse from api.utils.response import BaseResponse
@ -89,3 +90,23 @@ class TaskView(APIView):
return Response(res.dict) return Response(res.dict)
res.code = 1002 res.code = 1002
return Response(res.dict) return Response(res.dict)
class ShowUdidView(View):
def get(self, request):
server_domain = get_http_server_domain(request)
path_info_lists = [server_domain, "look_udid"]
udid_url = "/".join(path_info_lists)
ios_udid_mobile_config = make_sign_udid_mobile_config(udid_url, 'show_udid_info', 'flyapps.cn', '查询设备udid')
response = FileResponse(ios_udid_mobile_config)
response['Content-Type'] = "application/x-apple-aspen-config"
response['Content-Disposition'] = 'attachment; filename=' + make_random_uuid() + '.mobileconfig'
return response
def post(self, request):
stream_f = str(request.body)
format_udid_info = udid_bytes_to_dict(stream_f)
logger.info(f"look_udid receive new udid {format_udid_info}")
server_domain = get_redirect_server_domain(request)
return HttpResponsePermanentRedirect(
"%sudid=%s" % (server_domain, format_udid_info.get("udid")))

@ -18,7 +18,7 @@ from django.urls import re_path, include
from django.views.static import serve from django.views.static import serve
from fir_ser import settings from fir_ser import settings
from api.views.download import DownloadView, InstallView from api.views.download import DownloadView, InstallView
from api.views.receiveudids import IosUDIDView from api.views.receiveudids import IosUDIDView, ShowUdidView
urlpatterns = [ urlpatterns = [
re_path('fly.admin/', admin.site.urls), re_path('fly.admin/', admin.site.urls),
@ -31,5 +31,6 @@ urlpatterns = [
re_path("download/(?P<filename>\w+\.\w+)$", DownloadView.as_view(), name="download"), re_path("download/(?P<filename>\w+\.\w+)$", DownloadView.as_view(), name="download"),
re_path("install/(?P<app_id>\w+)$", InstallView.as_view(), name="install"), re_path("install/(?P<app_id>\w+)$", InstallView.as_view(), name="install"),
re_path("^udid/(?P<short>\w+)$", IosUDIDView.as_view()), re_path("^udid/(?P<short>\w+)$", IosUDIDView.as_view()),
re_path("^look_udid$", ShowUdidView.as_view()),
] ]

Loading…
Cancel
Save