Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: Create `Aliases` and use it in `httpd`
xphoniex committed 2 years ago
commit 13bea902b231aec910cd49453d5b8d6582971294
parent 0cae3c0967bd670764dd42d38e25f23485f53bf1
5 files changed +53 -18
modified radicle-httpd/src/api/v1/projects.rs
@@ -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,
    )))
}

modified radicle-httpd/src/test.rs
@@ -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");

modified radicle/src/node/address.rs
@@ -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)]
modified radicle/src/node/address/store.rs
@@ -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> {
modified radicle/src/profile.rs
@@ -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) {