use crate::codec::Encoder;
use crate::command::Command;
use crate::crypto::Verifier;
use crate::domain::hash::Hash;
use crate::domain::object::Object;
use crate::error::VctrlError;
use crate::hashing::Hasher;
use crate::storage::traits::{ObjectStore, RefStore};
pub struct VerifyCommit {
pub commit_hash: Hash,
pub verifier: Box<dyn Verifier>,
pub encoder: Box<dyn Encoder>,
pub hasher: Box<dyn Hasher>,
}
impl Command for VerifyCommit {
type Output = bool;
fn execute(
&self,
store: &mut dyn ObjectStore,
_refs: &mut dyn RefStore,
) -> Result<bool, VctrlError> {
let commit = match store.get(&self.commit_hash)? {
Some(Object::Commit(c)) => *c,
_ => return Err(VctrlError::NotFound("commit not found".into())),
};
let sig_bytes = match &commit.signature {
Some(s) => s.clone(),
None => return Ok(false),
};
let pre_sig_commit = crate::domain::commit::Commit {
tree: commit.tree,
parents: commit.parents.clone(),
author: commit.author.clone(),
committer: commit.committer.clone(),
timestamp: commit.timestamp,
message: commit.message.clone(),
signature: None,
headers: commit.headers.clone(),
};
let mut buf = Vec::new();
self.encoder.encode_commit(&pre_sig_commit, &mut buf)?;
let pre_sig_hash = self.hasher.hash_commit_encoded(&buf);
self.verifier.verify(pre_sig_hash.as_bytes(), &sig_bytes)
}
}