mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
G9: Preserve supplied passwords when confirming the Save PDF dialog
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
parent
4a7cba0dd3
commit
c021f402a9
@@ -95,8 +95,20 @@ pub fn open(app: &mut VectorcraftApp, params: &Value) -> Result<Value, String> {
|
||||
/// dialog fields. A standard the writer can't produce yet still shows (Save PDF then says so).
|
||||
fn settings_fields(app: &VectorcraftApp, params: &Value) -> Result<Map<String, Value>, String> {
|
||||
let settings = pdf::resolve("ui.savePdfDialog", params, &app.session.prefs.pdf_presets).map_err(|e| e.to_string())?;
|
||||
match serde_json::to_value(settings).map_err(|e| e.to_string())? {
|
||||
Value::Object(fields) => Ok(fields),
|
||||
match serde_json::to_value(&settings).map_err(|e| e.to_string())? {
|
||||
Value::Object(mut fields) => {
|
||||
// Serialization omits passwords from presets and summaries; the live dialog needs
|
||||
// the validated passwords so confirming it still encrypts the PDF.
|
||||
let security = fields.get_mut("security").and_then(Value::as_object_mut).ok_or("PDF security settings are not an object")?;
|
||||
for (key, password) in
|
||||
[("openPassword", settings.security.open_password), ("permissionsPassword", settings.security.permissions_password)]
|
||||
{
|
||||
if !password.is_empty() {
|
||||
security.insert(key.into(), json!(password));
|
||||
}
|
||||
}
|
||||
Ok(fields)
|
||||
}
|
||||
_ => Err("PDF settings are not an object".into()),
|
||||
}
|
||||
}
|
||||
@@ -1020,6 +1032,46 @@ mod tests {
|
||||
assert_eq!(SECTIONS[section_of("standard")], "General");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn confirming_preserves_passwords_supplied_when_opening_the_dialog() {
|
||||
for (open, owner) in [("open", ""), ("", "owner"), ("open", "owner")] {
|
||||
let (mut app, written, _) = app();
|
||||
app.run(
|
||||
"ui.savePdfDialog",
|
||||
json!({"path": "/tmp/locked.pdf", "security": {"openPassword": open, "permissionsPassword": owner, "printing": "none"}}),
|
||||
)
|
||||
.unwrap();
|
||||
// Drawing the Security and Summary sections must retain the live passwords.
|
||||
for section in ["Security", "Summary"] {
|
||||
set_field(&mut app, "__section", json!(section));
|
||||
frame(&mut app);
|
||||
}
|
||||
let p = params(app.ui.dialog.as_ref().unwrap());
|
||||
let summary = summary_of(&mut app, &egui::Context::default(), &p).unwrap();
|
||||
assert!(!summary.to_string().contains("Password"), "summaries omit passwords");
|
||||
let mut d = app.ui.dialog.clone().unwrap();
|
||||
set(&mut d, SAVE_AS, json!("Protected"));
|
||||
save_preset(&mut app, &mut d).unwrap();
|
||||
let saved = &app.session.prefs.pdf_presets[0].settings.security;
|
||||
assert!(saved.open_password.is_empty() && saved.permissions_password.is_empty(), "presets forget passwords");
|
||||
|
||||
super::super::confirm(&mut app).unwrap();
|
||||
assert!(app.ui.dialog.is_none());
|
||||
let written = written.borrow();
|
||||
let bytes = &written[0].1;
|
||||
assert!(String::from_utf8_lossy(bytes).contains("/Encrypt"));
|
||||
if open.is_empty() {
|
||||
assert_eq!(vectorcraft_pdf::info(bytes, None).unwrap().pages.len(), 3);
|
||||
} else {
|
||||
assert_eq!(vectorcraft_pdf::info(bytes, None).unwrap_err(), vectorcraft_pdf::PdfError::NeedsPassword);
|
||||
}
|
||||
assert_eq!(vectorcraft_pdf::info(bytes, Some("wrong")).unwrap_err(), vectorcraft_pdf::PdfError::WrongPassword);
|
||||
for password in [open, owner].into_iter().filter(|p| !p.is_empty()) {
|
||||
assert_eq!(vectorcraft_pdf::info(bytes, Some(password)).unwrap().pages.len(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_security_section_takes_passwords_that_presets_drop() {
|
||||
let (mut app, _, _) = app();
|
||||
|
||||
Reference in New Issue
Block a user