diff --git a/radicle-httpd/Cargo.lock b/radicle-httpd/Cargo.lock index 9ac830ae6..13bf411bf 100644 --- a/radicle-httpd/Cargo.lock +++ b/radicle-httpd/Cargo.lock @@ -1581,9 +1581,9 @@ dependencies = [ [[package]] name = "radicle" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a818569c11f1bac56f38b002d778ce8ec92e312024b9aebcd68bad5dee6a465" +checksum = "fd823aeed3ffe73eb82a213e62cb3811f9bdf453844d6e0b14684e0757fb389b" dependencies = [ "amplify", "base64 0.21.7", @@ -1612,9 +1612,9 @@ dependencies = [ [[package]] name = "radicle-cob" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fac94999d8ffb6e88674bee487b080b69bbc9fb1b439ebfa51481ede1a17b3" +checksum = "90581a9508ccc310998e991d7acf139d2991297d3fb37d30de07536e10256afb" dependencies = [ "fastrand", "git2", @@ -1652,9 +1652,9 @@ dependencies = [ [[package]] name = "radicle-dag" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a678c3049a88ae6a34dd9f52ea9a5f9f066a0af63466b75cf8c48840303067" +checksum = "cb41c7e10ada3a4df960190a96bfb4af56d33ada890f917acc8e3b122b614875" dependencies = [ "fastrand", ] diff --git a/radicle-httpd/Cargo.toml b/radicle-httpd/Cargo.toml index ef6af21b9..12427506f 100644 --- a/radicle-httpd/Cargo.toml +++ b/radicle-httpd/Cargo.toml @@ -42,7 +42,7 @@ tracing-logfmt = { version = "0.3.5", optional = true } tracing-subscriber = { version = "0.3.18", default-features = false, features = ["std", "ansi", "fmt"] } [dependencies.radicle] -version = "0.13.0" +version = "0.14.0" [dev-dependencies] hyper = { version = "1.4", default-features = false, features = ["client"] } diff --git a/radicle-httpd/src/api.rs b/radicle-httpd/src/api.rs index 425fe877a..b0de418fb 100644 --- a/radicle-httpd/src/api.rs +++ b/radicle-httpd/src/api.rs @@ -56,15 +56,16 @@ impl Context { let aliases = self.profile.aliases(); let delegates = doc - .delegates - .into_iter() - .map(|did| json::Author::new(&did).as_json(&aliases)) + .delegates() + .iter() + .map(|did| json::Author::new(did).as_json(&aliases)) .collect::>(); let db = &self.profile.database()?; let seeding = db.count(&rid).unwrap_or_default(); let payloads: BTreeMap = doc - .payload + .payload() + .clone() .into_iter() .filter_map(|(id, payload)| { if id == PayloadId::project() { @@ -94,8 +95,8 @@ impl Context { Ok(repo::Info { payloads, delegates, - threshold: doc.threshold, - visibility: doc.visibility, + threshold: doc.threshold(), + visibility: doc.visibility().clone(), rid, seeding, }) @@ -106,7 +107,7 @@ impl Context { let repo = self.profile.storage.repository(rid)?; let doc = repo.identity_doc()?; // Don't allow accessing private repos. - if doc.visibility.is_private() { + if doc.visibility().is_private() { return Err(Error::NotFound); } Ok((repo, doc)) @@ -150,11 +151,9 @@ mod search { use std::cmp::Ordering; use std::collections::BTreeMap; - use nonempty::NonEmpty; use serde::{Deserialize, Serialize}; use serde_json::json; - use radicle::crypto::Verified; use radicle::identity::doc::{Payload, PayloadId}; use radicle::identity::RepoId; use radicle::node::routing::Store; @@ -174,7 +173,7 @@ mod search { pub struct SearchResult { pub rid: RepoId, pub payloads: BTreeMap, - pub delegates: NonEmpty, + pub delegates: Vec, pub seeds: usize, #[serde(skip)] pub index: usize, @@ -183,30 +182,35 @@ mod search { impl SearchResult { pub fn new( q: &str, - info: RepositoryInfo, + info: RepositoryInfo, db: &Database, aliases: &Aliases, ) -> Option { - if info.doc.visibility.is_private() { + if info.doc.visibility().is_private() { return None; } let Ok(Some(index)) = info.doc.project().map(|p| p.name().find(q)) else { return None; }; let seeds = db.count(&info.rid).unwrap_or_default(); - let delegates = info.doc.delegates.map(|did| match aliases.alias(&did) { - Some(alias) => json!({ - "id": did, - "alias": alias, - }), - None => json!({ - "id": did, - }), - }); + let delegates = info + .doc + .delegates() + .iter() + .map(|did| match aliases.alias(did) { + Some(alias) => json!({ + "id": did, + "alias": alias, + }), + None => json!({ + "id": did, + }), + }) + .collect::>(); Some(SearchResult { rid: info.rid, - payloads: info.doc.payload, + payloads: info.doc.payload().clone(), delegates, seeds, index, diff --git a/radicle-httpd/src/api/v1/delegates.rs b/radicle-httpd/src/api/v1/delegates.rs index aeca0ef3c..28e962305 100644 --- a/radicle-httpd/src/api/v1/delegates.rs +++ b/radicle-httpd/src/api/v1/delegates.rs @@ -37,14 +37,14 @@ async fn delegates_repos_handler( RepoQuery::All => storage .repositories()? .into_iter() - .filter(|repo| repo.doc.visibility.is_public()) - .filter(|repo| repo.doc.delegates.iter().any(|d| *d == did)) + .filter(|repo| repo.doc.visibility().is_public()) + .filter(|repo| repo.doc.delegates().iter().any(|d| *d == did)) .collect::>(), RepoQuery::Pinned => storage .repositories_by_id(pinned.repositories.iter())? .into_iter() - .filter(|repo| repo.doc.visibility.is_public()) - .filter(|repo| repo.doc.delegates.iter().any(|d| *d == did)) + .filter(|repo| repo.doc.visibility().is_public()) + .filter(|repo| repo.doc.delegates().iter().any(|d| *d == did)) .collect::>(), }; repos.sort_by_key(|p| p.rid); diff --git a/radicle-httpd/src/api/v1/repos.rs b/radicle-httpd/src/api/v1/repos.rs index 4191770ee..8678bd901 100644 --- a/radicle-httpd/src/api/v1/repos.rs +++ b/radicle-httpd/src/api/v1/repos.rs @@ -73,12 +73,12 @@ async fn repo_root_handler( RepoQuery::All => storage .repositories()? .into_iter() - .filter(|repo| repo.doc.visibility.is_public()) + .filter(|repo| repo.doc.visibility().is_public()) .collect::>(), RepoQuery::Pinned => storage .repositories_by_id(pinned.repositories.iter())? .into_iter() - .filter(|repo| repo.doc.visibility.is_public()) + .filter(|repo| repo.doc.visibility().is_public()) .collect::>(), }; repos.sort_by_key(|p| p.rid); @@ -436,7 +436,7 @@ async fn stats_tree_handler( /// `GET /repos/:rid/remotes` async fn remotes_handler(State(ctx): State, Path(rid): Path) -> impl IntoResponse { let (repo, doc) = ctx.repo(rid)?; - let delegates = &doc.delegates; + let delegates = doc.delegates(); let aliases = &ctx.profile.aliases(); let remotes = repo .remotes()? @@ -478,7 +478,7 @@ async fn remote_handler( Path((rid, node_id)): Path<(RepoId, NodeId)>, ) -> impl IntoResponse { let (repo, doc) = ctx.repo(rid)?; - let delegates = &doc.delegates; + let delegates = doc.delegates(); let remote = repo.remote(&node_id)?; let refs = remote .refs diff --git a/radicle-httpd/src/git.rs b/radicle-httpd/src/git.rs index 1f0960ed9..9fbd6294b 100644 --- a/radicle-httpd/src/git.rs +++ b/radicle-httpd/src/git.rs @@ -85,7 +85,7 @@ async fn git_http_backend( // Don't allow cloning of private repositories. let doc = profile.storage.repository(id)?.identity_doc()?; - if doc.visibility.is_private() { + if doc.visibility().is_private() { return Err(Error::NotFound); } diff --git a/radicle-httpd/src/raw.rs b/radicle-httpd/src/raw.rs index c673cd035..4609c9454 100644 --- a/radicle-httpd/src/raw.rs +++ b/radicle-httpd/src/raw.rs @@ -116,7 +116,7 @@ async fn file_by_commit_handler( let repo = storage.repository(rid)?; // Don't allow downloading raw files for private repos. - if repo.identity_doc()?.visibility.is_private() { + if repo.identity_doc()?.visibility().is_private() { return Err(Error::NotFound); } @@ -134,7 +134,7 @@ async fn file_by_canonical_head_handler( let repo = storage.repository(rid)?; // Don't allow downloading raw files for private repos. - if repo.identity_doc()?.visibility.is_private() { + if repo.identity_doc()?.visibility().is_private() { return Err(Error::NotFound); } @@ -176,7 +176,7 @@ async fn file_by_oid_handler( let repo = storage.repository(rid)?; // Don't allow downloading raw files for private repos. - if repo.identity_doc()?.visibility.is_private() { + if repo.identity_doc()?.visibility().is_private() { return Err(Error::NotFound); } diff --git a/radicle-httpd/src/test.rs b/radicle-httpd/src/test.rs index 70dcf38de..5a5c9289a 100644 --- a/radicle-httpd/src/test.rs +++ b/radicle-httpd/src/test.rs @@ -7,20 +7,21 @@ use std::sync::Arc; use axum::body::{Body, Bytes}; use axum::http::{Method, Request}; use axum::Router; -use radicle::node::{Features, Timestamp, UserAgent}; use serde_json::Value; use tower::ServiceExt; +use radicle::cob::migrate; use radicle::cob::patch::MergeTarget; use radicle::crypto::ssh::Keystore; +use radicle::crypto::test::signer::MockSigner; use radicle::crypto::{KeyPair, Seed, Signer}; use radicle::git::{raw as git2, RefString}; use radicle::identity::{project, Visibility}; +use radicle::node::{Features, Timestamp, UserAgent}; use radicle::profile::{env, Home}; use radicle::storage::ReadStorage; use radicle::{node, profile}; use radicle::{Node, Storage}; -use radicle_crypto::test::signer::MockSigner; use crate::api::Context; @@ -65,6 +66,10 @@ pub fn profile(home: &Path, seed: [u8; 32]) -> radicle::Profile { ) .unwrap(); + // Migrate COBs cache. + let mut cobs = home.cobs_db_mut().unwrap(); + cobs.migrate(migrate::ignore).unwrap(); + radicle::storage::git::transport::local::register(storage.clone()); keystore.store(keypair.clone(), "radicle", None).unwrap();