Add unit tests for PDF Packager converter functionality

- Implement tests for converter properties, ensuring correct input and output formats.
- Add tests for chip parsing, covering various image, pdf_image, and pdfa chip formats.
- Include tests for the isArchiveOutput and getOutputFileName functions.
- Mock execFile for testing the convert function, verifying command execution and output file creation.
- Ensure all chips are parseable and validate the completeness of chip categories.
This commit is contained in:
Your Name 2026-01-24 14:39:22 +08:00
parent 87bd318303
commit 944fe18b75
11 changed files with 2233 additions and 8 deletions

129
scripts/pdf_sign.py Normal file
View file

@ -0,0 +1,129 @@
#!/usr/bin/env python3
"""
PDF 數位簽章腳本
使用 endesive 庫對 PDF 進行數位簽章
環境變數
- PDF_SIGN_P12_PATH: PKCS12 憑證檔案路徑必須
- PDF_SIGN_P12_PASSWORD: PKCS12 憑證密碼選用預設為空
- PDF_SIGN_REASON: 簽章原因選用
- PDF_SIGN_LOCATION: 簽章地點選用
- PDF_SIGN_CONTACT: 聯絡資訊選用
用法
python3 pdf_sign.py <input.pdf> <output.pdf>
錯誤代碼
0: 成功
1: 參數錯誤
2: 憑證未配置
3: 憑證讀取失敗
4: 簽章失敗
"""
import os
import sys
from datetime import datetime
def main():
# 檢查參數
if len(sys.argv) != 3:
print("用法: python3 pdf_sign.py <input.pdf> <output.pdf>", file=sys.stderr)
sys.exit(1)
input_pdf = sys.argv[1]
output_pdf = sys.argv[2]
# 檢查環境變數(支援預設憑證)
p12_path = os.environ.get("PDF_SIGN_P12_PATH", "/app/certs/default.p12")
p12_password = os.environ.get("PDF_SIGN_P12_PASSWORD", "")
sign_reason = os.environ.get("PDF_SIGN_REASON", "ConvertX-CN PDF Packager")
sign_location = os.environ.get("PDF_SIGN_LOCATION", "ConvertX-CN")
sign_contact = os.environ.get("PDF_SIGN_CONTACT", "")
if not os.path.exists(p12_path):
print(f"錯誤: 憑證檔案不存在: {p12_path}", file=sys.stderr)
print("提示: Docker 環境預設使用 /app/certs/default.p12", file=sys.stderr)
print(" 如需使用自訂憑證,請設定 PDF_SIGN_P12_PATH 環境變數", file=sys.stderr)
sys.exit(2)
if not os.path.exists(input_pdf):
print(f"錯誤: 輸入檔案不存在: {input_pdf}", file=sys.stderr)
sys.exit(1)
try:
# 載入 endesive
from endesive.pdf import cms
from cryptography.hazmat.primitives.serialization import pkcs12
from cryptography.hazmat.backends import default_backend
# 讀取 PKCS12 憑證
print(f"[PDF Sign] 載入憑證: {p12_path}")
with open(p12_path, "rb") as f:
p12_data = f.read()
try:
private_key, certificate, additional_certs = pkcs12.load_key_and_certificates(
p12_data,
p12_password.encode() if p12_password else None,
default_backend()
)
except Exception as e:
print(f"錯誤: 無法載入憑證(密碼錯誤或格式不正確): {e}", file=sys.stderr)
sys.exit(3)
if not private_key or not certificate:
print("錯誤: 憑證中未找到私鑰或證書", file=sys.stderr)
sys.exit(3)
# 讀取 PDF
print(f"[PDF Sign] 讀取 PDF: {input_pdf}")
with open(input_pdf, "rb") as f:
pdf_data = f.read()
# 準備簽章參數
dct = {
"aligned": 0,
"sigflags": 3,
"sigflagsft": 132,
"sigpage": 0,
"sigbutton": False,
"contact": sign_contact,
"location": sign_location,
"signingdate": datetime.utcnow().strftime("%Y%m%d%H%M%S+00'00'"),
"reason": sign_reason,
}
# 執行簽章
print("[PDF Sign] 執行數位簽章...")
signed_data = cms.sign(
pdf_data,
dct,
private_key,
certificate,
additional_certs or [],
"sha256",
)
# 寫入輸出檔案
print(f"[PDF Sign] 寫入簽章 PDF: {output_pdf}")
with open(output_pdf, "wb") as f:
f.write(pdf_data)
f.write(signed_data)
print("[PDF Sign] ✅ 簽章完成")
sys.exit(0)
except ImportError as e:
print(f"錯誤: 缺少必要的 Python 庫: {e}", file=sys.stderr)
print("請確保已安裝 endesive: pip install endesive", file=sys.stderr)
sys.exit(4)
except Exception as e:
print(f"錯誤: 簽章失敗: {e}", file=sys.stderr)
sys.exit(4)
if __name__ == "__main__":
main()