1use crate::error::PdfError;
7use crate::forms::signature_field::{SignatureAlgorithm, SignatureField, SignerInfo};
8use crate::objects::{Dictionary, Object};
9use chrono::Utc;
10use std::collections::{HashMap, HashSet};
11
12pub struct SignatureHandler {
14 signature_fields: HashMap<String, SignatureField>,
16 locked_fields: HashSet<String>,
18 settings: SignatureSettings,
20}
21
22#[derive(Debug, Clone)]
24pub struct SignatureSettings {
25 pub incremental_save: bool,
27 pub require_all_signatures: bool,
29 pub lock_all_after_first_signature: bool,
31 pub default_algorithm: SignatureAlgorithm,
33 pub enable_timestamps: bool,
35}
36
37impl Default for SignatureSettings {
38 fn default() -> Self {
39 Self {
40 incremental_save: true,
41 require_all_signatures: false,
42 lock_all_after_first_signature: false,
43 default_algorithm: SignatureAlgorithm::RsaSha256,
44 enable_timestamps: true,
45 }
46 }
47}
48
49#[derive(Debug, Clone)]
51pub struct ValidationResult {
52 pub field_name: String,
54 pub is_valid: bool,
56 pub signer: Option<SignerInfo>,
58 pub validated_at: chrono::DateTime<Utc>,
60 pub errors: Vec<String>,
62 pub warnings: Vec<String>,
64}
65
66#[allow(clippy::derivable_impls)]
67impl Default for SignatureHandler {
68 fn default() -> Self {
69 Self {
70 signature_fields: HashMap::new(),
71 locked_fields: HashSet::new(),
72 settings: SignatureSettings::default(),
73 }
74 }
75}
76
77impl SignatureHandler {
78 pub fn new() -> Self {
80 Self::default()
81 }
82
83 pub fn with_settings(settings: SignatureSettings) -> Self {
85 Self {
86 signature_fields: HashMap::new(),
87 locked_fields: HashSet::new(),
88 settings,
89 }
90 }
91
92 pub fn add_signature_field(&mut self, field: SignatureField) -> Result<(), PdfError> {
94 if self.signature_fields.contains_key(&field.name) {
95 return Err(PdfError::DuplicateField(format!(
96 "Signature field '{}' already exists",
97 field.name
98 )));
99 }
100
101 self.signature_fields.insert(field.name.clone(), field);
102 Ok(())
103 }
104
105 pub fn get_field(&self, name: &str) -> Option<&SignatureField> {
107 self.signature_fields.get(name)
108 }
109
110 pub fn get_field_mut(&mut self, name: &str) -> Option<&mut SignatureField> {
112 self.signature_fields.get_mut(name)
113 }
114
115 pub fn sign_field(
117 &mut self,
118 field_name: &str,
119 signer: SignerInfo,
120 reason: Option<String>,
121 ) -> Result<(), PdfError> {
122 if self.locked_fields.contains(field_name) {
124 return Err(PdfError::InvalidOperation(format!(
125 "Field '{}' is locked and cannot be signed",
126 field_name
127 )));
128 }
129
130 let field = self
132 .signature_fields
133 .get_mut(field_name)
134 .ok_or_else(|| PdfError::FieldNotFound(field_name.to_string()))?;
135
136 field.sign(signer, reason)?;
137
138 let fields_to_lock = field.lock_fields.clone();
140 for field_to_lock in fields_to_lock {
141 self.locked_fields.insert(field_to_lock);
142 }
143
144 if self.settings.lock_all_after_first_signature {
146 for field_name in self.signature_fields.keys() {
147 self.locked_fields.insert(field_name.clone());
148 }
149 }
150
151 Ok(())
152 }
153
154 pub fn validate_all(&self) -> Vec<ValidationResult> {
156 let mut results = Vec::new();
157
158 for (name, field) in &self.signature_fields {
159 results.push(self.validate_field(name, field));
160 }
161
162 results
163 }
164
165 fn validate_field(&self, name: &str, field: &SignatureField) -> ValidationResult {
167 let mut result = ValidationResult {
168 field_name: name.to_string(),
169 is_valid: false,
170 signer: field.signer.clone(),
171 validated_at: Utc::now(),
172 errors: Vec::new(),
173 warnings: Vec::new(),
174 };
175
176 if !field.is_signed() {
177 if field.required {
178 result
179 .errors
180 .push("Required signature field is not signed".to_string());
181 } else {
182 result.warnings.push("Field is not signed".to_string());
183 }
184 return result;
185 }
186
187 match field.verify() {
189 Ok(valid) => {
190 result.is_valid = valid;
191 if !valid {
192 result
193 .errors
194 .push("Signature verification failed".to_string());
195 }
196 }
197 Err(e) => {
198 result.errors.push(format!("Validation error: {}", e));
199 }
200 }
201
202 if let Some(ref sig_value) = field.signature_value {
204 if sig_value.certificates.is_empty() {
206 result
207 .warnings
208 .push("No certificates found in signature".to_string());
209 }
210 }
211
212 result
213 }
214
215 pub fn is_field_locked(&self, field_name: &str) -> bool {
217 self.locked_fields.contains(field_name)
218 }
219
220 pub fn get_unsigned_required_fields(&self) -> Vec<String> {
222 self.signature_fields
223 .iter()
224 .filter(|(_, field)| field.required && !field.is_signed())
225 .map(|(name, _)| name.clone())
226 .collect()
227 }
228
229 pub fn all_required_signed(&self) -> bool {
231 self.get_unsigned_required_fields().is_empty()
232 }
233
234 pub fn get_signing_order(&self) -> Vec<String> {
236 let mut order = Vec::new();
238 let mut added = HashSet::new();
239
240 for (name, field) in &self.signature_fields {
242 if field.lock_fields.is_empty() && !field.is_signed() {
243 order.push(name.clone());
244 added.insert(name.clone());
245 }
246 }
247
248 for (name, field) in &self.signature_fields {
250 if !added.contains(name) && !field.is_signed() {
251 order.push(name.clone());
252 }
253 }
254
255 order
256 }
257
258 pub fn export_to_dict(&self) -> Dictionary {
260 let mut dict = Dictionary::new();
261 let mut fields = Vec::new();
262
263 for field in self.signature_fields.values() {
264 fields.push(Object::Dictionary(field.to_dict()));
265 }
266
267 dict.set("Fields", Object::Array(fields));
268 dict.set("SigFlags", Object::Integer(3)); dict
271 }
272
273 pub fn generate_summary(&self) -> SignatureSummary {
275 let total = self.signature_fields.len();
276 let signed = self
277 .signature_fields
278 .values()
279 .filter(|f| f.is_signed())
280 .count();
281 let required = self
282 .signature_fields
283 .values()
284 .filter(|f| f.required)
285 .count();
286 let required_signed = self
287 .signature_fields
288 .values()
289 .filter(|f| f.required && f.is_signed())
290 .count();
291
292 SignatureSummary {
293 total_fields: total,
294 signed_fields: signed,
295 unsigned_fields: total - signed,
296 required_fields: required,
297 required_signed,
298 required_unsigned: required - required_signed,
299 all_required_complete: required == required_signed,
300 locked_fields: self.locked_fields.len(),
301 }
302 }
303}
304
305#[derive(Debug, Clone)]
307pub struct SignatureSummary {
308 pub total_fields: usize,
310 pub signed_fields: usize,
312 pub unsigned_fields: usize,
314 pub required_fields: usize,
316 pub required_signed: usize,
318 pub required_unsigned: usize,
320 pub all_required_complete: bool,
322 pub locked_fields: usize,
324}
325
326impl SignatureSummary {
327 pub fn completion_percentage(&self) -> f64 {
329 if self.total_fields == 0 {
330 100.0
331 } else {
332 (self.signed_fields as f64 / self.total_fields as f64) * 100.0
333 }
334 }
335
336 pub fn is_ready(&self) -> bool {
338 self.all_required_complete
339 }
340
341 pub fn to_report(&self) -> String {
343 format!(
344 "Signature Summary:\n\
345 - Total fields: {}\n\
346 - Signed: {} ({:.1}%)\n\
347 - Unsigned: {}\n\
348 - Required fields: {} ({} signed, {} unsigned)\n\
349 - Status: {}\n\
350 - Locked fields: {}",
351 self.total_fields,
352 self.signed_fields,
353 self.completion_percentage(),
354 self.unsigned_fields,
355 self.required_fields,
356 self.required_signed,
357 self.required_unsigned,
358 if self.is_ready() {
359 "Ready"
360 } else {
361 "Incomplete"
362 },
363 self.locked_fields
364 )
365 }
366}
367
368#[cfg(test)]
369mod tests {
370 use super::*;
371
372 #[test]
373 fn test_signature_handler_creation() {
374 let handler = SignatureHandler::new();
375 assert_eq!(handler.signature_fields.len(), 0);
376 assert_eq!(handler.locked_fields.len(), 0);
377 }
378
379 #[test]
380 fn test_add_signature_field() {
381 let mut handler = SignatureHandler::new();
382 let field = SignatureField::new("sig1");
383
384 assert!(handler.add_signature_field(field.clone()).is_ok());
385 assert_eq!(handler.signature_fields.len(), 1);
386
387 assert!(handler.add_signature_field(field).is_err());
389 }
390
391 #[test]
392 fn test_sign_field() {
393 let mut handler = SignatureHandler::new();
394 let field =
395 SignatureField::new("sig1").lock_fields_after_signing(vec!["field1".to_string()]);
396
397 handler.add_signature_field(field).unwrap();
398
399 let signer = SignerInfo::new("John Doe");
400 assert!(handler
401 .sign_field("sig1", signer, Some("Approved".to_string()))
402 .is_ok());
403
404 assert!(handler.is_field_locked("field1"));
406 }
407
408 #[test]
409 fn test_validation() {
410 let mut handler = SignatureHandler::new();
411 let field = SignatureField::new("sig1").required();
412
413 handler.add_signature_field(field).unwrap();
414
415 let results = handler.validate_all();
416 assert_eq!(results.len(), 1);
417 assert!(!results[0].is_valid);
418 assert!(!results[0].errors.is_empty());
419 }
420
421 #[test]
422 fn test_signing_order() {
423 let mut handler = SignatureHandler::new();
424
425 let field1 =
427 SignatureField::new("sig1").lock_fields_after_signing(vec!["sig2".to_string()]);
428 let field2 = SignatureField::new("sig2");
429
430 handler.add_signature_field(field1).unwrap();
431 handler.add_signature_field(field2).unwrap();
432
433 let order = handler.get_signing_order();
434 assert_eq!(order[0], "sig2"); assert_eq!(order[1], "sig1"); }
437
438 #[test]
439 fn test_summary() {
440 let mut handler = SignatureHandler::new();
441
442 handler
443 .add_signature_field(SignatureField::new("sig1").required())
444 .unwrap();
445 handler
446 .add_signature_field(SignatureField::new("sig2"))
447 .unwrap();
448
449 let summary = handler.generate_summary();
450 assert_eq!(summary.total_fields, 2);
451 assert_eq!(summary.required_fields, 1);
452 assert_eq!(summary.signed_fields, 0);
453 assert!(!summary.is_ready());
454
455 handler
457 .sign_field("sig1", SignerInfo::new("Signer"), None)
458 .unwrap();
459
460 let summary = handler.generate_summary();
461 assert_eq!(summary.signed_fields, 1);
462 assert!(summary.is_ready());
463 }
464}