mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 13:20:42 +00:00
Add signature handling for manifests
- Implemented support for fetching, importing, and storing signature payloads during transaction creation. - Added the `Signature` struct to represent signature-related action data. - Updated `Manifest` to include and process `signatures` as part of its fields. - Enabled signature file imports with proper path resolution in `pkg6repo`.
This commit is contained in:
parent
38baf16b6f
commit
dfc24725b8
3 changed files with 91 additions and 1 deletions
|
|
@ -790,6 +790,35 @@ impl From<Action> for Transform {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, Diff)]
|
||||
#[diff(attr(
|
||||
#[derive(Debug, PartialEq)]
|
||||
))]
|
||||
pub struct Signature {
|
||||
pub value: String,
|
||||
pub algorithm: String,
|
||||
pub chain: String,
|
||||
pub chash: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
impl From<Action> for Signature {
|
||||
fn from(act: Action) -> Self {
|
||||
let mut sig = Signature::default();
|
||||
sig.value = act.payload_string;
|
||||
for prop in act.properties {
|
||||
match prop.key.as_str() {
|
||||
"algorithm" => sig.algorithm = prop.value,
|
||||
"chain" => sig.chain = prop.value,
|
||||
"chash" => sig.chash = prop.value,
|
||||
"version" => sig.version = prop.value,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
sig
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Hash, Eq, PartialEq, Debug, Default, Clone, Deserialize, Serialize, Diff)]
|
||||
#[diff(attr(
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
|
@ -827,6 +856,8 @@ pub struct Manifest {
|
|||
pub legacies: Vec<Legacy>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
pub transforms: Vec<Transform>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
pub signatures: Vec<Signature>,
|
||||
}
|
||||
|
||||
impl Manifest {
|
||||
|
|
@ -843,6 +874,7 @@ impl Manifest {
|
|||
drivers: Vec::new(),
|
||||
legacies: Vec::new(),
|
||||
transforms: Vec::new(),
|
||||
signatures: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -886,7 +918,7 @@ impl Manifest {
|
|||
self.transforms.push(act.into());
|
||||
}
|
||||
ActionKind::Signature => {
|
||||
debug!("signature action encountered, skipping for now");
|
||||
self.signatures.push(act.into());
|
||||
}
|
||||
ActionKind::Unknown { action } => {
|
||||
debug!("action {:?} not known, skipping", action);
|
||||
|
|
|
|||
|
|
@ -266,6 +266,23 @@ impl<'a, S: ReadableRepository + Sync> PackageReceiver<'a, S> {
|
|||
txn.add_file((*file).clone(), &temp_file_path)?;
|
||||
}
|
||||
|
||||
// Fetch signature payloads
|
||||
for sig in &manifest.signatures {
|
||||
if sig.value.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let digest = &sig.value;
|
||||
let temp_file_path = temp_dir.path().join(format!("sig-{}", digest));
|
||||
debug!("Fetching signature payload {} to {}", digest, temp_file_path.display());
|
||||
|
||||
self.source.fetch_payload(publisher, digest, &temp_file_path)?;
|
||||
|
||||
let mut sig_file_action = crate::actions::File::default();
|
||||
sig_file_action.path = format!("signature-{}", digest);
|
||||
txn.add_file(sig_file_action, &temp_file_path)?;
|
||||
}
|
||||
|
||||
txn.update_manifest(manifest.clone());
|
||||
txn.commit()?;
|
||||
|
||||
|
|
|
|||
|
|
@ -554,6 +554,47 @@ impl Pkg5Importer {
|
|||
}
|
||||
}
|
||||
|
||||
// Import signature files
|
||||
for signature in &manifest.signatures {
|
||||
if signature.value.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let hash = &signature.value;
|
||||
// Determine the file path in the source repository
|
||||
let first_two = &hash[0..2];
|
||||
let next_two = &hash[2..4];
|
||||
let file_path_new = file_dir.join(first_two).join(next_two).join(hash);
|
||||
let file_path_old = file_dir.join(first_two).join(hash);
|
||||
|
||||
let file_path = if file_path_new.exists() {
|
||||
file_path_new
|
||||
} else if file_path_old.exists() {
|
||||
file_path_old
|
||||
} else {
|
||||
warn!(
|
||||
"Signature file not found in source repository: {}",
|
||||
hash
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
// Use a unique name for the signature file in the proto dir
|
||||
let proto_sig_path = proto_dir.join(format!("signature-{}", hash));
|
||||
if let Some(parent) = proto_sig_path.parent() {
|
||||
fs::create_dir_all(parent).map_err(|e| Pkg6RepoError::IoError(e))?;
|
||||
}
|
||||
|
||||
fs::copy(&file_path, &proto_sig_path).map_err(|e| Pkg6RepoError::IoError(e))?;
|
||||
|
||||
// We need a FileAction to add it to the transaction
|
||||
// Even though it's a signature, FileBackend uses add_file to store payloads
|
||||
let mut sig_file_action = libips::actions::File::default();
|
||||
sig_file_action.path = format!("signature-{}", hash);
|
||||
// transaction.add_file will calculate the hash and store it in the repo's file dir
|
||||
transaction.add_file(sig_file_action, &proto_sig_path)?;
|
||||
}
|
||||
|
||||
// Update the manifest in the transaction
|
||||
transaction.update_manifest(manifest);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue