mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 21:30:41 +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)]
|
#[derive(Hash, Eq, PartialEq, Debug, Default, Clone, Deserialize, Serialize, Diff)]
|
||||||
#[diff(attr(
|
#[diff(attr(
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
|
@ -827,6 +856,8 @@ pub struct Manifest {
|
||||||
pub legacies: Vec<Legacy>,
|
pub legacies: Vec<Legacy>,
|
||||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||||
pub transforms: Vec<Transform>,
|
pub transforms: Vec<Transform>,
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||||
|
pub signatures: Vec<Signature>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Manifest {
|
impl Manifest {
|
||||||
|
|
@ -843,6 +874,7 @@ impl Manifest {
|
||||||
drivers: Vec::new(),
|
drivers: Vec::new(),
|
||||||
legacies: Vec::new(),
|
legacies: Vec::new(),
|
||||||
transforms: Vec::new(),
|
transforms: Vec::new(),
|
||||||
|
signatures: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -886,7 +918,7 @@ impl Manifest {
|
||||||
self.transforms.push(act.into());
|
self.transforms.push(act.into());
|
||||||
}
|
}
|
||||||
ActionKind::Signature => {
|
ActionKind::Signature => {
|
||||||
debug!("signature action encountered, skipping for now");
|
self.signatures.push(act.into());
|
||||||
}
|
}
|
||||||
ActionKind::Unknown { action } => {
|
ActionKind::Unknown { action } => {
|
||||||
debug!("action {:?} not known, skipping", 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)?;
|
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.update_manifest(manifest.clone());
|
||||||
txn.commit()?;
|
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
|
// Update the manifest in the transaction
|
||||||
transaction.update_manifest(manifest);
|
transaction.update_manifest(manifest);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue