Sign COB refs after modification

This commit is contained in:
Alexis Sellier 2023-03-06 10:42:26 +01:00
parent 05d2487a47
commit 44f3984159
No known key found for this signature in database
4 changed files with 30 additions and 20 deletions

View File

@ -302,7 +302,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
t.render(); t.render();
} }
Operation::Delete { id } => { Operation::Delete { id } => {
issues.remove(&id)?; issues.remove(&id, &signer)?;
} }
} }

View File

@ -491,8 +491,8 @@ impl<'a> Issues<'a> {
} }
/// Remove an issue. /// Remove an issue.
pub fn remove(&self, id: &ObjectId) -> Result<(), store::Error> { pub fn remove<G: Signer>(&self, id: &ObjectId, signer: &G) -> Result<(), store::Error> {
self.raw.remove(id) self.raw.remove(id, signer)
} }
} }

View File

@ -84,33 +84,35 @@ pub enum Error {
HistoryType(String), HistoryType(String),
#[error("object `{1}` of type `{0}` was not found")] #[error("object `{1}` of type `{0}` was not found")]
NotFound(TypeName, ObjectId), NotFound(TypeName, ObjectId),
#[error("signed refs: {0}")]
SignRefs(#[from] storage::Error),
} }
/// Storage for collaborative objects of a specific type `T` in a single repository. /// Storage for collaborative objects of a specific type `T` in a single repository.
pub struct Store<'a, T> { pub struct Store<'a, T> {
whoami: PublicKey, whoami: PublicKey,
parent: git::Oid, parent: git::Oid,
raw: &'a storage::Repository, repo: &'a storage::Repository,
witness: PhantomData<T>, witness: PhantomData<T>,
rng: StdRng, rng: StdRng,
} }
impl<'a, T> AsRef<storage::Repository> for Store<'a, T> { impl<'a, T> AsRef<storage::Repository> for Store<'a, T> {
fn as_ref(&self) -> &storage::Repository { fn as_ref(&self) -> &storage::Repository {
self.raw self.repo
} }
} }
impl<'a, T> Store<'a, T> { impl<'a, T> Store<'a, T> {
/// Open a new generic store. /// Open a new generic store.
pub fn open(whoami: PublicKey, store: &'a storage::Repository) -> Result<Self, Error> { pub fn open(whoami: PublicKey, repo: &'a storage::Repository) -> Result<Self, Error> {
let rng = rng::std(); let rng = rng::std();
let identity = store.identity()?; let identity = repo.identity()?;
Ok(Self { Ok(Self {
parent: identity.current, parent: identity.current,
whoami, whoami,
raw: store, repo,
witness: PhantomData, witness: PhantomData,
rng, rng,
}) })
@ -145,9 +147,8 @@ where
signer: &G, signer: &G,
) -> Result<CollaborativeObject, Error> { ) -> Result<CollaborativeObject, Error> {
let changes = actions.into(); let changes = actions.into();
let obj = cob::update(
cob::update( self.repo,
self.raw,
signer, signer,
self.parent, self.parent,
signer.public_key(), signer.public_key(),
@ -158,8 +159,11 @@ where
message: message.to_owned(), message: message.to_owned(),
changes, changes,
}, },
) )?;
.map_err(Error::from)
self.repo.sign_refs(signer).map_err(Error::SignRefs)?;
Ok(obj)
} }
/// Create an object. /// Create an object.
@ -171,7 +175,7 @@ where
) -> Result<(ObjectId, T, Lamport), Error> { ) -> Result<(ObjectId, T, Lamport), Error> {
let contents = actions.into(); let contents = actions.into();
let cob = cob::create( let cob = cob::create(
self.raw, self.repo,
signer, signer,
self.parent, self.parent,
signer.public_key(), signer.public_key(),
@ -184,12 +188,14 @@ where
)?; )?;
let (object, clock) = T::from_history(cob.history())?; let (object, clock) = T::from_history(cob.history())?;
self.repo.sign_refs(signer).map_err(Error::SignRefs)?;
Ok((*cob.id(), object, clock)) Ok((*cob.id(), object, clock))
} }
/// Get an object. /// Get an object.
pub fn get(&self, id: &ObjectId) -> Result<Option<(T, Lamport)>, Error> { pub fn get(&self, id: &ObjectId) -> Result<Option<(T, Lamport)>, Error> {
let cob = cob::get(self.raw, T::type_name(), id)?; let cob = cob::get(self.repo, T::type_name(), id)?;
if let Some(cob) = cob { if let Some(cob) = cob {
if cob.manifest().history_type != HISTORY_TYPE { if cob.manifest().history_type != HISTORY_TYPE {
@ -207,7 +213,7 @@ where
pub fn all( pub fn all(
&self, &self,
) -> Result<impl Iterator<Item = Result<(ObjectId, T, Lamport), Error>>, Error> { ) -> Result<impl Iterator<Item = Result<(ObjectId, T, Lamport), Error>>, Error> {
let raw = cob::list(self.raw, T::type_name())?; let raw = cob::list(self.repo, T::type_name())?;
Ok(raw.into_iter().map(|o| { Ok(raw.into_iter().map(|o| {
let (obj, clock) = T::from_history(o.history())?; let (obj, clock) = T::from_history(o.history())?;
@ -217,14 +223,17 @@ where
/// Return objects count. /// Return objects count.
pub fn count(&self) -> Result<usize, Error> { pub fn count(&self) -> Result<usize, Error> {
let raw = cob::list(self.raw, T::type_name())?; let raw = cob::list(self.repo, T::type_name())?;
Ok(raw.len()) Ok(raw.len())
} }
/// Remove an object. /// Remove an object.
pub fn remove(&self, id: &ObjectId) -> Result<(), Error> { pub fn remove<G: Signer>(&self, id: &ObjectId, signer: &G) -> Result<(), Error> {
cob::remove(self.raw, &self.whoami, T::type_name(), id).map_err(Error::from) cob::remove(self.repo, &self.whoami, T::type_name(), id)?;
self.repo.sign_refs(signer).map_err(Error::SignRefs)?;
Ok(())
} }
} }

View File

@ -16,10 +16,11 @@ use crate::identity::{Identity, IdentityError, Project};
use crate::storage::refs; use crate::storage::refs;
use crate::storage::refs::{Refs, SignedRefs}; use crate::storage::refs::{Refs, SignedRefs};
use crate::storage::{ use crate::storage::{
Error, Inventory, ReadRepository, ReadStorage, Remote, Remotes, WriteRepository, WriteStorage, Inventory, ReadRepository, ReadStorage, Remote, Remotes, WriteRepository, WriteStorage,
}; };
pub use crate::git::*; pub use crate::git::*;
pub use crate::storage::Error;
use super::RemoteId; use super::RemoteId;