Fix code around default policies
Make the code a little clearer and ensure that we are always calling the `Config` and not the `Store`, so that we fallback on the default policy.
This commit is contained in:
parent
7a5e5ec865
commit
131103cb53
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Reference in New Issue