caerp-sign-pdf 2024.1.4__tar.gz → 2024.2.1__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.
- caerp_sign_pdf-2024.2.1/CURRENT_VERSION +1 -0
- {caerp_sign_pdf-2024.1.4/src/caerp_sign_pdf.egg-info → caerp_sign_pdf-2024.2.1}/PKG-INFO +4 -2
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf/public.py +58 -34
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1/src/caerp_sign_pdf.egg-info}/PKG-INFO +5 -3
- caerp_sign_pdf-2024.1.4/CURRENT_VERSION +0 -1
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/LICENSE.txt +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/MANIFEST.in +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/README.rst +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/requirements.txt +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/setup.cfg +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/setup.py +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf/__init__.py +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf/models.py +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/SOURCES.txt +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/dependency_links.txt +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/not-zip-safe +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/requires.txt +0 -0
- {caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2024.2.1
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: caerp_sign_pdf
|
|
3
|
-
Version: 2024.1
|
|
3
|
+
Version: 2024.2.1
|
|
4
4
|
Summary: caerp_sign_pdf
|
|
5
5
|
Home-page: https://framagit.org/caerp/caerp_sign_pdf
|
|
6
6
|
Author: Kilya
|
|
7
7
|
Author-email: contact@kilya.net
|
|
8
8
|
License: GPLv3
|
|
9
9
|
Keywords: web wsgi bfg pylons pyramid caerp
|
|
10
|
+
Platform: UNKNOWN
|
|
10
11
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
11
12
|
Classifier: Programming Language :: Python
|
|
12
13
|
Classifier: Framework :: Pyramid
|
|
@@ -14,7 +15,6 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
14
15
|
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
15
16
|
Description-Content-Type: text/x-rst
|
|
16
17
|
License-File: LICENSE.txt
|
|
17
|
-
Requires-Dist: pyHanko[image-support,opentype,pkcs11,xmp]==0.25.1
|
|
18
18
|
|
|
19
19
|
CAERP Sign PDF
|
|
20
20
|
======================================================
|
|
@@ -70,3 +70,5 @@ Sous linux la signature d'un document PDF peut être vérifiée facilement en li
|
|
|
70
70
|
|
|
71
71
|
pdfsig <monfichierpdf.pdf>
|
|
72
72
|
|
|
73
|
+
|
|
74
|
+
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import logging
|
|
3
3
|
import hashlib
|
|
4
|
+
import subprocess
|
|
4
5
|
|
|
5
6
|
from io import BytesIO
|
|
6
7
|
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
|
|
7
|
-
from pyhanko.pdf_utils.xref import ObjectHeaderReadError
|
|
8
8
|
from pyhanko.sign import fields, signers
|
|
9
9
|
from pyhanko.sign.general import SigningError
|
|
10
10
|
from pyhanko.stamp import TextStampStyle
|
|
11
|
-
from PyPDF4.pdf import PdfFileReader, PdfFileWriter
|
|
12
11
|
from pyramid.httpexceptions import HTTPUnsupportedMediaType
|
|
13
12
|
|
|
14
13
|
from caerp.views.files.controller import FileData
|
|
@@ -28,6 +27,10 @@ nouveau fichier PDF avant de le recharger."
|
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
class SignPDFService(object):
|
|
30
|
+
"""
|
|
31
|
+
The PDF digital signing service
|
|
32
|
+
"""
|
|
33
|
+
|
|
31
34
|
def __init__(self, context, request):
|
|
32
35
|
self.context = context
|
|
33
36
|
self.request = request
|
|
@@ -59,18 +62,44 @@ class SignPDFService(object):
|
|
|
59
62
|
"""
|
|
60
63
|
return hashlib.md5(file_data.getvalue()).hexdigest()
|
|
61
64
|
|
|
62
|
-
def
|
|
65
|
+
def _get_clean_pdf(self, file_data: BytesIO) -> BytesIO:
|
|
63
66
|
"""
|
|
64
|
-
Create a new clean PDF buffer from the original
|
|
65
|
-
to avoid some format errors
|
|
67
|
+
Create a new clean PDF buffer from the original to avoid format errors
|
|
66
68
|
"""
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
logger.info(f"Cleaning PDF buffer...")
|
|
70
|
+
file_data.seek(0)
|
|
71
|
+
process = subprocess.Popen(
|
|
72
|
+
["/usr/bin/pdftocairo", "-pdf", "-", "-"],
|
|
73
|
+
stdin=subprocess.PIPE,
|
|
74
|
+
stdout=subprocess.PIPE,
|
|
75
|
+
)
|
|
76
|
+
output = process.communicate(input=file_data.read())[0]
|
|
77
|
+
result = BytesIO()
|
|
78
|
+
result.write(output)
|
|
79
|
+
result.seek(0)
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
def _get_pdf_stamp(self, display_stamp: bool) -> TextStampStyle:
|
|
83
|
+
"""
|
|
84
|
+
Prepare physical stamp to apply on the PDF
|
|
85
|
+
|
|
86
|
+
:param bool display_stamp: Whether the stamp must be visible or not
|
|
87
|
+
|
|
88
|
+
:return TextStampStyle: The stamp object
|
|
89
|
+
"""
|
|
90
|
+
stamp = None
|
|
91
|
+
if display_stamp:
|
|
92
|
+
stamp = TextStampStyle(
|
|
93
|
+
timestamp_format="%d/%m/%Y %H:%M:%S %Z",
|
|
94
|
+
stamp_text="Signé par: %(signer)s\nLe: %(ts)s",
|
|
95
|
+
border_width=2,
|
|
96
|
+
)
|
|
97
|
+
else:
|
|
98
|
+
stamp = TextStampStyle(
|
|
99
|
+
stamp_text="",
|
|
100
|
+
border_width=0,
|
|
101
|
+
)
|
|
102
|
+
return stamp
|
|
74
103
|
|
|
75
104
|
def sign(
|
|
76
105
|
self, pdf_data: FileData, node_id: int = None, with_stamp: bool = False
|
|
@@ -81,7 +110,8 @@ class SignPDFService(object):
|
|
|
81
110
|
|
|
82
111
|
:param FileData pdf_data: The FileData object describing the PDF file
|
|
83
112
|
:param int node_id: The related node's id if relevant
|
|
84
|
-
:param bool with_stamp:
|
|
113
|
+
:param bool with_stamp: Whether we want a printed stamp on result file or not
|
|
114
|
+
|
|
85
115
|
:return bool: either the PDF has been signed or not
|
|
86
116
|
"""
|
|
87
117
|
|
|
@@ -89,7 +119,7 @@ class SignPDFService(object):
|
|
|
89
119
|
|
|
90
120
|
# Check mimetype
|
|
91
121
|
if not pdf_data.mimetype == "application/pdf":
|
|
92
|
-
logger.
|
|
122
|
+
logger.warning("File is not a PDF, signing aborted")
|
|
93
123
|
return False
|
|
94
124
|
|
|
95
125
|
# Load sign certificate
|
|
@@ -104,26 +134,18 @@ class SignPDFService(object):
|
|
|
104
134
|
)
|
|
105
135
|
raise Exception(ERROR_LOAD_CERTIFICATE_MSG)
|
|
106
136
|
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
border_width=2,
|
|
114
|
-
)
|
|
115
|
-
else:
|
|
116
|
-
stamp = TextStampStyle(
|
|
117
|
-
stamp_text="",
|
|
118
|
-
border_width=0,
|
|
119
|
-
)
|
|
137
|
+
# Clean PDF
|
|
138
|
+
try:
|
|
139
|
+
pdf_data.data = self._get_clean_pdf(pdf_data.data)
|
|
140
|
+
except Exception as error:
|
|
141
|
+
logger.error(f"Error while cleaning original PDF file : {error}")
|
|
142
|
+
raise HTTPUnsupportedMediaType(ERROR_PDF_FORMAT_MSG)
|
|
120
143
|
|
|
121
|
-
# Open
|
|
144
|
+
# Open PDF
|
|
122
145
|
try:
|
|
123
|
-
pdf_data.data = self._get_safe_pdf(pdf_data.data)
|
|
124
146
|
pdf_writer = IncrementalPdfFileWriter(pdf_data.data, strict=False)
|
|
125
147
|
except Exception as error:
|
|
126
|
-
logger.error(f"Error while opening
|
|
148
|
+
logger.error(f"Error while opening PDF file : {error}")
|
|
127
149
|
raise HTTPUnsupportedMediaType(ERROR_PDF_FORMAT_MSG)
|
|
128
150
|
|
|
129
151
|
# Add signature field on the PDF
|
|
@@ -135,10 +157,10 @@ class SignPDFService(object):
|
|
|
135
157
|
),
|
|
136
158
|
)
|
|
137
159
|
except SigningError:
|
|
138
|
-
logger.
|
|
160
|
+
logger.warning("File is already signed, nothing to do")
|
|
139
161
|
return True
|
|
140
|
-
except
|
|
141
|
-
logger.error(f"Error while
|
|
162
|
+
except Exception as error:
|
|
163
|
+
logger.error(f"Error while adding signature field : {error}")
|
|
142
164
|
raise HTTPUnsupportedMediaType(ERROR_PDF_FORMAT_MSG)
|
|
143
165
|
|
|
144
166
|
# Sign PDF
|
|
@@ -147,12 +169,14 @@ class SignPDFService(object):
|
|
|
147
169
|
pdf_signer = signers.PdfSigner(
|
|
148
170
|
meta,
|
|
149
171
|
signer=signer,
|
|
150
|
-
stamp_style=
|
|
172
|
+
stamp_style=self._get_pdf_stamp(with_stamp),
|
|
151
173
|
)
|
|
152
174
|
pdf_data.data = pdf_signer.sign_pdf(pdf_writer)
|
|
153
175
|
except Exception as error:
|
|
154
176
|
logger.error(f"Error while signing PDF file : {error}")
|
|
155
177
|
raise HTTPUnsupportedMediaType(ERROR_PDF_FORMAT_MSG)
|
|
178
|
+
|
|
179
|
+
# Success
|
|
156
180
|
logger.info(
|
|
157
181
|
"File '{}' signed successfully by {} !".format(
|
|
158
182
|
pdf_data.name, signer.subject_name
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2024.1
|
|
2
|
+
Name: caerp-sign-pdf
|
|
3
|
+
Version: 2024.2.1
|
|
4
4
|
Summary: caerp_sign_pdf
|
|
5
5
|
Home-page: https://framagit.org/caerp/caerp_sign_pdf
|
|
6
6
|
Author: Kilya
|
|
7
7
|
Author-email: contact@kilya.net
|
|
8
8
|
License: GPLv3
|
|
9
9
|
Keywords: web wsgi bfg pylons pyramid caerp
|
|
10
|
+
Platform: UNKNOWN
|
|
10
11
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
11
12
|
Classifier: Programming Language :: Python
|
|
12
13
|
Classifier: Framework :: Pyramid
|
|
@@ -14,7 +15,6 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
14
15
|
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
15
16
|
Description-Content-Type: text/x-rst
|
|
16
17
|
License-File: LICENSE.txt
|
|
17
|
-
Requires-Dist: pyHanko[image-support,opentype,pkcs11,xmp]==0.25.1
|
|
18
18
|
|
|
19
19
|
CAERP Sign PDF
|
|
20
20
|
======================================================
|
|
@@ -70,3 +70,5 @@ Sous linux la signature d'un document PDF peut être vérifiée facilement en li
|
|
|
70
70
|
|
|
71
71
|
pdfsig <monfichierpdf.pdf>
|
|
72
72
|
|
|
73
|
+
|
|
74
|
+
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2024.1.4
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/requires.txt
RENAMED
|
File without changes
|
{caerp_sign_pdf-2024.1.4 → caerp_sign_pdf-2024.2.1}/src/caerp_sign_pdf.egg-info/top_level.txt
RENAMED
|
File without changes
|