mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-02 02:00:31 +08:00
radicle: pinned repositories configuration
Introduce pinned repositories to the `profile::Config`, i.e. `config.json`. This is used for pinning repositories in the httpd `/projects` handle. To allow returning all repositories, an `all` query parameter is also included. This is non-backwards compatible change, since we introduce the `show` query parameter which, if not supplied, will default to `pinned`. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
committed by
cloudhead
parent
92182a879b
commit
5b3d7b7652
@@ -125,10 +125,20 @@ async fn root_handler() -> impl IntoResponse {
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PaginationQuery {
|
||||
#[serde(default)]
|
||||
pub show: ProjectQuery,
|
||||
pub page: Option<usize>,
|
||||
pub per_page: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ProjectQuery {
|
||||
All,
|
||||
#[default]
|
||||
Pinned,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RawQuery {
|
||||
|
||||
@@ -14,7 +14,7 @@ use radicle::storage::{ReadRepository, ReadStorage};
|
||||
use crate::api::error::Error;
|
||||
use crate::api::project::Info;
|
||||
use crate::api::Context;
|
||||
use crate::api::PaginationQuery;
|
||||
use crate::api::{PaginationQuery, ProjectQuery};
|
||||
use crate::axum_extra::{Path, Query};
|
||||
|
||||
pub fn router(ctx: Context) -> Router {
|
||||
@@ -34,19 +34,28 @@ async fn delegates_projects_handler(
|
||||
Path(delegate): Path<Did>,
|
||||
Query(qs): Query<PaginationQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let PaginationQuery { page, per_page } = qs;
|
||||
let PaginationQuery {
|
||||
show,
|
||||
page,
|
||||
per_page,
|
||||
} = qs;
|
||||
let page = page.unwrap_or(0);
|
||||
let per_page = per_page.unwrap_or(10);
|
||||
let storage = &ctx.profile.storage;
|
||||
let db = &ctx.profile.database()?;
|
||||
let mut projects = storage
|
||||
.repositories()?
|
||||
.into_iter()
|
||||
.filter(|id| match &id.doc.visibility {
|
||||
Visibility::Private { .. } => addr.ip().is_loopback(),
|
||||
Visibility::Public => true,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let pinned = &ctx.profile.config.web.pinned;
|
||||
|
||||
let mut projects = match show {
|
||||
ProjectQuery::All => storage
|
||||
.repositories()?
|
||||
.into_iter()
|
||||
.filter(|repo| match &repo.doc.visibility {
|
||||
Visibility::Private { .. } => addr.ip().is_loopback(),
|
||||
Visibility::Public => true,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
ProjectQuery::Pinned => storage.repositories_by_id(pinned.repositories.iter())?,
|
||||
};
|
||||
projects.sort_by_key(|p| p.rid);
|
||||
|
||||
let infos = projects
|
||||
@@ -116,11 +125,16 @@ mod routes {
|
||||
.layer(MockConnectInfo(SocketAddr::from(([127, 0, 0, 1], 8080))));
|
||||
let response = get(
|
||||
&app,
|
||||
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects",
|
||||
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects?show=all",
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
response.status(),
|
||||
StatusCode::OK,
|
||||
"failed response: {:?}",
|
||||
response.json().await
|
||||
);
|
||||
assert_eq!(
|
||||
response.json().await,
|
||||
json!([
|
||||
@@ -179,11 +193,16 @@ mod routes {
|
||||
))));
|
||||
let response = get(
|
||||
&app,
|
||||
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects",
|
||||
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects?show=all",
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
response.status(),
|
||||
StatusCode::OK,
|
||||
"failed response: {:?}",
|
||||
response.json().await
|
||||
);
|
||||
assert_eq!(
|
||||
response.json().await,
|
||||
json!([
|
||||
|
||||
@@ -75,6 +75,7 @@ mod routes {
|
||||
"preferredSeeds": [
|
||||
"z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7@seed.radicle.garden:8776"
|
||||
],
|
||||
"web": { "pinned": { "repositories": [] } },
|
||||
"cli": {
|
||||
"hints": true
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@ use radicle_surf::{diff, Glob, Oid, Repository};
|
||||
|
||||
use crate::api::error::Error;
|
||||
use crate::api::project::Info;
|
||||
use crate::api::{self, announce_refs, CobsQuery, Context, PaginationQuery};
|
||||
use crate::api::{self, announce_refs, CobsQuery, Context, PaginationQuery, ProjectQuery};
|
||||
use crate::axum_extra::{Path, Query};
|
||||
|
||||
const CACHE_1_HOUR: &str = "public, max-age=3600, must-revalidate";
|
||||
@@ -79,19 +79,28 @@ async fn project_root_handler(
|
||||
State(ctx): State<Context>,
|
||||
Query(qs): Query<PaginationQuery>,
|
||||
) -> impl IntoResponse {
|
||||
let PaginationQuery { page, per_page } = qs;
|
||||
let PaginationQuery {
|
||||
show,
|
||||
page,
|
||||
per_page,
|
||||
} = qs;
|
||||
let page = page.unwrap_or(0);
|
||||
let per_page = per_page.unwrap_or(10);
|
||||
let storage = &ctx.profile.storage;
|
||||
let db = &ctx.profile.database()?;
|
||||
let mut projects = storage
|
||||
.repositories()?
|
||||
.into_iter()
|
||||
.filter(|id| match &id.doc.visibility {
|
||||
Visibility::Private { .. } => addr.ip().is_loopback(),
|
||||
Visibility::Public => true,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let pinned = &ctx.profile.config.web.pinned;
|
||||
|
||||
let mut projects = match show {
|
||||
ProjectQuery::All => storage
|
||||
.repositories()?
|
||||
.into_iter()
|
||||
.filter(|repo| match &repo.doc.visibility {
|
||||
Visibility::Private { .. } => addr.ip().is_loopback(),
|
||||
Visibility::Public => true,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
ProjectQuery::Pinned => storage.repositories_by_id(pinned.repositories.iter())?,
|
||||
};
|
||||
projects.sort_by_key(|p| p.rid);
|
||||
|
||||
let infos = projects
|
||||
@@ -976,7 +985,7 @@ mod routes {
|
||||
let seed = seed(tmp.path());
|
||||
let app = super::router(seed.clone())
|
||||
.layer(MockConnectInfo(SocketAddr::from(([127, 0, 0, 1], 8080))));
|
||||
let response = get(&app, "/projects").await;
|
||||
let response = get(&app, "/projects?show=all").await;
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
@@ -1035,7 +1044,7 @@ mod routes {
|
||||
[192, 168, 13, 37],
|
||||
8080,
|
||||
))));
|
||||
let response = get(&app, "/projects").await;
|
||||
let response = get(&app, "/projects?show=all").await;
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user