expanded on gateway-related endpoints

This commit is contained in:
Jędrzej Stuczyński
2023-10-02 15:07:16 +01:00
parent ca6b09ce8d
commit e8d601df67
10 changed files with 236 additions and 37 deletions
Generated
+37 -16
View File
@@ -2111,6 +2111,7 @@ dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest 0.10.7",
"fiat-crypto",
"platforms",
"rustc_version 0.4.0",
@@ -2706,6 +2707,20 @@ dependencies = [
"zeroize",
]
[[package]]
name = "ed25519-dalek"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980"
dependencies = [
"curve25519-dalek 4.1.0",
"ed25519 2.2.2",
"rand_core 0.6.4",
"serde",
"sha2 0.10.7",
"zeroize",
]
[[package]]
name = "ed25519-zebra"
version = "3.1.0"
@@ -2868,7 +2883,7 @@ dependencies = [
"libp2p 0.51.3",
"libp2p-identity",
"log",
"lru 0.10.0",
"lru 0.10.1",
"nym-config",
"nym-ephemera-common",
"nym-task",
@@ -4610,7 +4625,7 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c
dependencies = [
"asn1_der",
"bs58 0.4.0",
"ed25519-dalek",
"ed25519-dalek 1.0.1",
"either",
"fnv",
"futures",
@@ -4777,12 +4792,12 @@ dependencies = [
[[package]]
name = "libp2p-identity"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e2d584751cecb2aabaa56106be6be91338a60a0f4e420cf2af639204f596fc1"
checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce"
dependencies = [
"bs58 0.4.0",
"ed25519-dalek",
"ed25519-dalek 2.0.0",
"log",
"multiaddr 0.17.1",
"multihash",
@@ -5384,9 +5399,9 @@ dependencies = [
[[package]]
name = "lru"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03f1160296536f10c833a82dca22267d5486734230d47bf00bf435885814ba1e"
checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670"
dependencies = [
"hashbrown 0.13.2",
]
@@ -6390,7 +6405,7 @@ dependencies = [
"cipher 0.4.4",
"ctr 0.9.2",
"digest 0.10.7",
"ed25519-dalek",
"ed25519-dalek 1.0.1",
"generic-array 0.14.7",
"hkdf 0.12.3",
"hmac 0.12.1",
@@ -8712,9 +8727,9 @@ dependencies = [
[[package]]
name = "refinery"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb0436d0dd7bd8d4fce1e828751fa79742b08e35f27cfea7546f8a322b5ef24"
checksum = "529664dbccc0a296947615c997a857912d72d1c44be1fafb7bae54ecfa7a8c24"
dependencies = [
"refinery-core",
"refinery-macros",
@@ -8722,9 +8737,9 @@ dependencies = [
[[package]]
name = "refinery-core"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19206547cd047e8f4dfa6b20c30d3ecaf24be05841b6aa0aa926a47a3d0662bb"
checksum = "e895cb870cf06e92318cbbeb701f274d022d5ca87a16fa8244e291cd035ef954"
dependencies = [
"async-trait",
"cfg-if",
@@ -8743,9 +8758,9 @@ dependencies = [
[[package]]
name = "refinery-macros"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d94d4b9241859ba19eaa5c04c86e782eb3aa0aae2c5868e0cfa90c856e58a174"
checksum = "123e8b80f8010c3ae38330c81e76938fc7adf6cdbfbaad20295bb8c22718b4f1"
dependencies = [
"proc-macro2",
"quote",
@@ -9705,6 +9720,12 @@ dependencies = [
"dirs 4.0.0",
]
[[package]]
name = "shlex"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]]
name = "signal-hook"
version = "0.3.17"
@@ -9757,9 +9778,9 @@ dependencies = [
[[package]]
name = "siphasher"
version = "0.3.10"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
checksum = "54ac45299ccbd390721be55b412d41931911f654fa99e2cb8bfb57184b2061fe"
[[package]]
name = "slab"
+13 -4
View File
@@ -11,9 +11,17 @@ use nym_sphinx::addressing::clients::Recipient;
use nym_task::TaskClient;
fn load_gateway_details(
_config: &Config,
config: &Config,
) -> Result<http::api::v1::gateway::types::Gateway, GatewayError> {
Ok(http::api::v1::gateway::types::Gateway {})
Ok(http::api::v1::gateway::types::Gateway {
client_interfaces: http::api::v1::gateway::types::ClientInterfaces {
wireguard: None,
mixnet_websockets: Some(http::api::v1::gateway::types::WebSockets {
ws_port: config.gateway.clients_port,
wss_port: None,
}),
},
})
}
fn load_host_details(
@@ -31,7 +39,7 @@ fn load_host_details(
Ok(http::api::v1::node::types::HostInformation {
// TODO: this should be extracted differently, i.e. it's the issue of the public/private address
ip_address: vec![config.gateway.listening_address],
ip_address: vec![config.gateway.listening_address.to_string()],
hostname: None,
keys: http::api::v1::node::types::HostKeys {
ed25519: identity_public_key.to_base58_string(),
@@ -69,7 +77,7 @@ fn load_network_requester_details(
Ok(http::api::v1::network_requester::types::NetworkRequester {
encoded_identity_key: identity_public_key.to_base58_string(),
encoded_sphinx_key: dh_public_key.to_base58_string(),
encoded_x25519_key: dh_public_key.to_base58_string(),
address: Recipient::new(
identity_public_key,
dh_public_key,
@@ -91,6 +99,7 @@ pub(crate) fn start_http_api(
// and makes the code a bit nicer to manage. on top of it, all of it will refactored anyway at some point
// (famous last words, eh? - 22.09.23)
// TODO: load private key, set zeroizing wrapper and sign whatever responses we need to sign
let mut config =
nym_node::http::Config::new(bin_info_owned!(), load_host_details(gateway_config)?)
.with_gateway(load_gateway_details(gateway_config)?);
+6 -1
View File
@@ -29,7 +29,12 @@ mime = "0.3.17"
hyper = { workspace = true }
tower = { version = "0.4.13" }
tower-http = { version = "0.4.4", features = ["fs"] }
utoipa = { workspace = true, features = [] } # can't use `"axum_extras"` feature because ephemera uses `"actix_extras"` -.-'
# `actix_extras`? what the hell?
# hear me out first!
# we can't use `axum_extras` because of freaking ephemera that depends on `actix_extras`.
# however, it seems that pulling in `actix_extras` pulls in just enough shared features to improve `IntoParams` for our Query attributes
utoipa = { workspace = true, features = ["actix_extras"] } # can't use `"axum_extras"` feature because ephemera uses `"actix_extras"` -.-'
utoipa-swagger-ui = { workspace = true, features = ["axum"] }
# if we ever wanted redoc/rapidoc bridges:
@@ -0,0 +1,119 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::http::api::v1::gateway::types::{ClientInterfaces, WebSockets, Wireguard};
use crate::http::api::{FormattedResponse, OutputParams};
use crate::http::state::AppState;
use axum::extract::Query;
use axum::http::StatusCode;
use axum::routing::get;
use axum::Router;
pub(crate) mod routes {
pub(crate) const INTERFACES: &str = "/";
pub(crate) const WIREGUARD: &str = "/wireguard";
pub(crate) const WEBSOCKETS: &str = "/mixnet-websockets";
}
pub(crate) fn routes(interfaces: Option<ClientInterfaces>) -> Router<AppState> {
Router::new()
.route(
routes::INTERFACES,
get({
let interfaces = interfaces.clone();
move |query| client_interfaces(interfaces, query)
}),
)
.route(
routes::WEBSOCKETS,
get({
let websockets = interfaces.as_ref().and_then(|i| i.mixnet_websockets);
move |query| mixnet_websockets(websockets, query)
}),
)
.route(
routes::WIREGUARD,
get({
let wireguard_info = interfaces.and_then(|i| i.wireguard);
move |query| wireguard(wireguard_info, query)
}),
)
}
/// Returns client interfaces supported by this gateway.
#[utoipa::path(
get,
path = "/client-interfaces",
context_path = "/api/v1/gateway",
tag = "Gateway",
responses(
(status = 501, description = "the endpoint hasn't been implemented yet"),
(status = 200, content(
("application/json" = ClientInterfaces),
("application/yaml" = ClientInterfaces)
))
),
params(OutputParams)
)]
pub(crate) async fn client_interfaces(
interfaces: Option<ClientInterfaces>,
Query(output): Query<OutputParams>,
) -> Result<ClientInterfacesResponse, StatusCode> {
let interfaces = interfaces.ok_or(StatusCode::NOT_IMPLEMENTED)?;
let output = output.output.unwrap_or_default();
Ok(output.to_response(interfaces))
}
pub type ClientInterfacesResponse = FormattedResponse<ClientInterfaces>;
/// Returns client interfaces supported by this gateway.
#[utoipa::path(
get,
path = "/wireguard",
context_path = "/api/v1/gateway/client-interfaces",
tag = "Gateway",
responses(
(status = 501, description = "the endpoint hasn't been implemented yet"),
(status = 200, content(
("application/json" = Wireguard),
("application/yaml" = Wireguard)
))
),
params(OutputParams)
)]
pub(crate) async fn wireguard(
wireguard: Option<Wireguard>,
Query(output): Query<OutputParams>,
) -> Result<WireguardResponse, StatusCode> {
let wireguard = wireguard.ok_or(StatusCode::NOT_IMPLEMENTED)?;
let output = output.output.unwrap_or_default();
Ok(output.to_response(wireguard))
}
pub type WireguardResponse = FormattedResponse<Wireguard>;
/// Returns client interfaces supported by this gateway.
#[utoipa::path(
get,
path = "/mixnet-websockets",
context_path = "/api/v1/gateway/client-interfaces",
tag = "Gateway",
responses(
(status = 501, description = "the endpoint hasn't been implemented yet"),
(status = 200, content(
("application/json" = WebSockets),
("application/yaml" = WebSockets)
))
),
params(OutputParams)
)]
pub(crate) async fn mixnet_websockets(
websockets: Option<WebSockets>,
Query(output): Query<OutputParams>,
) -> Result<MixnetWebSocketsResponse, StatusCode> {
let websockets = websockets.ok_or(StatusCode::NOT_IMPLEMENTED)?;
let output = output.output.unwrap_or_default();
Ok(output.to_response(websockets))
}
pub type MixnetWebSocketsResponse = FormattedResponse<WebSockets>;
+14 -7
View File
@@ -5,11 +5,13 @@ use crate::http::state::AppState;
use axum::routing::get;
use axum::Router;
pub mod client_interfaces;
pub mod root;
pub mod types;
pub(crate) mod routes {
pub(crate) const ROOT: &str = "/";
pub(crate) const CLIENT_INTERFACES: &str = "/client-interfaces";
}
#[derive(Debug, Clone, Default)]
@@ -18,11 +20,16 @@ pub struct Config {
}
pub(crate) fn routes(config: Config) -> Router<AppState> {
Router::new().route(
routes::ROOT,
get({
let gateway_details = config.details;
move |query| root::root_gateway(gateway_details, query)
}),
)
Router::new()
.route(
routes::ROOT,
get({
let gateway_details = config.details.clone();
move |query| root::root_gateway(gateway_details, query)
}),
)
.nest(
routes::CLIENT_INTERFACES,
client_interfaces::routes(config.details.map(|g| g.client_interfaces)),
)
}
@@ -25,6 +25,7 @@ pub(crate) async fn root_gateway(
details: Option<Gateway>,
Query(output): Query<OutputParams>,
) -> Result<GatewayResponse, StatusCode> {
println!("query: {:?}", output);
let details = details.ok_or(StatusCode::NOT_IMPLEMENTED)?;
let output = output.output.unwrap_or_default();
Ok(output.to_response(details))
@@ -6,10 +6,29 @@ use utoipa::ToSchema;
#[derive(Serialize, Debug, Clone, ToSchema)]
pub struct Gateway {
// /// Base58 encoded ed25519 EdDSA public key of the gateway used for deriving shared keys with clients
// /// and for signing any messages
// pub encoded_identity_key: String,
//
// /// Base58-encoded x25519 public key used for sphinx key derivation.
// pub encoded_sphinx_key: String,
pub client_interfaces: ClientInterfaces,
}
#[derive(Serialize, Debug, Clone, ToSchema)]
pub struct Wireguard {
#[schema(example = 1234, default = 51820)]
pub port: u16,
pub public_key: String,
}
#[derive(Serialize, Debug, Clone, ToSchema)]
pub struct ClientInterfaces {
pub wireguard: Option<Wireguard>,
pub mixnet_websockets: Option<WebSockets>,
// pub mixnet_tcp:
}
#[derive(Serialize, Debug, Clone, Copy, ToSchema)]
pub struct WebSockets {
#[schema(example = 1234, default = 9000)]
pub ws_port: u16,
pub wss_port: Option<u16>,
}
@@ -10,8 +10,21 @@ pub struct NetworkRequester {
pub encoded_identity_key: String,
/// Base58-encoded x25519 public key used for performing key exchange with remote clients.
pub encoded_sphinx_key: String,
pub encoded_x25519_key: String,
/// Nym address of this network requester.
pub address: String,
}
// #[derive(Serialize, Debug, Clone, ToSchema)]
// pub struct ExitPolicy {
// // pub allowed_ports:
// // pub deny_list: DenyList,
// }
//
// #[derive(Serialize, Debug, Clone, ToSchema)]
// pub struct DenyListEntry {
// // pub ports:
// // pub ips:
// pub description: String,
// }
@@ -3,7 +3,6 @@
pub(crate) use nym_bin_common::build_information::BinaryBuildInformationOwned;
use serde::Serialize;
use std::net::IpAddr;
use utoipa::ToSchema;
#[derive(Clone, Default, Debug, Copy, ToSchema, Serialize)]
@@ -16,7 +15,7 @@ pub struct NodeRoles {
#[derive(Clone, Default, Debug, ToSchema, Serialize)]
pub struct HostInformation {
/// Ip address(es) of this host, such as `1.1.1.1`.
pub ip_address: Vec<IpAddr>,
pub ip_address: Vec<String>,
/// Optional hostname of this node, for example `nymtech.net`.
pub hostname: Option<String>,
@@ -15,6 +15,9 @@ use utoipa_swagger_ui::SwaggerUi;
api::v1::node::host_information::host_information,
api::v1::node::roles::roles,
api::v1::gateway::root::root_gateway,
api::v1::gateway::client_interfaces::client_interfaces,
api::v1::gateway::client_interfaces::wireguard,
api::v1::gateway::client_interfaces::mixnet_websockets,
api::v1::mixnode::root::root_mixnode,
api::v1::network_requester::root::root_network_requester,
),
@@ -26,6 +29,9 @@ use utoipa_swagger_ui::SwaggerUi;
api::v1::node::types::HostKeys,
api::v1::node::types::NodeRoles,
api::v1::gateway::types::Gateway,
api::v1::gateway::types::Wireguard,
api::v1::gateway::types::ClientInterfaces,
api::v1::gateway::types::WebSockets,
api::v1::mixnode::types::Mixnode,
api::v1::network_requester::types::NetworkRequester,
))