Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Add node policies endpoint
Sebastian Martinez committed 2 years ago
commit e360c6333dca1ce86688c4946d61401dc368cd60
parent 0d3bd3cf03b85ea8217ca44f96e6369c72aca0d3
2 files changed +60 -7
modified radicle-httpd/src/api.rs
@@ -19,7 +19,8 @@ use radicle::cob::{issue, Uri};
use radicle::cob::{patch, Embed};
use radicle::identity::{DocAt, Id};
use radicle::node::routing::Store;
-
use radicle::node::Handle;
+
use radicle::node::tracking::Scope;
+
use radicle::node::{Handle, NodeId};
use radicle::storage::{Oid, ReadRepository, ReadStorage};
use radicle::{Node, Profile};

@@ -143,6 +144,14 @@ pub struct CobsQuery<T> {
    pub state: Option<T>,
}

+
#[derive(Serialize, Deserialize, Clone)]
+
#[serde(rename_all = "camelCase")]
+
pub struct PoliciesQuery {
+
    /// The NID from which to fetch from after tracking a repo.
+
    pub from: Option<NodeId>,
+
    pub scope: Option<Scope>,
+
}
+

#[derive(Default, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub enum IssueState {
modified radicle-httpd/src/api/v1/node.rs
@@ -1,19 +1,27 @@
use axum::extract::State;
use axum::response::IntoResponse;
-
use axum::routing::get;
+
use axum::routing::{get, put};
use axum::{Json, Router};
+
use axum_auth::AuthBearer;
+
use hyper::StatusCode;
use serde_json::json;

-
use radicle::node::{tracking, Handle};
+
use radicle::identity::Id;
+
use radicle::node::{tracking, Handle, DEFAULT_TIMEOUT};
use radicle::Node;

use crate::api::error::Error;
-
use crate::api::Context;
+
use crate::api::{self, Context, PoliciesQuery};
+
use crate::axum_extra::{Path, Query};

pub fn router(ctx: Context) -> Router {
    Router::new()
        .route("/node", get(node_handler))
-
        .route("/node/tracking/repos", get(node_tracking_repos_handler))
+
        .route("/node/policies/repos", get(node_policies_repos_handler))
+
        .route(
+
            "/node/policies/repos/:rid",
+
            put(node_policies_track_handler).delete(node_policies_untrack_handler),
+
        )
        .with_state(ctx)
}

@@ -44,8 +52,8 @@ async fn node_handler(State(ctx): State<Context>) -> impl IntoResponse {
}

/// Return local tracking repos information.
-
/// `GET /node/tracking/repos`
-
async fn node_tracking_repos_handler(State(ctx): State<Context>) -> impl IntoResponse {
+
/// `GET /node/policies/repos`
+
async fn node_policies_repos_handler(State(ctx): State<Context>) -> impl IntoResponse {
    let tracking = ctx.profile.tracking()?;
    let mut repos = Vec::new();

@@ -59,3 +67,39 @@ async fn node_tracking_repos_handler(State(ctx): State<Context>) -> impl IntoRes

    Ok::<_, Error>(Json(repos))
}
+

+
/// Track a new repo.
+
/// `PUT /node/policies/repos/:rid`
+
async fn node_policies_track_handler(
+
    State(ctx): State<Context>,
+
    AuthBearer(token): AuthBearer,
+
    Path(project): Path<Id>,
+
    Query(qs): Query<PoliciesQuery>,
+
) -> impl IntoResponse {
+
    api::auth::validate(&ctx, &token).await?;
+
    let mut node = Node::new(ctx.profile.socket());
+
    node.track_repo(project, qs.scope.unwrap_or_default())?;
+
    if let Some(from) = qs.from {
+
        let results = node.fetch(project, from, DEFAULT_TIMEOUT)?;
+
        return Ok::<_, Error>((
+
            StatusCode::OK,
+
            Json(json!({ "success": true, "results": results })),
+
        ));
+
    }
+

+
    Ok::<_, Error>((StatusCode::OK, Json(json!({ "success": true }))))
+
}
+

+
/// Untrack a repo.
+
/// `DELETE /node/policies/repos/:rid`
+
async fn node_policies_untrack_handler(
+
    State(ctx): State<Context>,
+
    AuthBearer(token): AuthBearer,
+
    Path(project): Path<Id>,
+
) -> impl IntoResponse {
+
    api::auth::validate(&ctx, &token).await?;
+
    let mut node = Node::new(ctx.profile.socket());
+
    node.untrack_repo(project)?;
+

+
    Ok::<_, Error>((StatusCode::OK, Json(json!({ "success": true }))))
+
}