iOS企业证书开发的APP证书过期时间监控
大家都知道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证书过期时间监控的更多相关文章
- 安卓和ios的app证书过期的相关问题汇总
一,ios的APP的发布流程请见:ios的APP的发布流程 http://www.jianshu.com/p/b1b77d804254 这篇文章写得很好很全面 二,app证书过期了怎么办: IOS的情 ...
- XE6 & IOS开发之免证书真机调试(1):颁发属于自己的App签名证书(有图有真相)
网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 1.自己给自己颁发证书, ...
- IOS开发创建开发证书及发布App应用(二)——创建证书
2. 创建证书 证书分为两种,一种是开发者证书,主要是用来真机调试的 另一种就是发布证书,就是用来发布应用的, 最好是两种都要下载,不然编译时候可能报错,我猜想可能苹果怕你没用真机调试 创建证书分为两 ...
- IOS开发创建开发证书及发布App应用(一)——流程说明
之前在自己做的博客网站上面发布了这个系列的文章,当时还是不错的,帮助了很多跟我一样的新手朋友,不过由于服务器出现问题,丢失了一年了,现在终于找到了,所以发到博客园给大家共享一下,也是为我自己做个参考 ...
- 【iOS开发】企业版证书($299)In-House方式发布指南 (转)
一.明确几个概念 1.企业版IDP:即iOS Development Enterprise Program.注意是$299/Year那种,并不是$99/Year的那种. 2.In House:是只企业 ...
- 关于iOS开发的各种证书
关于iOS开发的各种证书 最近在接推送服务的时候,被各种证书弄得不亦晕乎,这里记录一下一些基本的证书作用: 1. App IDs appID分明确的和通配的两种,如果要使用推送功能,只能用明确的. 2 ...
- iOS开发-- 开发环境,证书和授权文件
一.成员介绍 1. Certification(证书)证书是对电脑开发资格的认证,每个开发者帐号有一套,分为两种:1) Developer Certification(开发证书)安装在电脑 ...
- IOS 开发环境,证书和授权文件等详解
(转自:http://blog.csdn.net/gtncwy/article/details/8617788) 一.成员介绍1. Certification(证书)证书是对电脑开发资格的认证, ...
- ios 企业证书 ipa 重新签名发布
提示:暂时不能用了,企业证书滥用 ios 企业证书 ipa 重新签名发布 1. 应用场景 当前有一个 未用企业证书签名的 ipa 文件,默认是不可以直接安装到设备上的:我们需要用企业版证书签名: 当前 ...
- iOS开发HTTPS实现之信任SSL证书和自签名证书
iOS开发HTTPS实现之信任SSL证书和自签名证书 转自:http://www.jianshu.com/p/6b9c8bd5005a/comments/5539345 (收录一下供自己学习用的) 字 ...
随机推荐
- 【主流技术】日常工作中关于 JSON 转换的经验大全(Java)
目录 前言 一.JSON 回顾 1.1结构形式 二.其它类型 -> JSON相关 2.1 JavaBean 转 JsonObject 2.2 JavaBean 转 Json 字符串 2.3 Li ...
- xxl-job的基本使用
xxl-job的基本使用 xxl-job是分布式的调度平台调度执行器执行任务,使用的是DB锁(for update)来保证集群分布式调用的一致性,学习简单,操作容易,成本不高. 准备阶段 服务端配置 ...
- 巧用SQL语句中的OR查询完成业务新需求-2022新项目
一.业务场景 目前参与开发的项目,之前的一个已上线的版本中有一类查询是根据两张表进行LEFT JOIN查询用来取数据, 主表中有一个字段field用来区分不同的数据类型比如说A/B/C.前面的版本中只 ...
- redis同步锁的真实应用场景
一.问题由来 现在正在做的小程序后台中,有一个功能叫做高光时刻,在操作高光时刻的时候,可能会有多个用户来同时想操作这个功能,可是在同一时间只能 有一个用户能够操作.刚开始做的时候,自己的做法是在red ...
- 痞子衡嵌入式:使用恩智浦GUI Guider快速创建全新LCD屏示例工程的步骤
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是使用恩智浦GUI Guider快速创建全新LCD屏示例工程的步骤. 在痞子衡旧文 <在i.MXRT1170上快速点亮一款全新LCD ...
- 关于debian安装完后输入法的问题
sudo apt install ibus-libpinyin后 重启计算机
- 逆向通达信Level-2 续七 (调试内置WebView)
通过窗口找WebView,打开DevTool调试 在WebView hack入控制台.那个,我已经打开了DevTool,算了. 通过pad面板找WebView. 逆向通达信Level-2 续十一 (无 ...
- Linux Char-Driver (字符驱动 摘要)(一)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 记录--两行CSS让页面提升了近7倍渲染性能
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 对于前端人员来讲,最令人头疼的应该就是页面性能了,当用户在访问一个页面时,总是希望它能够快速呈现在眼前并且是可交互状态.如果页面加载 ...
- 2022北航软件研究生入学考试991考试大纲-数据结构与C
991"数据结构与C语言程序设计"考试大纲 "数据结构与C语言程序设计"考试内容包括"数据结构"与"C语言程序设计"两门 ...