Implement `public_references` helper function
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
parent
111480cd6e
commit
e6fd85f249
|
|
@ -233,32 +233,8 @@ impl Repository {
|
||||||
})
|
})
|
||||||
.collect::<Result<_, VerifyError>>()?;
|
.collect::<Result<_, VerifyError>>()?;
|
||||||
|
|
||||||
// TODO: We could create a higher level `references` method that skips
|
for entry in self.public_references()? {
|
||||||
// canonical/unverifiable refs.
|
let (remote_id, refname, oid) = entry?;
|
||||||
for r in self.backend.references()? {
|
|
||||||
let r = r?;
|
|
||||||
|
|
||||||
let name = r.name().ok_or(VerifyError::InvalidRef)?;
|
|
||||||
let oid = if let Some(oid) = r.target() {
|
|
||||||
oid
|
|
||||||
} else {
|
|
||||||
// Ignore symbolic refs, eg. `HEAD`.
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let (remote_id, refname) = git::parse_ref::<RemoteId>(name)?;
|
|
||||||
let remote_id = if let Some(remote_id) = remote_id {
|
|
||||||
remote_id
|
|
||||||
} else {
|
|
||||||
// Ignore refs that aren't part of a namespace, eg. canonical refs.
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
if refname == *refs::SIGNATURE_REF {
|
|
||||||
// Ignore the signed-refs reference, as this is what we're verifying.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let remote = remotes
|
let remote = remotes
|
||||||
.get_mut(&remote_id)
|
.get_mut(&remote_id)
|
||||||
.ok_or(VerifyError::InvalidRemote(remote_id))?;
|
.ok_or(VerifyError::InvalidRemote(remote_id))?;
|
||||||
|
|
@ -267,8 +243,8 @@ impl Repository {
|
||||||
.remove(&refname)
|
.remove(&refname)
|
||||||
.ok_or_else(|| VerifyError::UnknownRef(remote_id, refname.clone()))?;
|
.ok_or_else(|| VerifyError::UnknownRef(remote_id, refname.clone()))?;
|
||||||
|
|
||||||
if Oid::from(oid) != signed_oid {
|
if oid != signed_oid {
|
||||||
return Err(VerifyError::InvalidRefTarget(remote_id, refname, oid));
|
return Err(VerifyError::InvalidRefTarget(remote_id, refname, *oid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,6 +367,35 @@ impl Repository {
|
||||||
);
|
);
|
||||||
Ok(remotes)
|
Ok(remotes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return all references that are public, ie. that are replicated, verified and signed.
|
||||||
|
fn public_references(
|
||||||
|
&self,
|
||||||
|
) -> Result<impl Iterator<Item = Result<(RemoteId, Qualified, Oid), refs::Error>>, git2::Error>
|
||||||
|
{
|
||||||
|
let refs = self.backend.references_glob("refs/namespaces/*")?;
|
||||||
|
let refs = refs
|
||||||
|
.map(|reference| {
|
||||||
|
let r = reference?;
|
||||||
|
let name = r.name().ok_or(refs::Error::InvalidRef)?;
|
||||||
|
let (namespace, refname) = git::parse_ref_namespaced::<RemoteId>(name)?;
|
||||||
|
let oid = if let Some(oid) = r.target() {
|
||||||
|
oid
|
||||||
|
} else {
|
||||||
|
// Ignore symbolic refs, eg. `HEAD`.
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
if refname == *refs::SIGNATURE_REF {
|
||||||
|
// Ignore the signed-refs reference, as this is what we're verifying.
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
Ok(Some((namespace, refname.to_owned(), oid.into())))
|
||||||
|
})
|
||||||
|
.filter_map(Result::transpose);
|
||||||
|
|
||||||
|
Ok(refs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadRepository for Repository {
|
impl ReadRepository for Repository {
|
||||||
|
|
@ -852,6 +857,26 @@ mod tests {
|
||||||
assert_eq!(bob_master.target().unwrap(), alice_head);
|
assert_eq!(bob_master.target().unwrap(), alice_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_public_references() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let signer = MockSigner::default();
|
||||||
|
let storage = Storage::open(tmp.path().join("storage")).unwrap();
|
||||||
|
let (id, _, _, _) =
|
||||||
|
fixtures::project(tmp.path().join("project"), &storage, &signer).unwrap();
|
||||||
|
let proj = storage.repository(id).unwrap();
|
||||||
|
|
||||||
|
let mut refs = proj
|
||||||
|
.public_references()
|
||||||
|
.unwrap()
|
||||||
|
.map(|r| r.unwrap())
|
||||||
|
.map(|(_, r, _)| r.to_string())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
refs.sort();
|
||||||
|
|
||||||
|
assert_eq!(refs, vec!["refs/heads/master", "refs/heads/radicle/id"]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_upload_pack() {
|
fn test_upload_pack() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue