caerp-sign-pdf 2024.1.1__tar.gz → 2024.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. caerp_sign_pdf-2024.1.3/CURRENT_VERSION +1 -0
  2. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/PKG-INFO +1 -1
  3. caerp_sign_pdf-2024.1.3/requirements.txt +1 -0
  4. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf/public.py +50 -17
  5. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf.egg-info/PKG-INFO +1 -1
  6. caerp_sign_pdf-2024.1.3/src/caerp_sign_pdf.egg-info/requires.txt +1 -0
  7. caerp_sign_pdf-2024.1.1/CURRENT_VERSION +0 -1
  8. caerp_sign_pdf-2024.1.1/requirements.txt +0 -1
  9. caerp_sign_pdf-2024.1.1/src/caerp_sign_pdf.egg-info/requires.txt +0 -1
  10. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/LICENSE.txt +0 -0
  11. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/MANIFEST.in +0 -0
  12. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/README.rst +0 -0
  13. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/setup.cfg +0 -0
  14. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/setup.py +0 -0
  15. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf/__init__.py +0 -0
  16. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf/models.py +0 -0
  17. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf.egg-info/SOURCES.txt +0 -0
  18. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf.egg-info/dependency_links.txt +0 -0
  19. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf.egg-info/not-zip-safe +0 -0
  20. {caerp_sign_pdf-2024.1.1 → caerp_sign_pdf-2024.1.3}/src/caerp_sign_pdf.egg-info/top_level.txt +0 -0
@@ -0,0 +1 @@
1
+ 2024.1.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: caerp_sign_pdf
3
- Version: 2024.1.1
3
+ Version: 2024.1.3
4
4
  Summary: caerp_sign_pdf
5
5
  Home-page: https://framagit.org/caerp/caerp_sign_pdf
6
6
  Author: Kilya
@@ -0,0 +1 @@
1
+ pyHanko[pkcs11,image-support,opentype,xmp]==0.25.0
@@ -4,12 +4,11 @@ import hashlib
4
4
 
5
5
  from io import BytesIO
6
6
  from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
7
- from pyhanko.sign import (
8
- fields,
9
- signers,
10
- )
7
+ from pyhanko.sign import fields, signers
11
8
  from pyhanko.sign.general import SigningError
12
9
  from pyhanko.stamp import TextStampStyle
10
+ from PyPDF4.pdf import PdfFileReader, PdfFileWriter
11
+ from pyramid.httpexceptions import HTTPUnsupportedMediaType
13
12
 
14
13
  from caerp.views.files.controller import FileData
15
14
 
@@ -19,6 +18,14 @@ from .models import PDFSignatureHistory
19
18
  logger = logging.getLogger(f"caerp.{__name__}")
20
19
 
21
20
 
21
+ ERROR_LOAD_CERTIFICATE_MSG = "Impossible de charger le certificat à utiliser \
22
+ pour signer numériquement le fichier. Veuillez contacter le support."
23
+
24
+ ERROR_PDF_FORMAT_MSG = "Le fichier PDF ne peut pas être signé numériquement \
25
+ car son format n'est pas correct. Vous pouvez essayer de l'imprimer dans un \
26
+ nouveau fichier PDF avant de le recharger."
27
+
28
+
22
29
  class SignPDFService(object):
23
30
  def __init__(self, context, request):
24
31
  self.context = context
@@ -51,6 +58,19 @@ class SignPDFService(object):
51
58
  """
52
59
  return hashlib.md5(file_data.getvalue()).hexdigest()
53
60
 
61
+ def _get_safe_pdf(self, file_data: BytesIO) -> str:
62
+ """
63
+ Create a new clean PDF buffer from the original
64
+ to avoid some format errors
65
+ """
66
+ writer = PdfFileWriter()
67
+ reader = PdfFileReader(file_data, strict=False)
68
+ num_pages = reader.getNumPages()
69
+ for page in range(num_pages):
70
+ writer.addPage(reader.getPage(page))
71
+ writer.write(file_data)
72
+ return file_data
73
+
54
74
  def sign(
55
75
  self, pdf_data: FileData, node_id: int = None, with_stamp: bool = False
56
76
  ) -> bool:
@@ -77,11 +97,11 @@ class SignPDFService(object):
77
97
  passphrase=self._get_certificate_passphrase().encode(),
78
98
  )
79
99
  if not signer:
80
- raise Exception(
100
+ logger.error(
81
101
  "Unable to load certificate for signing PDF files (check \
82
- 'caerp.sign_certificate_path' and 'caerp.sign_certificate_passphrase' \
83
- in config)"
102
+ 'caerp.sign_certificate_path' and 'caerp.sign_certificate_passphrase' in config)"
84
103
  )
104
+ raise Exception(ERROR_LOAD_CERTIFICATE_MSG)
85
105
 
86
106
  # Prepare stamp (if needed)
87
107
  stamp = None
@@ -97,11 +117,18 @@ in config)"
97
117
  border_width=0,
98
118
  )
99
119
 
100
- # Sign
101
- w = IncrementalPdfFileWriter(pdf_data.data, strict=False)
120
+ # Open original PDF
121
+ try:
122
+ pdf_data.data = self._get_safe_pdf(pdf_data.data)
123
+ pdf_writer = IncrementalPdfFileWriter(pdf_data.data, strict=False)
124
+ except Exception as error:
125
+ logger.error(f"Error while opening original PDF file : {error}")
126
+ raise HTTPUnsupportedMediaType(ERROR_PDF_FORMAT_MSG)
127
+
128
+ # Add signature field on the PDF
102
129
  try:
103
130
  fields.append_signature_field(
104
- w,
131
+ pdf_writer,
105
132
  sig_field_spec=fields.SigFieldSpec(
106
133
  "SignatureCAERP", box=(445, 800, 580, 830)
107
134
  ),
@@ -109,13 +136,19 @@ in config)"
109
136
  except SigningError:
110
137
  logger.warn("File is already signed, nothing to do")
111
138
  return True
112
- meta = signers.PdfSignatureMetadata(field_name="SignatureCAERP")
113
- pdf_signer = signers.PdfSigner(
114
- meta,
115
- signer=signer,
116
- stamp_style=stamp,
117
- )
118
- pdf_data.data = pdf_signer.sign_pdf(w)
139
+
140
+ # Sign PDF
141
+ try:
142
+ meta = signers.PdfSignatureMetadata(field_name="SignatureCAERP")
143
+ pdf_signer = signers.PdfSigner(
144
+ meta,
145
+ signer=signer,
146
+ stamp_style=stamp,
147
+ )
148
+ pdf_data.data = pdf_signer.sign_pdf(pdf_writer)
149
+ except Exception as error:
150
+ logger.error(f"Error while signing PDF file : {error}")
151
+ raise HTTPUnsupportedMediaType(ERROR_PDF_FORMAT_MSG)
119
152
  logger.info(
120
153
  "File '{}' signed successfully by {} !".format(
121
154
  pdf_data.name, signer.subject_name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: caerp-sign-pdf
3
- Version: 2024.1.1
3
+ Version: 2024.1.3
4
4
  Summary: caerp_sign_pdf
5
5
  Home-page: https://framagit.org/caerp/caerp_sign_pdf
6
6
  Author: Kilya
@@ -0,0 +1 @@
1
+ pyHanko[image-support,opentype,pkcs11,xmp]==0.25.0
@@ -1 +0,0 @@
1
- 2024.1.1
@@ -1 +0,0 @@
1
- pyHanko[pkcs11,image-support,opentype,xmp]==0.20.1
@@ -1 +0,0 @@
1
- pyHanko[image-support,opentype,pkcs11,xmp]==0.20.1