mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-29 09:37:37 +08:00
Webdav (#923)
* feat: WebDAV backup/restore - Add WebDAV test/backup/restore commands and settings\n- Fix ja i18n missing keys; decode PROPFIND href as UTF-8\n- Stabilize Windows prompt auto-import tests via CC_SWITCH_TEST_HOME * chore: format and minor cleanups * fix: update build config * feat(webdav): unify sync UX and hardening fixes * fix(webdav): harden sync flow and stabilize sync UX/tests * fix(webdav): add resource limits to skills.zip extraction Prevent zip bomb / resource exhaustion by enforcing: - MAX_EXTRACT_ENTRIES (10,000 files) - MAX_EXTRACT_BYTES (512 MB cumulative) * refactor(webdav): drop deviceId and display deviceName only --------- Co-authored-by: small-lovely-cat <77799160+small-lovely-cat@users.noreply.github.com> Co-authored-by: saladday <1203511142@qq.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
use serde_json::{json, Value};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::database::Database;
|
||||
use crate::error::AppError;
|
||||
use crate::services::provider::ProviderService;
|
||||
use crate::settings;
|
||||
use crate::store::AppState;
|
||||
|
||||
pub(crate) fn run_post_import_sync(db: Arc<Database>) -> Result<(), AppError> {
|
||||
let app_state = AppState::new(db);
|
||||
ProviderService::sync_current_to_live(&app_state)?;
|
||||
settings::reload_settings()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn post_sync_warning<E: std::fmt::Display>(err: E) -> String {
|
||||
AppError::localized(
|
||||
"sync.post_operation_sync_failed",
|
||||
format!("后置同步状态失败: {err}"),
|
||||
format!("Post-operation synchronization failed: {err}"),
|
||||
)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub(crate) fn post_sync_warning_from_result(
|
||||
result: Result<Result<(), AppError>, String>,
|
||||
) -> Option<String> {
|
||||
match result {
|
||||
Ok(Ok(())) => None,
|
||||
Ok(Err(err)) => Some(post_sync_warning(err)),
|
||||
Err(err) => Some(post_sync_warning(err)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn attach_warning(mut value: Value, warning: Option<String>) -> Value {
|
||||
if let Some(message) = warning {
|
||||
if let Some(obj) = value.as_object_mut() {
|
||||
obj.insert("warning".to_string(), Value::String(message));
|
||||
}
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
pub(crate) fn success_payload_with_warning(backup_id: String, warning: Option<String>) -> Value {
|
||||
attach_warning(
|
||||
json!({
|
||||
"success": true,
|
||||
"message": "SQL imported successfully",
|
||||
"backupId": backup_id
|
||||
}),
|
||||
warning,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{attach_warning, post_sync_warning_from_result};
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn post_sync_warning_from_result_returns_none_on_success() {
|
||||
let warning = post_sync_warning_from_result(Ok(Ok(())));
|
||||
assert!(warning.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn post_sync_warning_from_result_returns_some_on_sync_error() {
|
||||
let warning =
|
||||
post_sync_warning_from_result(Ok(Err(crate::error::AppError::Config("boom".into()))));
|
||||
assert!(warning.is_some());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn post_sync_warning_from_result_returns_some_on_join_error() {
|
||||
let handle = tokio::spawn(async move {
|
||||
panic!("forced join error");
|
||||
});
|
||||
let join_err = handle.await.expect_err("task should panic");
|
||||
let warning = post_sync_warning_from_result(Err(join_err.to_string()));
|
||||
assert!(warning.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attach_warning_adds_warning_without_dropping_existing_fields() {
|
||||
let payload = json!({ "status": "downloaded" });
|
||||
let updated = attach_warning(payload, Some("post sync warning".to_string()));
|
||||
assert_eq!(
|
||||
updated.get("status").and_then(|v| v.as_str()),
|
||||
Some("downloaded")
|
||||
);
|
||||
assert_eq!(
|
||||
updated.get("warning").and_then(|v| v.as_str()),
|
||||
Some("post sync warning")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user