Include auth in self description

This commit is contained in:
Bogdan-Ștefan Neacşu
2024-07-03 13:50:44 +00:00
parent a4eb3a7dbf
commit fec3d46b33
12 changed files with 152 additions and 1 deletions
+9
View File
@@ -605,6 +605,9 @@ pub struct NymNodeDescription {
#[serde(default)]
pub ip_packet_router: Option<IpPacketRouterDetails>,
#[serde(default)]
pub authenticator: Option<AuthenticatorDetails>,
// for now we only care about their ws/wss situation, nothing more
pub mixnet_websockets: WebSockets,
}
@@ -639,6 +642,12 @@ pub struct IpPacketRouterDetails {
pub address: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct AuthenticatorDetails {
/// address of the embedded authenticator
pub address: String,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct ApiHealthResponse {
pub status: ApiStatus,
+10 -1
View File
@@ -8,7 +8,7 @@ use crate::support::config;
use crate::support::config::DEFAULT_NODE_DESCRIBE_BATCH_SIZE;
use futures::{stream, StreamExt};
use nym_api_requests::models::{
IpPacketRouterDetails, NetworkRequesterDetails, NymNodeDescription,
AuthenticatorDetails, IpPacketRouterDetails, NetworkRequesterDetails, NymNodeDescription,
};
use nym_config::defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT};
use nym_contracts_common::IdentityKey;
@@ -186,12 +186,21 @@ async fn get_gateway_description(
None
};
let authenticator = if let Ok(auth) = client.get_authenticator().await {
Some(AuthenticatorDetails {
address: auth.address,
})
} else {
None
};
let description = NymNodeDescription {
host_information: host_info.data.into(),
last_polled: OffsetDateTime::now_utc().into(),
build_information: build_info,
network_requester,
ip_packet_router,
authenticator,
mixnet_websockets: websockets.into(),
auxiliary_details,
};
@@ -0,0 +1,23 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use axum::routing::get;
use axum::Router;
use nym_node_requests::api::v1::authenticator::models;
pub mod root;
#[derive(Debug, Clone, Default)]
pub struct Config {
pub details: Option<models::Authenticator>,
}
pub(crate) fn routes<S: Send + Sync + 'static + Clone>(config: Config) -> Router<S> {
Router::new().route(
"/",
get({
let authenticator_details = config.details;
move |query| root::root_authenticator(authenticator_details, query)
}),
)
}
@@ -0,0 +1,33 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::router::api::{FormattedResponse, OutputParams};
use axum::extract::Query;
use axum::http::StatusCode;
use nym_node_requests::api::v1::authenticator::models::Authenticator;
/// Returns root authenticator information
#[utoipa::path(
get,
path = "",
context_path = "/api/v1/authenticator",
tag = "Authenticator",
responses(
(status = 501, description = "the endpoint hasn't been implemented yet"),
(status = 200, content(
("application/json" = Authenticator),
("application/yaml" = Authenticator)
))
),
params(OutputParams)
)]
pub(crate) async fn root_authenticator(
details: Option<Authenticator>,
Query(output): Query<OutputParams>,
) -> Result<AuthenticatorResponse, StatusCode> {
let details = details.ok_or(StatusCode::NOT_IMPLEMENTED)?;
let output = output.output.unwrap_or_default();
Ok(output.to_response(details))
}
pub type AuthenticatorResponse = FormattedResponse<Authenticator>;
@@ -6,6 +6,7 @@ use axum::routing::get;
use axum::Router;
use nym_node_requests::routes::api::v1;
pub mod authenticator;
pub mod gateway;
pub mod health;
pub mod ip_packet_router;
@@ -23,6 +24,7 @@ pub struct Config {
pub mixnode: mixnode::Config,
pub network_requester: network_requester::Config,
pub ip_packet_router: ip_packet_router::Config,
pub authenticator: authenticator::Config,
}
pub(super) fn routes(config: Config) -> Router<AppState> {
@@ -39,6 +41,10 @@ pub(super) fn routes(config: Config) -> Router<AppState> {
v1::IP_PACKET_ROUTER,
ip_packet_router::routes(config.ip_packet_router),
)
.nest(
v1::AUTHENTICATOR,
authenticator::routes(config.authenticator),
)
.merge(node::routes(config.node))
.merge(openapi::route())
}
@@ -8,6 +8,7 @@ use crate::NymNodeHTTPServer;
use axum::response::Redirect;
use axum::routing::get;
use axum::Router;
use nym_node_requests::api::v1::authenticator::models::Authenticator;
use nym_node_requests::api::v1::gateway::models::{Gateway, Wireguard};
use nym_node_requests::api::v1::ip_packet_router::models::IpPacketRouter;
use nym_node_requests::api::v1::mixnode::models::Mixnode;
@@ -53,6 +54,7 @@ impl Config {
mixnode: Default::default(),
network_requester: Default::default(),
ip_packet_router: Default::default(),
authenticator: Default::default(),
},
},
}
@@ -147,6 +149,12 @@ impl Config {
self.api.v1_config.ip_packet_router.details = Some(ip_packet_router);
self
}
#[must_use]
pub fn with_authenticator_details(mut self, authenticator: Authenticator) -> Self {
self.api.v1_config.authenticator.details = Some(authenticator);
self
}
}
pub struct NymNodeRouter {
@@ -9,6 +9,7 @@ use async_trait::async_trait;
use nym_bin_common::build_information::BinaryBuildInformationOwned;
use nym_http_api_client::{ApiClient, HttpClientError};
use crate::api::v1::authenticator::models::Authenticator;
use crate::api::v1::health::models::NodeHealth;
use crate::api::v1::ip_packet_router::models::IpPacketRouter;
use crate::api::v1::network_requester::exit_policy::models::UsedExitPolicy;
@@ -63,6 +64,11 @@ pub trait NymNodeApiClientExt: ApiClient {
self.get_json_from(routes::api::v1::ip_packet_router_absolute())
.await
}
async fn get_authenticator(&self) -> Result<Authenticator, NymNodeApiClientError> {
self.get_json_from(routes::api::v1::authenticator_absolute())
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
@@ -0,0 +1,4 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod models;
@@ -0,0 +1,18 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
pub struct Authenticator {
/// Base58 encoded ed25519 EdDSA public key of the authenticator.
pub encoded_identity_key: String,
/// Base58-encoded x25519 public key used for performing key exchange with remote clients.
pub encoded_x25519_key: String,
/// Nym address of this ip packet router.
pub address: String,
}
@@ -1,6 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod authenticator;
pub mod gateway;
pub mod health;
pub mod ip_packet_router;
+2
View File
@@ -42,6 +42,7 @@ pub mod routes {
pub const METRICS: &str = "/metrics";
pub const NETWORK_REQUESTER: &str = "/network-requester";
pub const IP_PACKET_ROUTER: &str = "/ip-packet-router";
pub const AUTHENTICATOR: &str = "/authenticator";
// define helper functions to get absolute routes
absolute_route!(health_absolute, v1_absolute(), HEALTH);
@@ -57,6 +58,7 @@ pub mod routes {
absolute_route!(metrics_absolute, v1_absolute(), METRICS);
absolute_route!(network_requester_absolute, v1_absolute(), NETWORK_REQUESTER);
absolute_route!(ip_packet_router_absolute, v1_absolute(), IP_PACKET_ROUTER);
absolute_route!(authenticator_absolute, v1_absolute(), AUTHENTICATOR);
absolute_route!(swagger_absolute, v1_absolute(), SWAGGER);
pub mod metrics {
+32
View File
@@ -106,6 +106,9 @@ pub struct ExitGatewayData {
ipr_ed25519: ed25519::PublicKey,
ipr_x25519: x25519::PublicKey,
auth_ed25519: ed25519::PublicKey,
auth_x25519: x25519::PublicKey,
}
impl ExitGatewayData {
@@ -236,11 +239,24 @@ impl ExitGatewayData {
"ip packet router x25519",
)?;
let auth_paths = &config.storage_paths.authenticator;
let auth_ed25519 = load_key(
&auth_paths.public_ed25519_identity_key_file,
"authenticator ed25519",
)?;
let auth_x25519 = load_key(
&auth_paths.public_x25519_diffie_hellman_key_file,
"authenticator x25519",
)?;
Ok(ExitGatewayData {
nr_ed25519,
nr_x25519,
ipr_ed25519,
ipr_x25519,
auth_ed25519,
auth_x25519,
})
}
}
@@ -411,6 +427,14 @@ impl NymNode {
)
}
fn exit_authenticator_address(&self) -> Recipient {
Recipient::new(
self.exit_gateway.auth_ed25519,
self.exit_gateway.auth_x25519,
*self.ed25519_identity_keys.public_key(),
)
}
fn x25519_wireguard_key(&self) -> &x25519::PublicKey {
self.wireguard.inner.keypair().public_key()
}
@@ -575,6 +599,13 @@ impl NymNode {
encoded_x25519_key: self.exit_gateway.ipr_x25519.to_base58_string(),
address: self.exit_ip_packet_router_address().to_string(),
};
let auth_details = api_requests::v1::authenticator::models::Authenticator {
encoded_identity_key: self.exit_gateway.auth_ed25519.to_base58_string(),
encoded_x25519_key: self.exit_gateway.auth_x25519.to_base58_string(),
address: self.exit_authenticator_address().to_string(),
};
let exit_policy_details =
api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy {
enabled: true,
@@ -594,6 +625,7 @@ impl NymNode {
.with_gateway_details(gateway_details)
.with_network_requester_details(nr_details)
.with_ip_packet_router_details(ipr_details)
.with_authenticator_details(auth_details)
.with_used_exit_policy(exit_policy_details)
.with_description(self.description.clone())
.with_auxiliary_details(auxiliary_details);