node: prevent fetch response if no repo policy

If a node had removed a seeding policy and another node fetched from
it, then it would perform the fetch.

Instead, check the policy during the authorization step and prevent
the fetch is the resulting policy is `Block`.

Note that the policy will be `Block` iff the `Block` policy was
specifically set or the `Block` is the default policy for the node.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny 2023-12-06 14:24:59 +00:00 committed by cloudhead
parent 53c08f5d26
commit e894b6512d
No known key found for this signature in database
2 changed files with 39 additions and 1 deletions

View File

@ -596,6 +596,35 @@ fn test_fetch_up_to_date() {
);
}
#[test]
fn test_fetch_unseeded() {
logger::init(log::Level::Debug);
let tmp = tempfile::tempdir().unwrap();
let alice = Node::init(tmp.path(), Config::test(Alias::new("alice")));
let mut bob = Node::init(tmp.path(), Config::test(Alias::new("bob")));
let acme = bob.project("acme", "");
let mut alice = alice.spawn();
let mut bob = bob.spawn();
alice.connect(&bob);
converge([&alice, &bob]);
transport::local::register(alice.storage.clone());
let _ = alice.handle.seed(acme, Scope::All).unwrap();
let result = alice.handle.fetch(acme, bob.id, DEFAULT_TIMEOUT).unwrap();
assert!(result.is_success());
// Bob stops seeding the repository
assert!(bob.handle.unseed(acme).unwrap());
// Alice attempts to fetch but is unauthorized
let result = alice.handle.fetch(acme, bob.id, DEFAULT_TIMEOUT).unwrap();
assert_matches!(result, FetchResult::Failed { .. });
}
#[test]
fn test_large_fetch() {
logger::init(log::Level::Debug);

View File

@ -79,6 +79,8 @@ pub enum UploadError {
Identity(#[from] radicle::identity::DocError),
#[error(transparent)]
Repository(#[from] radicle::storage::RepositoryError),
#[error(transparent)]
PolicyStore(#[from] radicle::node::policy::store::Error),
}
impl UploadError {
@ -259,9 +261,16 @@ impl Worker {
}
fn is_authorized(&self, remote: NodeId, rid: Id) -> Result<(), UploadError> {
let policy = {
let policy = self.fetch_config.policy;
let scope = self.fetch_config.scope;
let db = &self.fetch_config.policies_db;
let policies = policy::Config::new(policy, scope, policy::Store::reader(db)?);
policies.repo_policy(&rid)?.policy
};
let repo = self.storage.repository(rid)?;
let doc = repo.canonical_identity_doc()?;
if !doc.is_visible_to(&remote) {
if !doc.is_visible_to(&remote) || policy == Policy::Block {
Err(UploadError::Unauthorized(remote, rid))
} else {
Ok(())