parent
1451f497c2
commit
e132a3623c
@ -0,0 +1,515 @@ |
|||||||
|
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||||
|
// All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0
|
||||||
|
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||||
|
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||||
|
// at your option. All files in the project carrying such
|
||||||
|
// notice may not be copied, modified, or distributed except
|
||||||
|
// according to those terms.
|
||||||
|
|
||||||
|
use crate::verifier::Verifier; |
||||||
|
use ng_repo::errors::VerifierError; |
||||||
|
use ng_repo::log::*; |
||||||
|
use ng_repo::object::Object; |
||||||
|
use ng_repo::repo::{BranchInfo, Repo}; |
||||||
|
use ng_repo::store::Store; |
||||||
|
use ng_repo::types::*; |
||||||
|
use std::collections::HashMap; |
||||||
|
use std::sync::Arc; |
||||||
|
|
||||||
|
pub trait CommitVerifier { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError>; |
||||||
|
} |
||||||
|
|
||||||
|
fn list_dep_chain_until( |
||||||
|
start: ObjectRef, |
||||||
|
end: &ObjectId, |
||||||
|
store: &Store, |
||||||
|
) -> Result<Vec<Commit>, VerifierError> { |
||||||
|
let mut res = vec![]; |
||||||
|
let mut pos = start; |
||||||
|
loop { |
||||||
|
let pos_id = pos.id.clone(); |
||||||
|
if pos_id == *end { |
||||||
|
break; |
||||||
|
} |
||||||
|
let commit = Commit::load(pos, &store, true)?; |
||||||
|
let deps = commit.deps(); |
||||||
|
if deps.len() != 1 { |
||||||
|
return Err(VerifierError::MalformedSyncSignatureDeps); |
||||||
|
} |
||||||
|
res.push(commit); |
||||||
|
pos = deps[0].clone(); |
||||||
|
} |
||||||
|
res.reverse(); |
||||||
|
|
||||||
|
Ok(res) |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RootBranch { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
match self { |
||||||
|
RootBranch::V0(root_branch) => { |
||||||
|
let repository_commit = Commit::load(root_branch.repo.clone(), &store, true)?; |
||||||
|
let repository = match repository_commit |
||||||
|
.body() |
||||||
|
.ok_or(VerifierError::CommitBodyNotFound)? |
||||||
|
{ |
||||||
|
CommitBody::V0(CommitBodyV0::Repository(r)) => r, |
||||||
|
_ => return Err(VerifierError::InvalidRepositoryCommit), |
||||||
|
}; |
||||||
|
//TODO: deal with quorum_type (verify signature)
|
||||||
|
|
||||||
|
let user_priv = verifier.user_privkey(); |
||||||
|
let user_id = user_priv.to_pub(); |
||||||
|
let repo_write_cap_secret = if store.is_private() { |
||||||
|
Some(SymKey::nil()) |
||||||
|
} else if let Some(pos) = root_branch.owners.iter().position(|&o| o == user_id) { |
||||||
|
let cryptobox = &root_branch.owners_write_cap[pos]; |
||||||
|
Some(RootBranch::decrypt_write_cap(user_priv, cryptobox)?) |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
let topic_priv_key = if let Some(rwcs) = repo_write_cap_secret.as_ref() { |
||||||
|
Branch::decrypt_branch_write_cap_secret( |
||||||
|
root_branch.topic_privkey.clone(), |
||||||
|
root_branch.topic.clone(), |
||||||
|
root_branch.id.clone(), |
||||||
|
rwcs, |
||||||
|
) |
||||||
|
.map_or(None, |k| Some(k)) |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
let reference = commit.reference().unwrap(); |
||||||
|
let root_branch = BranchInfo { |
||||||
|
id: root_branch.id.clone(), |
||||||
|
branch_type: BranchType::Root, |
||||||
|
topic: root_branch.topic, |
||||||
|
topic_priv_key, |
||||||
|
read_cap: reference.clone(), |
||||||
|
current_heads: vec![reference.clone()], |
||||||
|
}; |
||||||
|
let id = root_branch.id; |
||||||
|
let branches = vec![(root_branch.id, root_branch)]; |
||||||
|
let repo = Repo { |
||||||
|
id, |
||||||
|
repo_def: repository.clone(), |
||||||
|
signer: None, //TO BE ADDED LATER when AddSignerCap commit is found
|
||||||
|
members: HashMap::new(), |
||||||
|
store: Arc::clone(&store), |
||||||
|
read_cap: Some(reference), |
||||||
|
write_cap: repo_write_cap_secret, |
||||||
|
branches: branches.into_iter().collect(), |
||||||
|
opened_branches: HashMap::new(), |
||||||
|
}; |
||||||
|
let _repo_ref = verifier.add_repo_and_save(repo); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for Branch { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
match self { |
||||||
|
Branch::V0(branch) => { |
||||||
|
//TODO: deal with root_branch_readcap_id (the epoch)
|
||||||
|
|
||||||
|
//TODO: deal with quorum_type (verify signature)
|
||||||
|
|
||||||
|
let repository_commit = Commit::load(branch.repo.clone(), &store, true)?; |
||||||
|
|
||||||
|
let repository = match repository_commit |
||||||
|
.body() |
||||||
|
.ok_or(VerifierError::CommitBodyNotFound)? |
||||||
|
{ |
||||||
|
CommitBody::V0(CommitBodyV0::Repository(r)) => r, |
||||||
|
_ => return Err(VerifierError::InvalidRepositoryCommit), |
||||||
|
}; |
||||||
|
|
||||||
|
// check that the repository exists
|
||||||
|
let repo = verifier.get_repo_mut(repository.id(), store.get_store_repo())?; |
||||||
|
|
||||||
|
let topic_priv_key = if let Some(rwcs) = repo.write_cap.as_ref() { |
||||||
|
Branch::decrypt_branch_write_cap_secret( |
||||||
|
branch.topic_privkey.clone(), |
||||||
|
branch.topic.clone(), |
||||||
|
branch.id.clone(), |
||||||
|
rwcs, |
||||||
|
) |
||||||
|
.map_or(None, |k| Some(k)) |
||||||
|
} else { |
||||||
|
None |
||||||
|
}; |
||||||
|
let reference = commit.reference().unwrap(); |
||||||
|
|
||||||
|
let branch_info = repo.branch_mut(&branch.id)?; |
||||||
|
if branch_info.read_cap != reference { |
||||||
|
return Err(VerifierError::InvalidBranch); |
||||||
|
} |
||||||
|
branch_info.topic_priv_key = topic_priv_key; |
||||||
|
branch_info.current_heads = vec![reference]; |
||||||
|
|
||||||
|
verifier.update_branch(&repository.id(), &branch.id, store.get_store_repo())?; |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for SyncSignature { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
match self { |
||||||
|
SyncSignature::V0(signature_ref) => { |
||||||
|
let sign = Object::load_ref(signature_ref, &store)?; |
||||||
|
match sign.content_v0()? { |
||||||
|
ObjectContentV0::Signature(sig) => { |
||||||
|
//TODO: verify signature
|
||||||
|
} |
||||||
|
_ => return Err(VerifierError::InvalidSignatureObject), |
||||||
|
} |
||||||
|
// process each deps
|
||||||
|
let acks = commit.acks(); |
||||||
|
if acks.len() != 1 { |
||||||
|
return Err(VerifierError::MalformedSyncSignatureAcks); |
||||||
|
} |
||||||
|
let ack = &acks[0]; |
||||||
|
let deps = commit.deps(); |
||||||
|
if deps.len() != 1 { |
||||||
|
return Err(VerifierError::MalformedSyncSignatureDeps); |
||||||
|
} |
||||||
|
let commits = list_dep_chain_until(deps[0].clone(), &ack.id, &store)?; |
||||||
|
for commit in commits { |
||||||
|
verifier.verify_commit(commit, Arc::clone(&store))?; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddBranch { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
match self { |
||||||
|
AddBranch::V0(v0) => { |
||||||
|
if v0.branch_type == BranchType::Root { |
||||||
|
return Err(VerifierError::InvalidBranch); |
||||||
|
} |
||||||
|
// let _ = verifier.topics.insert(
|
||||||
|
// (store.inner_overlay(), v0.topic_id),
|
||||||
|
// (*commit.branch(), v0.branch_id),
|
||||||
|
// );
|
||||||
|
|
||||||
|
let branch_info = BranchInfo { |
||||||
|
id: v0.branch_id, |
||||||
|
branch_type: v0.branch_type.clone(), |
||||||
|
topic: v0.topic_id, |
||||||
|
topic_priv_key: None, |
||||||
|
read_cap: v0.branch_read_cap.clone(), |
||||||
|
current_heads: vec![], |
||||||
|
}; |
||||||
|
|
||||||
|
verifier.add_branch_and_save( |
||||||
|
commit.branch(), |
||||||
|
branch_info, |
||||||
|
store.get_store_repo(), |
||||||
|
)?; |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for Repository { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
// left empty intentionally
|
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for StoreUpdate { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
verifier.new_store_from_update(self) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddSignerCap { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
match self { |
||||||
|
AddSignerCap::V0(v0) => verifier.update_signer_cap(&v0.cap), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddMember { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveMember { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddPermission { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemovePermission { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveBranch { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddName { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveName { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for () { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for Snapshot { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddFile { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveFile { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for Compact { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AsyncSignature { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RefreshReadCap { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RefreshWriteCap { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddRepo { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveRepo { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for AddLink { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveLink { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for RemoveSignerCap { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl CommitVerifier for WalletUpdate { |
||||||
|
fn verify( |
||||||
|
&self, |
||||||
|
commit: &Commit, |
||||||
|
verifier: &mut Verifier, |
||||||
|
store: Arc<Store>, |
||||||
|
) -> Result<(), VerifierError> { |
||||||
|
Ok(()) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue