mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-07-20 23:12:48 +00:00
fix(api): dont verify signature or DID during importRepo
This commit is contained in:
@@ -77,27 +77,6 @@ pub async fn import_repo(
|
||||
blocks.len(),
|
||||
root
|
||||
);
|
||||
let Some(root_block) = blocks.get(&root) else {
|
||||
return Err(ApiError::InvalidRequest(
|
||||
"Root block not found in CAR file".into(),
|
||||
));
|
||||
};
|
||||
let commit_did: Did = match jacquard_repo::commit::Commit::from_cbor(root_block) {
|
||||
Ok(commit) => commit
|
||||
.did()
|
||||
.as_str()
|
||||
.parse()
|
||||
.map_err(|_| ApiError::InvalidRequest("Commit contains invalid DID".into()))?,
|
||||
Err(e) => {
|
||||
return Err(ApiError::InvalidRequest(format!("Invalid commit: {}", e)));
|
||||
}
|
||||
};
|
||||
if commit_did != *did {
|
||||
return Err(ApiError::InvalidRepo(format!(
|
||||
"CAR file is for DID {} but you are authenticated as {}",
|
||||
commit_did, did
|
||||
)));
|
||||
}
|
||||
let skip_verification = std::env::var("SKIP_IMPORT_VERIFICATION")
|
||||
.ok()
|
||||
.map(|v| v == "true" || v == "1")
|
||||
@@ -108,11 +87,13 @@ pub async fn import_repo(
|
||||
});
|
||||
let is_migration = user.inbound_migration && user.deactivated_at.is_some();
|
||||
if skip_verification {
|
||||
warn!("Skipping all CAR verification for import (SKIP_IMPORT_VERIFICATION=true)");
|
||||
} else if is_migration {
|
||||
debug!("Verifying CAR file structure for migration (skipping signature verification)");
|
||||
warn!("Skipping all CAR verification for repo import (SKIP_IMPORT_VERIFICATION=true)");
|
||||
} else {
|
||||
debug!(
|
||||
"Verifying CAR file structure for repo import (skipping signature and DID verification)"
|
||||
);
|
||||
let verifier = CarVerifier::new();
|
||||
match verifier.verify_car_structure_only(did, &root, &blocks) {
|
||||
match verifier.verify_car_structure_only(&root, &blocks) {
|
||||
Ok(verified) => {
|
||||
debug!(
|
||||
"CAR structure verification successful: rev={}, data_cid={}",
|
||||
@@ -142,56 +123,6 @@ pub async fn import_repo(
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug!("Verifying CAR file signature and structure for DID {}", did);
|
||||
let verifier = CarVerifier::new();
|
||||
match verifier.verify_car(did, &root, &blocks).await {
|
||||
Ok(verified) => {
|
||||
debug!(
|
||||
"CAR verification successful: rev={}, data_cid={}",
|
||||
verified.rev, verified.data_cid
|
||||
);
|
||||
}
|
||||
Err(tranquil_pds::sync::verify::VerifyError::DidMismatch {
|
||||
commit_did,
|
||||
expected_did,
|
||||
}) => {
|
||||
return Err(ApiError::InvalidRepo(format!(
|
||||
"CAR file is for DID {} but you are authenticated as {}",
|
||||
commit_did, expected_did
|
||||
)));
|
||||
}
|
||||
Err(tranquil_pds::sync::verify::VerifyError::InvalidSignature) => {
|
||||
return Err(ApiError::InvalidRequest(
|
||||
"CAR file commit signature verification failed".into(),
|
||||
));
|
||||
}
|
||||
Err(tranquil_pds::sync::verify::VerifyError::DidResolutionFailed(msg)) => {
|
||||
warn!("DID resolution failed during import verification: {}", msg);
|
||||
return Err(ApiError::InvalidRequest(format!(
|
||||
"Failed to verify DID: {}",
|
||||
msg
|
||||
)));
|
||||
}
|
||||
Err(tranquil_pds::sync::verify::VerifyError::NoSigningKey) => {
|
||||
return Err(ApiError::InvalidRequest(
|
||||
"DID document does not contain a signing key".into(),
|
||||
));
|
||||
}
|
||||
Err(tranquil_pds::sync::verify::VerifyError::MstValidationFailed(msg)) => {
|
||||
return Err(ApiError::InvalidRequest(format!(
|
||||
"MST validation failed: {}",
|
||||
msg
|
||||
)));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("CAR verification error: {:?}", e);
|
||||
return Err(ApiError::InvalidRequest(format!(
|
||||
"CAR verification failed: {}",
|
||||
e
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
let max_blocks = tranquil_config::get().import.max_blocks as usize;
|
||||
let _write_lock = state.repo_write_locks.lock(user_id).await;
|
||||
|
||||
@@ -92,30 +92,20 @@ impl CarVerifier {
|
||||
|
||||
pub fn verify_car_structure_only(
|
||||
&self,
|
||||
expected_did: &Did,
|
||||
root_cid: &Cid,
|
||||
blocks: &HashMap<Cid, Bytes>,
|
||||
) -> Result<VerifiedCar, VerifyError> {
|
||||
) -> Result<StructureVerifiedCar, VerifyError> {
|
||||
let root_block = blocks
|
||||
.get(root_cid)
|
||||
.ok_or_else(|| VerifyError::BlockNotFound(root_cid.to_string()))?;
|
||||
let commit =
|
||||
Commit::from_cbor(root_block).map_err(|e| VerifyError::InvalidCommit(e.to_string()))?;
|
||||
let commit_did = commit.did().as_str();
|
||||
if commit_did != expected_did.as_str() {
|
||||
return Err(VerifyError::DidMismatch {
|
||||
commit_did: commit_did.to_string(),
|
||||
expected_did: expected_did.to_string(),
|
||||
});
|
||||
}
|
||||
let commit_did = commit.did().to_string().into();
|
||||
let data_cid = commit.data();
|
||||
self.verify_mst_structure(data_cid, blocks)?;
|
||||
debug!(
|
||||
"MST structure verified for DID {} (signature verification skipped for migration)",
|
||||
expected_did
|
||||
);
|
||||
Ok(VerifiedCar {
|
||||
did: expected_did.clone(),
|
||||
debug!("MST structure verified for commit: {:?}", commit);
|
||||
Ok(StructureVerifiedCar {
|
||||
did: commit_did,
|
||||
rev: commit.rev().to_string(),
|
||||
data_cid: *data_cid,
|
||||
prev: commit.prev().cloned(),
|
||||
@@ -289,6 +279,14 @@ impl CarVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StructureVerifiedCar {
|
||||
pub did: Did,
|
||||
pub rev: String,
|
||||
pub data_cid: Cid,
|
||||
pub prev: Option<Cid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VerifiedCar {
|
||||
pub did: Did,
|
||||
|
||||
@@ -73,7 +73,7 @@ fn write_varint(buf: &mut Vec<u8>, mut value: u64) {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_import_rejects_car_for_different_user() {
|
||||
async fn test_import_doesnt_reject_car_for_different_user() {
|
||||
let client = client();
|
||||
let (token_a, _did_a) = create_account_and_login(&client).await;
|
||||
let (_token_b, did_b) = create_account_and_login(&client).await;
|
||||
@@ -99,15 +99,9 @@ async fn test_import_rejects_car_for_different_user() {
|
||||
.send()
|
||||
.await
|
||||
.expect("Import failed");
|
||||
assert_eq!(import_res.status(), StatusCode::FORBIDDEN);
|
||||
assert_eq!(import_res.status(), StatusCode::OK);
|
||||
let body: serde_json::Value = import_res.json().await.unwrap();
|
||||
assert!(
|
||||
body["error"] == "InvalidRepo"
|
||||
|| body["error"] == "InvalidRequest"
|
||||
|| body["error"] == "DidMismatch",
|
||||
"Expected InvalidRepo, DidMismatch, or InvalidRequest error, got: {:?}",
|
||||
body
|
||||
);
|
||||
assert!(body.is_object() && body.as_object().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user