added ErrorResponse for wireguard routes

This commit is contained in:
Jędrzej Stuczyński
2023-10-11 16:03:04 +01:00
parent 3260ba84fe
commit 44db2b8d71
5 changed files with 74 additions and 22 deletions
@@ -69,3 +69,8 @@ impl<T> Deref for SignedData<T> {
&self.data
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ErrorResponse {
pub message: String,
}
@@ -4,6 +4,8 @@
use crate::http::api::v1::gateway::client_interfaces::wireguard::{
WireguardAppState, WireguardAppStateInner,
};
use crate::http::router::types::RequestError;
use crate::wireguard::error::WireguardError;
use crate::wireguard::types::{
Client, ClientMessage, ClientMessageRequest, ClientPublicKey, InitMessage,
};
@@ -11,15 +13,20 @@ use axum::extract::{Path, State};
use axum::http::StatusCode;
use axum::Json;
use std::str::FromStr;
use tracing::warn;
async fn process_final_message(client: Client, state: &WireguardAppStateInner) -> StatusCode {
async fn process_final_message(
client: Client,
state: &WireguardAppStateInner,
) -> Result<StatusCode, RequestError> {
let preshared_nonce = {
let in_progress_ro = state.registration_in_progress.read().await;
if let Some(nonce) = in_progress_ro.get(&client.pub_key()) {
*nonce
} else {
return StatusCode::BAD_REQUEST;
return Err(RequestError::from_err(
WireguardError::RegistrationNotInProgress,
StatusCode::BAD_REQUEST,
));
}
};
@@ -35,10 +42,13 @@ async fn process_final_message(client: Client, state: &WireguardAppStateInner) -
let mut registry_rw = state.client_registry.write().await;
registry_rw.insert(client.socket(), client);
}
return StatusCode::OK;
Ok(StatusCode::OK)
} else {
Err(RequestError::from_err(
WireguardError::MacVerificationFailure,
StatusCode::BAD_REQUEST,
))
}
StatusCode::BAD_REQUEST
}
async fn process_init_message(init_message: InitMessage, state: &WireguardAppStateInner) -> u64 {
@@ -51,25 +61,22 @@ async fn process_init_message(init_message: InitMessage, state: &WireguardAppSta
pub(crate) async fn register_client(
State(state): State<WireguardAppState>,
Json(payload): Json<ClientMessageRequest>,
) -> (StatusCode, Json<Option<u64>>) {
) -> Result<(StatusCode, Json<Option<u64>>), RequestError> {
let Some(state) = state.inner() else {
return (StatusCode::NOT_IMPLEMENTED, Json(None));
return Ok((StatusCode::NOT_IMPLEMENTED, Json(None)));
};
match ClientMessage::try_from(payload) {
Ok(payload) => match payload {
ClientMessage::Init(i) => (
ClientMessage::Init(i) => Ok((
StatusCode::OK,
Json(Some(process_init_message(i, state).await)),
),
ClientMessage::Final(client) => {
(process_final_message(client, state).await, Json(None))
}
)),
ClientMessage::Final(client) => process_final_message(client, state)
.await
.map(|code| (code, Json(None))),
},
Err(err) => {
warn!("failed to deserialize received request: {err}");
(StatusCode::BAD_REQUEST, Json(None))
}
Err(err) => Err(RequestError::from_err(err, StatusCode::BAD_REQUEST)),
}
}
@@ -97,13 +104,13 @@ pub(crate) async fn get_all_clients(
pub(crate) async fn get_client(
Path(pub_key): Path<String>,
State(state): State<WireguardAppState>,
) -> (StatusCode, Json<Vec<Client>>) {
) -> Result<(StatusCode, Json<Vec<Client>>), RequestError> {
let Some(state) = state.inner() else {
return (StatusCode::NOT_IMPLEMENTED, Json(Vec::new()));
return Ok((StatusCode::NOT_IMPLEMENTED, Json(Vec::new())));
};
let pub_key = match ClientPublicKey::from_str(&pub_key) {
Ok(pub_key) => pub_key,
Err(_) => return (StatusCode::BAD_REQUEST, Json(vec![])),
Err(err) => return Err(RequestError::from_err(err, StatusCode::BAD_REQUEST)),
};
let registry_ro = state.client_registry.read().await;
@@ -118,9 +125,9 @@ pub(crate) async fn get_client(
})
.collect::<Vec<Client>>();
if clients.is_empty() {
return (StatusCode::NOT_FOUND, Json(clients));
return Ok((StatusCode::NOT_FOUND, Json(clients)));
}
(StatusCode::OK, Json(clients))
Ok((StatusCode::OK, Json(clients)))
}
// pub type ClientResponse = FormattedResponse<()>;
+1
View File
@@ -17,6 +17,7 @@ use std::net::SocketAddr;
pub mod api;
pub mod landing_page;
pub mod types;
#[derive(Debug, Clone)]
pub struct Config {
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use nym_node_requests::api::ErrorResponse;
pub(crate) struct RequestError {
pub(crate) inner: ErrorResponse,
pub(crate) status: StatusCode,
}
impl RequestError {
pub(crate) fn new<S: Into<String>>(message: S, status: StatusCode) -> Self {
RequestError {
inner: ErrorResponse {
message: message.into(),
},
status,
}
}
pub(crate) fn from_err<E: std::error::Error>(err: E, status: StatusCode) -> Self {
Self::new(err.to_string(), status)
}
}
impl IntoResponse for RequestError {
fn into_response(self) -> Response {
(self.status, Json(self.inner)).into_response()
}
}
+6
View File
@@ -40,4 +40,10 @@ pub enum WireguardError {
#[source]
source: AddrParseError,
},
#[error("the client is currently not in the process of being registered")]
RegistrationNotInProgress,
#[error("the client mac failed to get verified correctly")]
MacVerificationFailure,
}