get specific network

This commit is contained in:
c0repwn3r 2023-04-04 09:31:41 -04:00
parent 359f5be936
commit 6d97826050
Signed by: core
GPG Key ID: FDBF740DADDCEECF
2 changed files with 87 additions and 3 deletions

View File

@ -72,6 +72,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
.service(routes::v1::auth::totp::totp_request) .service(routes::v1::auth::totp::totp_request)
.service(routes::v1::networks::get_networks) .service(routes::v1::networks::get_networks)
.service(routes::v1::organization::create_org_request) .service(routes::v1::organization::create_org_request)
.service(routes::v1::networks::get_network_request)
}).bind(CONFIG.server.bind)?.run().await?; }).bind(CONFIG.server.bind)?.run().await?;
Ok(()) Ok(())

View File

@ -1,6 +1,6 @@
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use actix_web::{get, HttpRequest, HttpResponse}; use actix_web::{get, HttpRequest, HttpResponse};
use actix_web::web::{Data, Query}; use actix_web::web::{Data, Path, Query};
use chrono::{TimeZone, Utc}; use chrono::{TimeZone, Utc};
use log::error; use log::error;
use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder}; use sea_orm::{ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, QueryOrder};
@ -26,7 +26,7 @@ pub struct GetNetworksResponseData {
#[serde(rename = "signingCAID")] #[serde(rename = "signingCAID")]
pub signing_ca_id: String, pub signing_ca_id: String,
#[serde(rename = "createdAt")] #[serde(rename = "createdAt")]
pub created_at: String, // 2023-03-22T18:55:47.009Z, %Y-%m-%dT%H-%M-%S.%.3fZ pub created_at: String, // 2023-03-22T18:55:47.009Z, %Y-%m-%dT%H-%M-%S%.3fZ
pub name: String, pub name: String,
#[serde(rename = "lighthousesAsRelays")] #[serde(rename = "lighthousesAsRelays")]
pub lighthouses_as_relays: bool pub lighthouses_as_relays: bool
@ -248,3 +248,86 @@ pub async fn get_networks(opts: Query<GetNetworksQueryParams>, req_info: HttpReq
}, },
}) })
} }
#[get("/v1/networks/{network_id}")]
pub async fn get_network_request(net: Path<String>, req_info: HttpRequest, db: Data<AppState>) -> HttpResponse {
// For this endpoint, you either need to be a fully authenticated user OR a token with networks:list
let session_info = enforce_2fa(&req_info, &db.conn).await.unwrap_or(TokenInfo::NotPresent);
let api_token_info = enforce_api_token(&req_info, &["networks:read"], &db.conn).await.unwrap_or(TokenInfo::NotPresent);
// If neither are present, throw an error
if matches!(session_info, TokenInfo::NotPresent) && matches!(api_token_info, TokenInfo::NotPresent) {
return HttpResponse::Unauthorized().json(APIErrorsResponse {
errors: vec![
APIError {
code: "ERR_UNAUTHORIZED".to_string(),
message: "This endpoint requires either a fully authenticated user or a token with the networks:read scope".to_string(),
path: None,
}
],
})
}
// If both are present, throw an error
if matches!(session_info, TokenInfo::AuthToken(_)) && matches!(api_token_info, TokenInfo::ApiToken(_)) {
return HttpResponse::BadRequest().json(APIErrorsResponse {
errors: vec![
APIError {
code: "ERR_AMBIGUOUS_AUTHENTICATION".to_string(),
message: "Both a user token and an API token with the proper scope was provided. Please only provide one.".to_string(),
path: None
}
],
})
}
let network: Option<network::Model> = match network::Entity::find().filter(network::Column::Id.eq(net.into_inner())).one(&db.conn).await {
Ok(r) => r,
Err(e) => {
error!("database error: {}", e);
return HttpResponse::InternalServerError().json(APIErrorsResponse {
errors: vec![
APIError {
code: "ERR_DB_ERROR".to_string(),
message: "There was an error performing the database request, please try again later.".to_string(),
path: None,
}
],
});
}
};
if let Some(network) = network {
HttpResponse::Ok().json(GetNetworkResponse {
data: GetNetworksResponseData {
id: network.id,
cidr: network.cidr,
organization_id: network.organization,
signing_ca_id: network.signing_ca,
created_at: Utc.timestamp_opt(network.created_at, 0).unwrap().format("%Y-%m-%dT%H-%M-%S%.3fZ").to_string(),
name: network.name,
lighthouses_as_relays: network.lighthouses_as_relays,
},
metadata: GetNetworkResponseMetadata {},
})
} else {
HttpResponse::NotFound().json(APIErrorsResponse {
errors: vec![
APIError {
code: "ERR_MISSING_NETWORK".to_string(),
message: "Network does not exist".to_string(),
path: None,
}
],
})
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GetNetworkResponse {
pub data: GetNetworksResponseData,
pub metadata: GetNetworkResponseMetadata
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GetNetworkResponseMetadata {}