Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Fix code around default policies
cloudhead committed 2 years ago
commit 131103cb53032a258badd7a191be4640a113a3b1
parent 7a5e5ec86524afbd372ed14b7f8c9c16b64bb4d7
13 files changed +100 -75
modified radicle-cli/src/commands/follow.rs
@@ -166,9 +166,14 @@ pub fn following(profile: &Profile, alias: Option<Alias>) -> anyhow::Result<()>
fn push_policies(
    t: &mut Table<3, Paint<String>>,
    aliases: &impl AliasStore,
-
    policies: impl Iterator<Item = policy::Node>,
+
    policies: impl Iterator<Item = policy::FollowPolicy>,
) {
-
    for policy::Node { id, alias, policy } in policies {
+
    for policy::FollowPolicy {
+
        nid: id,
+
        alias,
+
        policy,
+
    } in policies
+
    {
        t.push([
            term::format::highlight(Did::from(id).to_string()),
            match alias {
modified radicle-cli/src/commands/inspect.rs
@@ -172,22 +172,24 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
            }
        }
        Target::Policy => {
-
            let tracking = profile.policies()?;
-
            if let Some(repo) = tracking.seed_policy(&rid)? {
-
                let tracking = match repo.policy {
-
                    Policy::Allow => term::format::positive("tracked"),
-
                    Policy::Block => term::format::negative("blocked"),
-
                };
-
                println!(
-
                    "Repository {} is {} with scope {}",
-
                    term::format::tertiary(&rid),
-
                    tracking,
-
                    term::format::dim(format!("`{}`", repo.scope))
-
                );
-
            } else {
-
                term::print(term::format::italic(format!(
-
                    "No tracking policy found for {rid}"
-
                )));
+
            let policies = profile.policies()?;
+
            let seed = policies.seed_policy(&rid)?;
+
            match seed.policy {
+
                Policy::Allow => {
+
                    println!(
+
                        "Repository {} is {} with scope {}",
+
                        term::format::tertiary(&rid),
+
                        term::format::positive("being seeded"),
+
                        term::format::dim(format!("`{}`", seed.scope))
+
                    );
+
                }
+
                Policy::Block => {
+
                    println!(
+
                        "Repository {} is {}",
+
                        term::format::tertiary(&rid),
+
                        term::format::negative("not being seeded"),
+
                    );
+
                }
            }
        }
        Target::Delegates => {
modified radicle-cli/src/commands/ls.rs
@@ -106,7 +106,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
        if refs.is_none() && !options.all {
            continue;
        }
-
        let seeded = policy.is_seeded(&rid)?;
+
        let seeded = policy.is_seeding(&rid)?;

        if !seeded && !options.all {
            continue;
@@ -120,7 +120,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
            if seeded {
                term::format::visibility(&doc.visibility).into()
            } else {
-
                term::format::tertiary("local").into()
+
                term::format::dim("local").into()
            },
            term::format::secondary(head),
            term::format::italic(proj.description().to_owned()),
modified radicle-cli/src/commands/remote/add.rs
@@ -25,7 +25,7 @@ pub fn run(
    if sync {
        let mut node = radicle::Node::new(profile.socket());

-
        if !profile.policies()?.is_followed(nid)? {
+
        if !profile.policies()?.is_following(nid)? {
            let alias = name.as_ref().and_then(|n| Alias::from_str(n.as_str()).ok());

            follow::follow(*nid, alias, &mut node, profile)?;
modified radicle-cli/src/commands/seed.rs
@@ -183,7 +183,12 @@ pub fn seeding(profile: &Profile) -> anyhow::Result<()> {
    ]);
    t.divider();

-
    for policy::Repo { id, scope, policy } in store.seed_policies()? {
+
    for policy::SeedPolicy {
+
        rid: id,
+
        scope,
+
        policy,
+
    } in store.seed_policies()?
+
    {
        let id = id.to_string();
        let scope = scope.to_string();
        let policy = policy.to_string();
modified radicle-cli/src/commands/sync.rs
@@ -281,7 +281,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
        }
        Operation::Synchronize(SyncMode::Repo { mode, direction }) => {
            if [SyncDirection::Fetch, SyncDirection::Both].contains(&direction) {
-
                if !profile.policies()?.is_seeded(&rid)? {
+
                if !profile.policies()?.is_seeding(&rid)? {
                    anyhow::bail!("repository {rid} is not seeded");
                }
                let results = fetch(rid, mode.clone(), options.timeout, &mut node)?;
modified radicle-fetch/src/policy.rs
@@ -16,7 +16,7 @@ pub enum Allowed {
impl Allowed {
    pub fn from_config(rid: RepoId, config: &Config<Read>) -> Result<Self, error::Policy> {
        let entry = config
-
            .repo_policy(&rid)
+
            .seed_policy(&rid)
            .map_err(|err| error::Policy::FailedPolicy { rid, err })?;
        match entry.policy {
            Policy::Block => {
@@ -30,7 +30,7 @@ impl Allowed {
                        .follow_policies()
                        .map_err(|err| error::Policy::FailedNodes { rid, err })?;
                    let followed: HashSet<_> = nodes
-
                        .filter_map(|node| (node.policy == Policy::Allow).then_some(node.id))
+
                        .filter_map(|node| (node.policy == Policy::Allow).then_some(node.nid))
                        .collect();

                    Ok(Allowed::Followed { remotes: followed })
@@ -64,7 +64,7 @@ impl BlockList {
    pub fn from_config(config: &Config<Read>) -> Result<BlockList, error::Blocked> {
        Ok(config
            .follow_policies()?
-
            .filter_map(|entry| (entry.policy == Policy::Block).then_some(entry.id))
+
            .filter_map(|entry| (entry.policy == Policy::Block).then_some(entry.nid))
            .collect())
    }
}
modified radicle-httpd/src/api/v1/node.rs
@@ -58,7 +58,12 @@ async fn node_policies_repos_handler(State(ctx): State<Context>) -> impl IntoRes
    let policies = ctx.profile.policies()?;
    let mut repos = Vec::new();

-
    for policy::Repo { id, scope, policy } in policies.seed_policies()? {
+
    for policy::SeedPolicy {
+
        rid: id,
+
        scope,
+
        policy,
+
    } in policies.seed_policies()?
+
    {
        repos.push(json!({
            "id": id,
            "scope": scope,
modified radicle-node/src/service.rs
@@ -460,7 +460,7 @@ where
        self.filter = Filter::new(
            self.policies
                .seed_policies()?
-
                .filter_map(|t| (t.policy == Policy::Allow).then_some(t.id)),
+
                .filter_map(|t| (t.policy == Policy::Allow).then_some(t.rid)),
        );
        Ok(updated)
    }
@@ -598,7 +598,7 @@ where
        self.filter = Filter::new(
            self.policies
                .seed_policies()?
-
                .filter_map(|t| (t.policy == Policy::Allow).then_some(t.id)),
+
                .filter_map(|t| (t.policy == Policy::Allow).then_some(t.rid)),
        );
        // Connect to configured peers.
        let addrs = self.config.connect.clone();
@@ -1331,7 +1331,7 @@ where
                }

                // TODO: Buffer/throttle fetches.
-
                let repo_entry = self.policies.repo_policy(&message.rid).expect(
+
                let repo_entry = self.policies.seed_policy(&message.rid).expect(
                    "Service::handle_announcement: error accessing repo seeding configuration",
                );

@@ -2029,7 +2029,7 @@ where
        let missing = self
            .policies
            .seed_policies()?
-
            .filter_map(|t| (t.policy == Policy::Allow).then_some(t.id))
+
            .filter_map(|t| (t.policy == Policy::Allow).then_some(t.rid))
            .filter(|rid| !inventory.contains(rid));

        for rid in missing {
modified radicle-node/src/worker.rs
@@ -262,7 +262,7 @@ impl Worker {
    }

    fn is_authorized(&self, remote: NodeId, rid: RepoId) -> Result<(), UploadError> {
-
        let policy = self.policies.repo_policy(&rid)?.policy;
+
        let policy = self.policies.seed_policy(&rid)?.policy;
        let repo = self.storage.repository(rid)?;
        let doc = repo.canonical_identity_doc()?;
        if !doc.is_visible_to(&remote) || policy == Policy::Block {
modified radicle/src/node/policy.rs
@@ -13,16 +13,16 @@ pub use super::{Alias, NodeId};

/// Repository seeding policy.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
-
pub struct Repo {
-
    pub id: RepoId,
+
pub struct SeedPolicy {
+
    pub rid: RepoId,
    pub scope: Scope,
    pub policy: Policy,
}

/// Node following policy.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
-
pub struct Node {
-
    pub id: NodeId,
+
pub struct FollowPolicy {
+
    pub nid: NodeId,
    pub alias: Option<Alias>,
    pub policy: Policy,
}
modified radicle/src/node/policy/config.rs
@@ -12,7 +12,7 @@ use crate::storage::{Namespaces, ReadRepository as _, ReadStorage, RepositoryErr
pub use crate::node::policy::store;
pub use crate::node::policy::store::Error;
pub use crate::node::policy::store::Store;
-
pub use crate::node::policy::{Alias, Node, Policy, Repo, Scope};
+
pub use crate::node::policy::{Alias, FollowPolicy, Policy, Scope, SeedPolicy};

#[derive(Debug, Error)]
pub enum NamespacesError {
@@ -75,32 +75,32 @@ impl<T> Config<T> {
    }

    /// Check if a repository is seeded.
-
    pub fn is_seeding(&self, id: &RepoId) -> Result<bool, Error> {
-
        self.repo_policy(id)
+
    pub fn is_seeding(&self, rid: &RepoId) -> Result<bool, Error> {
+
        self.seed_policy(rid)
            .map(|entry| entry.policy == Policy::Allow)
    }

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

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

-
    /// Get a repository's seediing information.
+
    /// Get a repository's seeding information.
    /// Returns the default policy if the repo isn't found.
-
    pub fn repo_policy(&self, id: &RepoId) -> Result<Repo, Error> {
-
        Ok(self.store.seed_policy(id)?.unwrap_or(Repo {
-
            id: *id,
+
    pub fn seed_policy(&self, rid: &RepoId) -> Result<SeedPolicy, Error> {
+
        Ok(self.store.seed_policy(rid)?.unwrap_or(SeedPolicy {
+
            rid: *rid,
            scope: self.scope,
            policy: self.policy,
        }))
@@ -117,7 +117,7 @@ impl<T> Config<T> {
        use NamespacesError::*;

        let entry = self
-
            .repo_policy(rid)
+
            .seed_policy(rid)
            .map_err(|err| FailedPolicy { rid: *rid, err })?;
        match entry.policy {
            Policy::Block => {
@@ -131,7 +131,7 @@ impl<T> Config<T> {
                        .follow_policies()
                        .map_err(|err| FailedNodes { rid: *rid, err })?;
                    let mut followed: HashSet<_> = nodes
-
                        .filter_map(|node| (node.policy == Policy::Allow).then_some(node.id))
+
                        .filter_map(|node| (node.policy == Policy::Allow).then_some(node.nid))
                        .collect();

                    if let Ok(repo) = storage.repository(*rid) {
modified radicle/src/node/policy/store.rs
@@ -9,7 +9,7 @@ use thiserror::Error;
use crate::node::{Alias, AliasStore};
use crate::prelude::{NodeId, RepoId};

-
use super::{Node, Policy, Repo, Scope};
+
use super::{FollowPolicy, Policy, Scope, SeedPolicy};

/// How long to wait for the database lock to be released before failing a read.
const DB_READ_TIMEOUT: time::Duration = time::Duration::from_secs(3);
@@ -204,10 +204,10 @@ impl Store<Write> {
/// `Config<Write>` can access these functions as well.
impl<T> Store<T> {
    /// Check if a node is followed.
-
    pub fn is_followed(&self, id: &NodeId) -> Result<bool, Error> {
+
    pub fn is_following(&self, id: &NodeId) -> Result<bool, Error> {
        Ok(matches!(
            self.follow_policy(id)?,
-
            Some(Node {
+
            Some(FollowPolicy {
                policy: Policy::Allow,
                ..
            })
@@ -215,10 +215,10 @@ impl<T> Store<T> {
    }

    /// Check if a repository is seeded.
-
    pub fn is_seeded(&self, id: &RepoId) -> Result<bool, Error> {
+
    pub fn is_seeding(&self, id: &RepoId) -> Result<bool, Error> {
        Ok(matches!(
            self.seed_policy(id)?,
-
            Some(Repo {
+
            Some(SeedPolicy {
                policy: Policy::Allow,
                ..
            })
@@ -226,7 +226,7 @@ impl<T> Store<T> {
    }

    /// Get a node's follow policy.
-
    pub fn follow_policy(&self, id: &NodeId) -> Result<Option<Node>, Error> {
+
    pub fn follow_policy(&self, id: &NodeId) -> Result<Option<FollowPolicy>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT alias, policy FROM `following` WHERE id = ?")?;
@@ -242,8 +242,8 @@ impl<T> Store<T> {
                .and_then(|s| Alias::from_str(&s).ok());
            let policy = row.read::<Policy, _>("policy");

-
            return Ok(Some(Node {
-
                id: *id,
+
            return Ok(Some(FollowPolicy {
+
                nid: *id,
                alias,
                policy,
            }));
@@ -252,7 +252,7 @@ impl<T> Store<T> {
    }

    /// Get a repository's seeding policy.
-
    pub fn seed_policy(&self, id: &RepoId) -> Result<Option<Repo>, Error> {
+
    pub fn seed_policy(&self, id: &RepoId) -> Result<Option<SeedPolicy>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT scope, policy FROM `seeding` WHERE id = ?")?;
@@ -260,8 +260,8 @@ impl<T> Store<T> {
        stmt.bind((1, id))?;

        if let Some(Ok(row)) = stmt.into_iter().next() {
-
            return Ok(Some(Repo {
-
                id: *id,
+
            return Ok(Some(SeedPolicy {
+
                rid: *id,
                scope: row.read::<Scope, _>("scope"),
                policy: row.read::<Policy, _>("policy"),
            }));
@@ -270,7 +270,7 @@ impl<T> Store<T> {
    }

    /// Get node follow policies.
-
    pub fn follow_policies(&self) -> Result<Box<dyn Iterator<Item = Node>>, Error> {
+
    pub fn follow_policies(&self) -> Result<Box<dyn Iterator<Item = FollowPolicy>>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT id, alias, policy FROM `following`")?
@@ -287,14 +287,18 @@ impl<T> Store<T> {
                .and_then(|s| Alias::from_str(&s).ok());
            let policy = row.read::<Policy, _>("policy");

-
            entries.push(Node { id, alias, policy });
+
            entries.push(FollowPolicy {
+
                nid: id,
+
                alias,
+
                policy,
+
            });
        }
        Ok(Box::new(entries.into_iter()))
    }

    // TODO: see if sql can return iterator directly
    /// Get repository seed policies.
-
    pub fn seed_policies(&self) -> Result<Box<dyn Iterator<Item = Repo>>, Error> {
+
    pub fn seed_policies(&self) -> Result<Box<dyn Iterator<Item = SeedPolicy>>, Error> {
        let mut stmt = self
            .db
            .prepare("SELECT id, scope, policy FROM `seeding`")?
@@ -306,7 +310,11 @@ impl<T> Store<T> {
            let scope = row.read("scope");
            let policy = row.read::<Policy, _>("policy");

-
            entries.push(Repo { id, scope, policy });
+
            entries.push(SeedPolicy {
+
                rid: id,
+
                scope,
+
                policy,
+
            });
        }
        Ok(Box::new(entries.into_iter()))
    }
@@ -335,10 +343,10 @@ mod test {
        let mut db = Store::open(":memory:").unwrap();

        assert!(db.follow(&id, Some("eve")).unwrap());
-
        assert!(db.is_followed(&id).unwrap());
+
        assert!(db.is_following(&id).unwrap());
        assert!(!db.follow(&id, Some("eve")).unwrap());
        assert!(db.unfollow(&id).unwrap());
-
        assert!(!db.is_followed(&id).unwrap());
+
        assert!(!db.is_following(&id).unwrap());
    }

    #[test]
@@ -347,10 +355,10 @@ mod test {
        let mut db = Store::open(":memory:").unwrap();

        assert!(db.seed(&id, Scope::All).unwrap());
-
        assert!(db.is_seeded(&id).unwrap());
+
        assert!(db.is_seeding(&id).unwrap());
        assert!(!db.seed(&id, Scope::All).unwrap());
        assert!(db.unseed(&id).unwrap());
-
        assert!(!db.is_seeded(&id).unwrap());
+
        assert!(!db.is_seeding(&id).unwrap());
    }

    #[test]
@@ -362,9 +370,9 @@ mod test {
            assert!(db.follow(id, None).unwrap());
        }
        let mut entries = db.follow_policies().unwrap();
-
        assert_matches!(entries.next(), Some(Node { id, .. }) if id == ids[0]);
-
        assert_matches!(entries.next(), Some(Node { id, .. }) if id == ids[1]);
-
        assert_matches!(entries.next(), Some(Node { id, .. }) if id == ids[2]);
+
        assert_matches!(entries.next(), Some(FollowPolicy { nid, .. }) if nid == ids[0]);
+
        assert_matches!(entries.next(), Some(FollowPolicy { nid, .. }) if nid == ids[1]);
+
        assert_matches!(entries.next(), Some(FollowPolicy { nid, .. }) if nid == ids[2]);
    }

    #[test]
@@ -376,9 +384,9 @@ mod test {
            assert!(db.seed(id, Scope::All).unwrap());
        }
        let mut entries = db.seed_policies().unwrap();
-
        assert_matches!(entries.next(), Some(Repo { id, .. }) if id == ids[0]);
-
        assert_matches!(entries.next(), Some(Repo { id, .. }) if id == ids[1]);
-
        assert_matches!(entries.next(), Some(Repo { id, .. }) if id == ids[2]);
+
        assert_matches!(entries.next(), Some(SeedPolicy { rid, .. }) if rid == ids[0]);
+
        assert_matches!(entries.next(), Some(SeedPolicy { rid, .. }) if rid == ids[1]);
+
        assert_matches!(entries.next(), Some(SeedPolicy { rid, .. }) if rid == ids[2]);
    }

    #[test]