大家都知道iOS的企业证书开发的APP,证书都是一年有效期,满一年得新建证书重新打包,否则无法继续使用。

我们一个企业账号下有几十个APP,一个个去看也很麻烦~~搞个监控呗!!!

写个脚本放Jenkins上定时跑就行,跑完发布邮件:

1.邮件包含信息:APP名称,APP相关的bundle id、证书名称、签名时间、团队id,过期时间,以及剩余有效的月数。

common_mail.py: 发布邮件,邮件发送网上多,自己找,不累述

copy_ipa_monitor.py: 把打好的ipa复制到指定的目录,这个目录给监控的扫描用

date_month.py: 专门计算月份差,Python没有直接计算月份差的模块,自己写,考虑下各种条件计算

ipa_monitor.py: 获取ipa的有效时间以及ipa包里描述文件里的有效时间

ipa_monitor_html.py: 生成邮件发送的html模版

贴代码:

  1 ## ipa_monitor.py
2 # coding = utf-8
3 # 读取配置证书
4
5 import os
6 import time
7 import shutil
8 import datetime
9 from pkg_common.cmd import common_run_cmd as cmd
10 from pkg_common.handle_file import find_file as find
11 from pkg_common.ipa_monitor import common_mail as mail
12 from pkg_common.ipa_monitor import ipa_monitor_html as html
13
14
15 to_find_path = '/Users/Work/package/ipa_monitor'
16
17
18 # 获取证书时间一些命令
19 codesign_cmd = 'codesign -d --extract-certificates Payload/*.app'
20 openssl_cmd = 'openssl x509 -inform DER -in codesign0 -noout -nameopt -oneline -dates'
21 codesign_get_cmd = 'codesign -dv --verbose=4 Payload/*.app'
22 mobile_provision_cmd = 'more Payload/Runner.app/embedded.mobileprovision'
23
24
25 def get_ipa_time():
26 f, f_l = find.find_file("'*.ipa'", to_find_path)
27 all_dic = []
28 for i in f_l:
29 dic = {}
30 dir_name = os.path.dirname(i)
31 app_name = dir_name.split('/')[-1]
32 dic['app_name'] = app_name
33 base_name = os.path.basename(i)
34 un_zip_cmd = 'unzip -q %s' % base_name
35 # 解压ipa文件
36 cmd.run_cmd(un_zip_cmd, dir_name)
37 time.sleep(2)
38 cmd.run_commands(codesign_cmd, dir_name)
39 time.sleep(2)
40 not_time = cmd.run_commands(openssl_cmd, dir_name)[1]
41 not_after, not_stamp = deal_gmt(not_time.split('\n')[1].split('=')[1])
42 f, f_l = find.find_file("'*.mobileprovision'", dir_name)
43 ipa_no_time = ''
44 ipa_no_stamp = 0
45 # 获取描述文件里的过期时间,这里解码格式一定要用ISO-8859-1
46 with open(f_l[0], 'r', encoding='ISO-8859-1') as f_w:
47 lines = f_w.readlines()
48 for index, l in enumerate(lines):
49 if 'ExpirationDate' in l:
50 ipa_no_time = lines[index+1].split('>')[1].split('<')[0]
51 ipa_no_time, ipa_no_stamp = deal_utc(ipa_no_time)
52 break
53 if not_stamp <= ipa_no_stamp:
54 expired_time = not_after
55 else:
56 expired_time = ipa_no_time
57 dic['expired_time'] = expired_time
58 pro_info = cmd.run_commands(codesign_get_cmd, dir_name)[1].split('\n')
59 delete_file(dir_name)
60
61 for x in pro_info:
62 if 'Identifier' == x.split('=')[0]:
63 dic['Identifier'] = x.split('=')[1]
64 if 'Authority' in x:
65 if 'Authority' not in dic:
66 dic['Authority'] = x.split('=')[1]
67 if 'Signed Time' in x:
68 dic['Signed_time'] = x.split('=')[1]
69 if 'TeamIdentifier' in x:
70 dic['TeamIdentifier'] = x.split('=')[1]
71 all_dic.append(dic)
72 return all_dic
73
74
75 def deal_gmt(gmt_time):
76 """
77 GMT时间转换
78 :param gmt_time:
79 :return:
80 """
81 gmt_format = '%b %d %H:%M:%S %Y GMT'
82 # GMT时间与北京时间相差8小时
83 sta_time = datetime.datetime.strptime(gmt_time, gmt_format) + datetime.timedelta(hours=8)
84 time_array = time.strptime(str(sta_time), "%Y-%m-%d %H:%M:%S")
85 time_stamp = int(time.mktime(time_array))
86 return sta_time, time_stamp
87
88
89 def deal_utc(utc_time):
90 utc_format = "%Y-%m-%dT%H:%M:%SZ"
91 sta_time = datetime.datetime.strptime(utc_time, utc_format) + datetime.timedelta(hours=8)
92 time_array = time.strptime(str(sta_time), "%Y-%m-%d %H:%M:%S")
93 time_stamp = int(time.mktime(time_array))
94 return sta_time, time_stamp
95
96
97 def delete_file(dir_name):
98 """
99 删除多余文件
100 :param dir_name:
101 :return:
102 """
103 os.remove(dir_name + '/codesign0')
104 os.remove(dir_name + '/codesign1')
105 os.remove(dir_name + '/codesign2')
106 shutil.rmtree(dir_name + '/Payload')
107
108
109 if __name__ == '__main__':
110 ipa_info = get_ipa_time()
111 subject, html = html.deal_html(ipa_info)
112 try:
113 if mail.cs_mail_send(subject, html, 'c'):
114 print('Send success')
115 else:
116 print('Send failure')
117 except Exception as e:
118 raise e
119
## date_month.py

import datetime
import calendar as c def cal_months(start_date, end_date): # 计算两个日期相隔月差
try:
same_month_date = datetime.date(end_date.year, end_date.month, start_date.day)
except Exception as e:
print(e)
same_month_date = datetime.date(end_date.year, end_date.month, c.monthrange(end_date.year, end_date.month)[1])
decimal_month = 0.0
if same_month_date > end_date:
try:
pre_date = datetime.date(end_date.year, end_date.month - 1, start_date.day)
except Exception as e:
print(e)
pre_date = datetime.date(end_date.year, end_date.month - 1, c.monthrange(end_date.year, end_date.month - 1)[1])
curr_month_days = (same_month_date - pre_date).days
hold_months = (pre_date.year - start_date.year) * 12 + pre_date.month - start_date.month
decimal_month = round((end_date - pre_date).days / curr_month_days, 1) elif same_month_date < end_date:
try:
next_month_date = datetime.date(end_date.year, end_date.month + 1, start_date.day)
except Exception as e:
print(e)
next_month_date = datetime.date(end_date.year, end_date.month + 1, c.monthrange(end_date.year, end_date.month + 1)[1])
curr_month_days = (next_month_date - same_month_date).days
hold_months = (same_month_date.year - start_date.year) * 12 + same_month_date.month - start_date.month
decimal_month = round((end_date - same_month_date).days / curr_month_days, 1) else:
hold_months = (end_date.year - start_date.year) * 12 + end_date.month - start_date.month return hold_months + decimal_month
## ipa_monitor_html.py
# coding = utf-8
# ipa过期时间监控 import datetime
from pkg_common.ipa_monitor import date_month as dm # 处理html
def deal_html(data):
tl = deal_tl(data)
subject = '企业证书iOS应用过期时间监控'
html = """
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>企业证书iOS应用过期时间监控</title>
<body>
<div id="container">
<center>
<strong>汇总时间: """ + str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + """</strong>
<p><strong></strong></p>
<div id="content">
<table border="1" cellpadding="2" style="border-collapse:collapse;margin-top:10px">
<tr>
<td colspan="4" align="center" height="35px"><font size="4"><strong>只针对企业证书打包的应用</strong>[<font color="red">有效期小于3月的红色加粗显示</font>]</font></td>
</tr>
<tr height="28px" bgcolor="#f0f8ff">
<td width="120" align="center"><font size="3"><strong>应用名称</strong></font></td>
<td width="520" align="center"><font size="3"><strong>APP参数</strong></font></td>
<td width="180" align="center"><font size="3"><strong>过期时间</strong></font></td>
<td width="80" align="center"><font size="3"><strong>剩余月数</strong></font></td>
</tr>
""" + tl + """
</tr>
</table>
<p><font size="3" ><center>--------------------<strong><a href="http://chandao.thecover.cn/">汇总数据源于测试监控系统</a></strong>--------------------</center></font>
</center>
</div>
</div>
</div>
</body>
</html>
"""
return subject, html def deal_tl(data): tl_a = ''
for i in data: dt1 = i['expired_time'].date()
dt2 = datetime.date.today()
dt = dm.cal_months(dt2, dt1) a = """
<tr>
<td rowspan="4" align="center"> %s </td>
<td align="left"> Identifier:%s</td>
<td rowspan="4" align="center"> %s</td>
""" % (i['app_name'], i['Identifier'], i['expired_time']) if dt > 3:
b = """ <td rowspan="4" align="center"> %s</td> """ % dt
else:
b = """ <td rowspan="4" align="center"> <strong><font color="red"> %s </font></strong></td> """ % dt c = """
</tr>
<tr>
<td align="left"> Authority:%s</td>
</tr>
<tr>
<td align="left"> Signed_time:%s </td>
</tr>
<tr>
<td align="left"> TeamIdentifier:%s </td>
</tr>
<tr>
<td colspan="4" align="center" height="0px" bgcolor="#a9a9a9"><font size="4"> </td>
</tr>
""" % (i['Authority'], i['Signed_time'], i['TeamIdentifier']) tl_a = tl_a + a + b + c return tl_a

其他py文件很简单,就不贴了,若遇到问题,可留言交流~~

iOS企业证书开发的APP证书过期时间监控的更多相关文章

  1. 安卓和ios的app证书过期的相关问题汇总

    一,ios的APP的发布流程请见:ios的APP的发布流程 http://www.jianshu.com/p/b1b77d804254 这篇文章写得很好很全面 二,app证书过期了怎么办: IOS的情 ...

  2. XE6 & IOS开发之免证书真机调试(1):颁发属于自己的App签名证书(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 1.自己给自己颁发证书, ...

  3. IOS开发创建开发证书及发布App应用(二)——创建证书

    2. 创建证书 证书分为两种,一种是开发者证书,主要是用来真机调试的 另一种就是发布证书,就是用来发布应用的, 最好是两种都要下载,不然编译时候可能报错,我猜想可能苹果怕你没用真机调试 创建证书分为两 ...

  4. IOS开发创建开发证书及发布App应用(一)——流程说明

    之前在自己做的博客网站上面发布了这个系列的文章,当时还是不错的,帮助了很多跟我一样的新手朋友,不过由于服务器出现问题,丢失了一年了,现在终于找到了,所以发到博客园给大家共享一下,也是为我自己做个参考 ...

  5. 【iOS开发】企业版证书($299)In-House方式发布指南 (转)

    一.明确几个概念 1.企业版IDP:即iOS Development Enterprise Program.注意是$299/Year那种,并不是$99/Year的那种. 2.In House:是只企业 ...

  6. 关于iOS开发的各种证书

    关于iOS开发的各种证书 最近在接推送服务的时候,被各种证书弄得不亦晕乎,这里记录一下一些基本的证书作用: 1. App IDs appID分明确的和通配的两种,如果要使用推送功能,只能用明确的. 2 ...

  7. iOS开发-- 开发环境,证书和授权文件

    一.成员介绍 1.    Certification(证书)证书是对电脑开发资格的认证,每个开发者帐号有一套,分为两种:1)    Developer Certification(开发证书)安装在电脑 ...

  8. IOS 开发环境,证书和授权文件等详解

    (转自:http://blog.csdn.net/gtncwy/article/details/8617788) 一.成员介绍1.    Certification(证书)证书是对电脑开发资格的认证, ...

  9. ios 企业证书 ipa 重新签名发布

    提示:暂时不能用了,企业证书滥用 ios 企业证书 ipa 重新签名发布 1. 应用场景 当前有一个 未用企业证书签名的 ipa 文件,默认是不可以直接安装到设备上的:我们需要用企业版证书签名: 当前 ...

  10. iOS开发HTTPS实现之信任SSL证书和自签名证书

    iOS开发HTTPS实现之信任SSL证书和自签名证书 转自:http://www.jianshu.com/p/6b9c8bd5005a/comments/5539345 (收录一下供自己学习用的) 字 ...

随机推荐

  1. php本地上传文件类

    /** * Class UploadFile * @author fengzi */ class UploadFile { public $error = array(); //上传前的error信息 ...

  2. AT_abc342_d 题解

    UD 2024/2/24 22:36 感谢 Lixiang_is_potato 指出一处笔误. 本文同步发表于洛谷. 赛时挂了,但是赛后 3min AC,我是飞舞. 题意 给你一个长度为 \(N\) ...

  3. 删除无用的docker镜像与容器

    docker rm `docker ps -a | grep Exited | awk '{print $1}'` 删除异常停止的docker容器 docker rmi -f `docker imag ...

  4. 使用Servlet进行页面跳转的两种方式

    最近在教学生学习JavaWeb相关的技术,刚好讲到Java当中的Servlet,一个服务端的小程序. 也在和学生讲使用Servlet如何进行页面跳转,一种方式是使用请求转发进行页面跳转,一种方式 是使 ...

  5. manjaro/archLinux出现什么的签名未知信任的时候

    sudo pacman -S archlinuxcn-keyring 在进行该做的就可以了 出现这种状况的原因是没有规范的更新系统!

  6. python librosa 实例解析

    一 概念 librosa是一个用于音乐和音频分析的python包.它提供了创建音乐信息检索系统所需的构建块. 核心函数:   二 实例解析   实例A,确认是否安装成功: import librosa ...

  7. mybatis之Mapped Statements collection does not contain value for...错误原因分析

    错误原因有几种:  1.mapper.xml中没有加入namespace:  2.mapper.xml中的方法和接口mapper的方法不对应:  3.mapper.xml没有加入到mybatis-co ...

  8. 云流化:XR扩展现实应用发展道路上的新方向

    扩展现实的发展已经改变了我们工作.生活和娱乐的方式,而且这才刚刚开始.扩展现实 (Extended reality, XR) 涵盖了沉浸式技术,包括虚拟现实.增强现实和混合现实.从游戏到虚拟制作再到产 ...

  9. 3D渲染速度慢,花重金买显卡还是用云渲染更划算

    3D渲染对建筑师和设计师来说并不陌生,3D渲染的过程中出现渲染卡顿.特殊材质难以渲染,或者本地配置不足.本地渲染资源不够时,常常会影响工作效率.本文比较了3D渲染时,为提高工作效率,买显卡还是用云渲染 ...

  10. 三维模型3DTile格式轻量化压缩模型变形浅析

    三维模型3DTile格式轻量化压缩模型变形浅析 在对三维模型进行轻量化压缩处理的过程中,常常会出现模型变形的现象.这种变形现象多数源于模型压缩过程中信息丢失或误差累积等因素.以下将对此现象进行详细分析 ...