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文件很簡單,就不貼了,若遇到問題,可留言交流~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM