radicle: Create `Aliases` and use it in `httpd`

Signed-off-by: xphoniex <dj.2dixx@gmail.com>
This commit is contained in:
xphoniex 2023-05-27 13:46:39 +00:00 committed by Alexis Sellier
parent 0cae3c0967
commit 13bea902b2
No known key found for this signature in database
5 changed files with 53 additions and 18 deletions

View File

@ -324,7 +324,7 @@ async fn remotes_handler(State(ctx): State<Context>, Path(project): Path<Id>) ->
let storage = &ctx.profile.storage;
let repo = storage.repository(project)?;
let delegates = repo.delegates()?;
let tracking_store = &ctx.profile.tracking()?;
let aliases = &ctx.profile.aliases()?;
let remotes = repo
.remotes()?
.filter_map(|r| r.map(|r| r.1).ok())
@ -339,7 +339,7 @@ async fn remotes_handler(State(ctx): State<Context>, Path(project): Path<Id>) ->
})
.collect::<BTreeMap<String, &Oid>>();
match tracking_store.alias(&remote.id) {
match aliases.alias(&remote.id) {
Some(alias) => json!({
"id": remote.id,
"alias": alias,
@ -454,10 +454,10 @@ async fn issues_handler(
.collect::<Vec<_>>();
issues.sort_by(|(_, a, _), (_, b, _)| b.timestamp().cmp(&a.timestamp()));
let tracking_store = &ctx.profile.tracking()?;
let aliases = &ctx.profile.aliases()?;
let issues = issues
.into_iter()
.map(|(id, issue, _)| api::json::issue(id, issue, &tracking_store))
.map(|(id, issue, _)| api::json::issue(id, issue, &aliases))
.skip(page * per_page)
.take(per_page)
.collect::<Vec<_>>();
@ -574,13 +574,9 @@ async fn issue_handler(
let issue = issue::Issues::open(&repo)?
.get(&issue_id.into())?
.ok_or(Error::NotFound)?;
let tracking_store = &ctx.profile.tracking()?;
let aliases = &ctx.profile.aliases()?;
Ok::<_, Error>(Json(api::json::issue(
issue_id.into(),
issue,
&tracking_store,
)))
Ok::<_, Error>(Json(api::json::issue(issue_id.into(), issue, &aliases)))
}
#[derive(Deserialize, Serialize)]
@ -738,10 +734,10 @@ async fn patches_handler(
})
.collect::<Vec<_>>();
patches.sort_by(|(_, a, _), (_, b, _)| b.timestamp().cmp(&a.timestamp()));
let tracking_store = &ctx.profile.tracking()?;
let aliases = &ctx.profile.aliases()?;
let patches = patches
.into_iter()
.map(|(id, patch, _)| api::json::patch(id, patch, &repo, &tracking_store))
.map(|(id, patch, _)| api::json::patch(id, patch, &repo, &aliases))
.skip(page * per_page)
.take(per_page)
.collect::<Vec<_>>();
@ -760,13 +756,13 @@ async fn patch_handler(
let patch = patch::Patches::open(&repo)?
.get(&patch_id.into())?
.ok_or(Error::NotFound)?;
let tracking_store = &ctx.profile.tracking()?;
let aliases = &ctx.profile.aliases()?;
Ok::<_, Error>(Json(api::json::patch(
patch_id.into(),
patch,
&repo,
&tracking_store,
&aliases,
)))
}

View File

@ -16,6 +16,7 @@ use radicle::crypto::ssh::keystore::MemorySigner;
use radicle::crypto::ssh::Keystore;
use radicle::crypto::{KeyPair, Seed, Signer};
use radicle::git::{raw as git2, RefString};
use radicle::node::address as AddressStore;
use radicle::node::routing as RoutingStore;
use radicle::node::tracking::store as TrackingStore;
use radicle::profile::Home;
@ -87,8 +88,11 @@ pub fn contributor(dir: &Path) -> Context {
fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G) -> Context {
let tracking_db = dir.join("radicle").join("node").join("tracking.db");
let routing_db = dir.join("radicle").join("node").join("routing.db");
let addresses_db = dir.join("radicle").join("node").join("addresses.db");
TrackingStore::Config::open(tracking_db).unwrap();
RoutingStore::Table::open(routing_db).unwrap();
AddressStore::Book::open(addresses_db).unwrap();
let workdir = dir.join("hello-world");

View File

@ -4,10 +4,12 @@ mod types;
pub use store::*;
pub use types::*;
use crate::node::Address;
use cyphernet::addr::HostName;
use std::net;
use cyphernet::addr::HostName;
use crate::node::Address;
/// Address type.
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]

View File

@ -251,7 +251,7 @@ impl Store for Book {
}
}
impl AliasStore for &Book {
impl AliasStore for Book {
/// Retrieve `alias` of given node.
/// Calls `Self::get` under the hood.
fn alias(&self, nid: &NodeId) -> Option<String> {

View File

@ -19,8 +19,9 @@ use crate::crypto::ssh::agent::Agent;
use crate::crypto::ssh::{keystore, Keystore, Passphrase};
use crate::crypto::{PublicKey, Signer};
use crate::node;
use crate::node::{address, routing, tracking};
use crate::node::{address, routing, tracking, AliasStore};
use crate::prelude::Did;
use crate::prelude::NodeId;
use crate::storage::git::transport;
use crate::storage::git::Storage;
@ -57,6 +58,10 @@ pub enum Error {
Agent(#[from] crate::crypto::ssh::agent::Error),
#[error("profile key `{0}` is not registered with ssh-agent")]
KeyNotRegistered(PublicKey),
#[error(transparent)]
TrackingStore(#[from] node::tracking::store::Error),
#[error(transparent)]
AddressStore(#[from] node::address::Error),
}
#[derive(Debug, Clone)]
@ -152,6 +157,17 @@ impl Profile {
Ok(addresses)
}
/// Return a multi-source store for aliases.
pub fn aliases(&self) -> Result<Aliases, Error> {
let tracking = self.tracking()?;
let addresses = self.addresses()?;
Ok(Aliases {
tracking,
addresses,
})
}
/// Return the path to the keys folder.
pub fn keys(&self) -> PathBuf {
self.home.keys()
@ -168,6 +184,23 @@ impl Profile {
}
}
/// Holds multiple alias stores, and will try
/// them one by one when asking for an alias.
pub struct Aliases {
tracking: tracking::store::Config,
addresses: address::Book,
}
impl AliasStore for &Aliases {
/// Retrieve `alias` of given node.
/// First looks in `tracking.db` and then `address.db`,
fn alias(&self, nid: &NodeId) -> Option<String> {
(&&self.tracking as &dyn AliasStore)
.alias(nid)
.or_else(|| (&self.addresses as &dyn AliasStore).alias(nid))
}
}
/// Get the path to the radicle home folder.
pub fn home() -> Result<Home, io::Error> {
if let Some(home) = env::var_os(env::RAD_HOME) {