Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: move service tracking config to radicle::node
Fintan Halpenny committed 2 years ago
commit ef6ae0fa84b912c2cbfffae93d0b24269be3a860
parent c06b2258779b78a2317084b8da541cfd0a64d6f0
4 files changed +168 -167
modified radicle-node/src/service.rs
@@ -6,7 +6,6 @@ pub mod io;
pub mod limitter;
pub mod message;
pub mod session;
-
pub mod tracking;

use std::collections::hash_map::Entry;
use std::collections::{BTreeMap, HashMap, HashSet};
@@ -23,6 +22,7 @@ use nonempty::NonEmpty;
use radicle::node::address;
use radicle::node::address::{AddressBook, KnownAddress};
use radicle::node::config::PeerConfig;
+
pub use radicle::node::tracking::config as tracking;
use radicle::node::ConnectOptions;
use radicle::storage::RepositoryError;

deleted radicle-node/src/service/tracking.rs
@@ -1,166 +0,0 @@
-
use core::fmt;
-
use std::collections::HashSet;
-
use std::ops;
-

-
use log::error;
-
use thiserror::Error;
-

-
use radicle::crypto::PublicKey;
-
use radicle::storage::{Namespaces, ReadRepository as _, ReadStorage, RepositoryError};
-

-
use crate::prelude::Id;
-
use crate::service::NodeId;
-

-
pub use crate::node::tracking::store;
-
pub use crate::node::tracking::store::Config as Store;
-
pub use crate::node::tracking::store::Error;
-
pub use crate::node::tracking::{Alias, Node, Policy, Repo, Scope};
-

-
#[derive(Debug, Error)]
-
pub enum NamespacesError {
-
    #[error("Failed to find tracking policy for {rid}")]
-
    FailedPolicy {
-
        rid: Id,
-
        #[source]
-
        err: Error,
-
    },
-
    #[error("Cannot fetch {rid} as it is not tracked")]
-
    BlockedPolicy { rid: Id },
-
    #[error("Failed to get tracking nodes for {rid}")]
-
    FailedNodes {
-
        rid: Id,
-
        #[source]
-
        err: Error,
-
    },
-
    #[error("Failed to get delegates for {rid}")]
-
    FailedDelegates {
-
        rid: Id,
-
        #[source]
-
        err: RepositoryError,
-
    },
-
    #[error("Could not find any trusted nodes for {rid}")]
-
    NoTrusted { rid: Id },
-
}
-

-
/// Tracking configuration.
-
pub struct Config<T> {
-
    /// Default policy, if a policy for a specific node or repository was not found.
-
    policy: Policy,
-
    /// Default scope, if a scope for a specific repository was not found.
-
    scope: Scope,
-
    /// Underlying configuration store.
-
    store: Store<T>,
-
}
-

-
// N.b. deriving `Debug` will require `T: Debug` so we manually
-
// implement it here.
-
impl<T> fmt::Debug for Config<T> {
-
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-
        f.debug_struct("Config")
-
            .field("policy", &self.policy)
-
            .field("scope", &self.scope)
-
            .field("store", &self.store)
-
            .finish()
-
    }
-
}
-

-
impl<T> Config<T> {
-
    /// Create a new tracking configuration.
-
    pub fn new(policy: Policy, scope: Scope, store: Store<T>) -> Self {
-
        Self {
-
            policy,
-
            scope,
-
            store,
-
        }
-
    }
-

-
    /// Check if a repository is tracked.
-
    pub fn is_repo_tracked(&self, id: &Id) -> Result<bool, Error> {
-
        self.repo_policy(id)
-
            .map(|entry| entry.policy == Policy::Track)
-
    }
-

-
    /// Check if a node is tracked.
-
    pub fn is_node_tracked(&self, id: &NodeId) -> Result<bool, Error> {
-
        self.node_policy(id)
-
            .map(|entry| entry.policy == Policy::Track)
-
    }
-

-
    /// Get a node's tracking information.
-
    /// Returns the default policy if the node isn't found.
-
    pub fn node_policy(&self, id: &NodeId) -> Result<Node, Error> {
-
        Ok(self.store.node_policy(id)?.unwrap_or(Node {
-
            id: *id,
-
            alias: None,
-
            policy: self.policy,
-
        }))
-
    }
-

-
    /// Get a repository's tracking information.
-
    /// Returns the default policy if the repo isn't found.
-
    pub fn repo_policy(&self, id: &Id) -> Result<Repo, Error> {
-
        Ok(self.store.repo_policy(id)?.unwrap_or(Repo {
-
            id: *id,
-
            scope: self.scope,
-
            policy: self.policy,
-
        }))
-
    }
-

-
    pub fn namespaces_for<S>(&self, storage: &S, rid: &Id) -> Result<Namespaces, NamespacesError>
-
    where
-
        S: ReadStorage,
-
    {
-
        use NamespacesError::*;
-

-
        let entry = self
-
            .repo_policy(rid)
-
            .map_err(|err| FailedPolicy { rid: *rid, err })?;
-
        match entry.policy {
-
            Policy::Block => {
-
                error!(target: "service", "Attempted to fetch untracked repo {rid}");
-
                Err(NamespacesError::BlockedPolicy { rid: *rid })
-
            }
-
            Policy::Track => match entry.scope {
-
                Scope::All => Ok(Namespaces::All),
-
                Scope::Trusted => {
-
                    let nodes = self
-
                        .node_policies()
-
                        .map_err(|err| FailedNodes { rid: *rid, err })?;
-
                    let mut trusted: HashSet<_> = nodes
-
                        .filter_map(|node| (node.policy == Policy::Track).then_some(node.id))
-
                        .collect();
-

-
                    if let Ok(repo) = storage.repository(*rid) {
-
                        let delegates = repo
-
                            .delegates()
-
                            .map_err(|err| FailedDelegates { rid: *rid, err })?
-
                            .map(PublicKey::from);
-
                        trusted.extend(delegates);
-
                    };
-
                    if trusted.is_empty() {
-
                        // Nb. returning All here because the
-
                        // fetching logic will correctly determine
-
                        // trusted and delegate remotes.
-
                        Ok(Namespaces::All)
-
                    } else {
-
                        Ok(Namespaces::Trusted(trusted))
-
                    }
-
                }
-
            },
-
        }
-
    }
-
}
-

-
impl<T> ops::Deref for Config<T> {
-
    type Target = Store<T>;
-

-
    fn deref(&self) -> &Self::Target {
-
        &self.store
-
    }
-
}
-

-
impl<T> ops::DerefMut for Config<T> {
-
    fn deref_mut(&mut self) -> &mut Self::Target {
-
        &mut self.store
-
    }
-
}
modified radicle/src/node/tracking.rs
@@ -1,3 +1,4 @@
+
pub mod config;
pub mod store;

use std::fmt;
added radicle/src/node/tracking/config.rs
@@ -0,0 +1,166 @@
+
use core::fmt;
+
use std::collections::HashSet;
+
use std::ops;
+

+
use log::error;
+
use thiserror::Error;
+

+
use crate::crypto::PublicKey;
+
use crate::prelude::{Id, NodeId};
+
use crate::storage::{Namespaces, ReadRepository as _, ReadStorage, RepositoryError};
+

+
pub use crate::node::tracking::store;
+
pub use crate::node::tracking::store::Config as Store;
+
pub use crate::node::tracking::store::Error;
+
pub use crate::node::tracking::{Alias, Node, Policy, Repo, Scope};
+

+
#[derive(Debug, Error)]
+
pub enum NamespacesError {
+
    #[error("Failed to find tracking policy for {rid}")]
+
    FailedPolicy {
+
        rid: Id,
+
        #[source]
+
        err: Error,
+
    },
+
    #[error("Cannot fetch {rid} as it is not tracked")]
+
    BlockedPolicy { rid: Id },
+
    #[error("Failed to get tracking nodes for {rid}")]
+
    FailedNodes {
+
        rid: Id,
+
        #[source]
+
        err: Error,
+
    },
+
    #[error("Failed to get delegates for {rid}")]
+
    FailedDelegates {
+
        rid: Id,
+
        #[source]
+
        err: RepositoryError,
+
    },
+
    #[error(transparent)]
+
    Git(#[from] crate::git::raw::Error),
+
    #[error("Could not find any trusted nodes for {rid}")]
+
    NoTrusted { rid: Id },
+
}
+

+
/// Tracking configuration.
+
pub struct Config<T> {
+
    /// Default policy, if a policy for a specific node or repository was not found.
+
    policy: Policy,
+
    /// Default scope, if a scope for a specific repository was not found.
+
    scope: Scope,
+
    /// Underlying configuration store.
+
    store: Store<T>,
+
}
+

+
// N.b. deriving `Debug` will require `T: Debug` so we manually
+
// implement it here.
+
impl<T> fmt::Debug for Config<T> {
+
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+
        f.debug_struct("Config")
+
            .field("policy", &self.policy)
+
            .field("scope", &self.scope)
+
            .field("store", &self.store)
+
            .finish()
+
    }
+
}
+

+
impl<T> Config<T> {
+
    /// Create a new tracking configuration.
+
    pub fn new(policy: Policy, scope: Scope, store: Store<T>) -> Self {
+
        Self {
+
            policy,
+
            scope,
+
            store,
+
        }
+
    }
+

+
    /// Check if a repository is tracked.
+
    pub fn is_repo_tracked(&self, id: &Id) -> Result<bool, Error> {
+
        self.repo_policy(id)
+
            .map(|entry| entry.policy == Policy::Track)
+
    }
+

+
    /// Check if a node is tracked.
+
    pub fn is_node_tracked(&self, id: &NodeId) -> Result<bool, Error> {
+
        self.node_policy(id)
+
            .map(|entry| entry.policy == Policy::Track)
+
    }
+

+
    /// Get a node's tracking information.
+
    /// Returns the default policy if the node isn't found.
+
    pub fn node_policy(&self, id: &NodeId) -> Result<Node, Error> {
+
        Ok(self.store.node_policy(id)?.unwrap_or(Node {
+
            id: *id,
+
            alias: None,
+
            policy: self.policy,
+
        }))
+
    }
+

+
    /// Get a repository's tracking information.
+
    /// Returns the default policy if the repo isn't found.
+
    pub fn repo_policy(&self, id: &Id) -> Result<Repo, Error> {
+
        Ok(self.store.repo_policy(id)?.unwrap_or(Repo {
+
            id: *id,
+
            scope: self.scope,
+
            policy: self.policy,
+
        }))
+
    }
+

+
    pub fn namespaces_for<S>(&self, storage: &S, rid: &Id) -> Result<Namespaces, NamespacesError>
+
    where
+
        S: ReadStorage,
+
    {
+
        use NamespacesError::*;
+

+
        let entry = self
+
            .repo_policy(rid)
+
            .map_err(|err| FailedPolicy { rid: *rid, err })?;
+
        match entry.policy {
+
            Policy::Block => {
+
                error!(target: "service", "Attempted to fetch untracked repo {rid}");
+
                Err(NamespacesError::BlockedPolicy { rid: *rid })
+
            }
+
            Policy::Track => match entry.scope {
+
                Scope::All => Ok(Namespaces::All),
+
                Scope::Trusted => {
+
                    let nodes = self
+
                        .node_policies()
+
                        .map_err(|err| FailedNodes { rid: *rid, err })?;
+
                    let mut trusted: HashSet<_> = nodes
+
                        .filter_map(|node| (node.policy == Policy::Track).then_some(node.id))
+
                        .collect();
+

+
                    if let Ok(repo) = storage.repository(*rid) {
+
                        let delegates = repo
+
                            .delegates()
+
                            .map_err(|err| FailedDelegates { rid: *rid, err })?
+
                            .map(PublicKey::from);
+
                        trusted.extend(delegates);
+
                    };
+
                    if trusted.is_empty() {
+
                        // Nb. returning All here because the
+
                        // fetching logic will correctly determine
+
                        // trusted and delegate remotes.
+
                        Ok(Namespaces::All)
+
                    } else {
+
                        Ok(Namespaces::Trusted(trusted))
+
                    }
+
                }
+
            },
+
        }
+
    }
+
}
+

+
impl<T> ops::Deref for Config<T> {
+
    type Target = Store<T>;
+

+
    fn deref(&self) -> &Self::Target {
+
        &self.store
+
    }
+
}
+

+
impl<T> ops::DerefMut for Config<T> {
+
    fn deref_mut(&mut self) -> &mut Self::Target {
+
        &mut self.store
+
    }
+
}