diff --git a/radicle-cli/tests/commands.rs b/radicle-cli/tests/commands.rs index 61ee44d5..b800fbc3 100644 --- a/radicle-cli/tests/commands.rs +++ b/radicle-cli/tests/commands.rs @@ -6,6 +6,7 @@ use radicle::git; use radicle::node; use radicle::node::address::Store as _; use radicle::node::config::seeds::{RADICLE_COMMUNITY_NODE, RADICLE_TEAM_NODE}; +use radicle::node::config::DefaultSeedingPolicy; use radicle::node::routing::Store as _; use radicle::node::Handle as _; use radicle::node::UserAgent; @@ -17,7 +18,7 @@ use radicle::storage::{ReadStorage, RefUpdate, RemoteRepository}; use radicle::test::fixtures; use radicle_cli_test::TestFormula; -use radicle_node::service::policy::{Scope, SeedingPolicy}; +use radicle_node::service::policy::Scope; use radicle_node::service::Event; use radicle_node::test::environment::{Config, Environment, Node}; #[allow(unused_imports)] @@ -773,7 +774,7 @@ fn rad_node() { Address::from(net::SocketAddr::from(([41, 12, 98, 112], 8776))), Address::from_str("seed.cloudhead.io:8776").unwrap(), ], - seeding_policy: SeedingPolicy::Block, + seeding_policy: DefaultSeedingPolicy::Block, ..Config::test(Alias::new("alice")) }); let working = tempfile::tempdir().unwrap(); @@ -1232,7 +1233,7 @@ fn rad_unseed() { fn rad_block() { let mut environment = Environment::new(); let alice = environment.node(Config { - seeding_policy: SeedingPolicy::permissive(), + seeding_policy: DefaultSeedingPolicy::permissive(), ..Config::test(Alias::new("alice")) }); let working = tempfile::tempdir().unwrap(); @@ -1551,7 +1552,7 @@ fn rad_init_sync_preferred() { let mut environment = Environment::new(); let mut alice = environment .node(Config { - seeding_policy: SeedingPolicy::permissive(), + seeding_policy: DefaultSeedingPolicy::permissive(), ..Config::test(Alias::new("alice")) }) .spawn(); @@ -1583,7 +1584,7 @@ fn rad_init_sync_timeout() { let mut environment = Environment::new(); let mut alice = environment .node(Config { - seeding_policy: SeedingPolicy::Block, + seeding_policy: DefaultSeedingPolicy::Block, ..Config::test(Alias::new("alice")) }) .spawn(); @@ -1926,7 +1927,7 @@ fn test_replication_via_seed() { let alice = environment.node(config::relay("alice")); let bob = environment.node(config::relay("bob")); let seed = environment.node(Config { - seeding_policy: SeedingPolicy::permissive(), + seeding_policy: DefaultSeedingPolicy::permissive(), ..config::relay("seed") }); let working = environment.tmp().join("working"); @@ -2174,7 +2175,7 @@ fn rad_patch_open_explore() { let mut environment = Environment::new(); let seed = environment .node(Config { - seeding_policy: SeedingPolicy::permissive(), + seeding_policy: DefaultSeedingPolicy::permissive(), ..config::seed("seed") }) .spawn(); diff --git a/radicle-node/src/runtime.rs b/radicle-node/src/runtime.rs index 5ed6ab45..dae86c08 100644 --- a/radicle-node/src/runtime.rs +++ b/radicle-node/src/runtime.rs @@ -123,7 +123,7 @@ impl Runtime { let clock = LocalTime::now(); let timestamp = clock.into(); let storage = Storage::open(home.storage(), git::UserInfo { alias, key: id })?; - let policy = config.seeding_policy; + let policy = config.seeding_policy.into(); for (key, _) in &config.extra { log::warn!(target: "node", "Unused or deprecated configuration attribute {:?}", key); diff --git a/radicle/src/node/config.rs b/radicle/src/node/config.rs index e65564bb..fdbe4476 100644 --- a/radicle/src/node/config.rs +++ b/radicle/src/node/config.rs @@ -7,7 +7,7 @@ use localtime::LocalDuration; use serde_json as json; use crate::node; -use crate::node::policy::SeedingPolicy; +use crate::node::policy::{Scope, SeedingPolicy}; use crate::node::{Address, Alias, NodeId}; /// Peer-to-peer protocol version. @@ -260,6 +260,42 @@ pub enum AddressConfig { Forward, } +/// Default seeding policy. Applies when no repository policies for the given repo are found. +#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase", tag = "default")] +pub enum DefaultSeedingPolicy { + /// Allow seeding. + Allow { + /// Seeding scope. + #[serde(default)] + scope: Scope, + }, + /// Block seeding. + #[default] + Block, +} + +impl DefaultSeedingPolicy { + /// Is this an "allow" policy. + pub fn is_allow(&self) -> bool { + matches!(self, Self::Allow { .. }) + } + + /// Seed everything from anyone. + pub fn permissive() -> Self { + Self::Allow { scope: Scope::All } + } +} + +impl From for SeedingPolicy { + fn from(policy: DefaultSeedingPolicy) -> Self { + match policy { + DefaultSeedingPolicy::Block => Self::Block, + DefaultSeedingPolicy::Allow { scope } => Self::Allow { scope }, + } + } +} + /// Service configuration. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] @@ -303,7 +339,7 @@ pub struct Config { pub workers: usize, /// Default seeding policy. #[serde(default)] - pub seeding_policy: SeedingPolicy, + pub seeding_policy: DefaultSeedingPolicy, /// Extra fields that aren't supported. #[serde(flatten, skip_serializing)] pub extra: json::Map, @@ -331,7 +367,7 @@ impl Config { limits: Limits::default(), workers: DEFAULT_WORKERS, log: defaults::log(), - seeding_policy: SeedingPolicy::default(), + seeding_policy: DefaultSeedingPolicy::default(), extra: json::Map::default(), } } diff --git a/radicle/src/node/policy.rs b/radicle/src/node/policy.rs index 66aa10b6..cd97ce05 100644 --- a/radicle/src/node/policy.rs +++ b/radicle/src/node/policy.rs @@ -34,9 +34,9 @@ pub struct FollowPolicy { pub policy: Policy, } -/// Default seeding policy. Applies when no repository policies for the given repo are found. +/// Seeding policy of a node or repo. #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -#[serde(rename_all = "camelCase", tag = "default")] +#[serde(rename_all = "camelCase", tag = "policy")] pub enum SeedingPolicy { /// Allow seeding. Allow { @@ -50,11 +50,6 @@ pub enum SeedingPolicy { } impl SeedingPolicy { - /// Seed everything from anyone. - pub fn permissive() -> Self { - Self::Allow { scope: Scope::All } - } - /// Is this an "allow" policy. pub fn is_allow(&self) -> bool { matches!(self, Self::Allow { .. }) diff --git a/radicle/src/profile.rs b/radicle/src/profile.rs index 90e6fac3..08ef97e7 100644 --- a/radicle/src/profile.rs +++ b/radicle/src/profile.rs @@ -23,10 +23,11 @@ use crate::crypto::ssh::agent::Agent; use crate::crypto::ssh::{keystore, Keystore, Passphrase}; use crate::crypto::{PublicKey, Signer}; use crate::explorer::Explorer; +use crate::node::config::DefaultSeedingPolicy; use crate::node::policy::config::store::Read; use crate::node::{ notifications, policy, - policy::{Policy, Scope, SeedingPolicy}, + policy::{Policy, Scope}, Alias, AliasStore, Handle as _, Node, UserAgent, }; use crate::prelude::{Did, NodeId, RepoId}; @@ -254,8 +255,8 @@ impl Config { ) { log::warn!(target: "radicle", "Overwriting `seedingPolicy` configuration"); cfg.node.seeding_policy = match policy { - Policy::Allow => SeedingPolicy::Allow { scope }, - Policy::Block => SeedingPolicy::Block, + Policy::Allow => DefaultSeedingPolicy::Allow { scope }, + Policy::Block => DefaultSeedingPolicy::Block, } } } @@ -415,7 +416,7 @@ impl Profile { pub fn policies(&self) -> Result, policy::store::Error> { let path = self.node().join(node::POLICIES_DB_FILE); let config = policy::config::Config::new( - self.config.node.seeding_policy, + self.config.node.seeding_policy.into(), policy::store::Store::reader(path)?, ); Ok(config)