diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/api.rs | 26 | ||||
-rw-r--r-- | src/api/error.rs | 5 | ||||
-rw-r--r-- | src/auth.rs | 6 | ||||
-rw-r--r-- | src/error.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 36 |
5 files changed, 32 insertions, 47 deletions
@@ -1,20 +1,25 @@ -use axum::{response::IntoResponse, routing::get}; +use axum::{http::Uri, response::IntoResponse, routing::get}; use crate::state::AppState; pub mod error; -mod users; +pub mod users; pub fn router() -> axum::Router<AppState> { axum::Router::new() .merge(users::router()) .route("/healthcheck", get(healthcheck)) + .fallback(fallback) } pub async fn healthcheck() -> impl IntoResponse { "success" } +pub async fn fallback(uri: Uri) -> impl IntoResponse { + self::error::Error::RouteNotFound(uri) +} + #[cfg(test)] mod tests { use crate::tests::{setup_test_env, TestResult}; @@ -43,4 +48,21 @@ mod tests { Ok(()) } + + #[sqlx::test] + async fn test_fallback_not_found(pool: PgPool) -> TestResult { + setup_test_env(); + + let router = Router::new().merge(router()).with_state(AppState { pool }); + + let request = Request::builder() + .uri("/does-not-exist") + .body(Body::empty())?; + + let response = router.oneshot(request).await?; + + assert_eq!(StatusCode::NOT_FOUND, response.status()); + + Ok(()) + } } diff --git a/src/api/error.rs b/src/api/error.rs index f5d4291..bd43ce3 100644 --- a/src/api/error.rs +++ b/src/api/error.rs @@ -3,6 +3,9 @@ pub enum Error { #[error("Database error: {0}")] Sqlx(#[from] sqlx::Error), + #[error("Route not found: {0}")] + RouteNotFound(axum::http::Uri), + #[error("User not found")] UserNotFound, @@ -27,7 +30,7 @@ impl axum::response::IntoResponse for Error { use axum::http::StatusCode; let status = match self { - Self::UserNotFound => StatusCode::NOT_FOUND, + Self::RouteNotFound(_) | Self::UserNotFound => StatusCode::NOT_FOUND, Self::EmailExists => StatusCode::CONFLICT, Self::EmailInvalid(_) => StatusCode::UNPROCESSABLE_ENTITY, Self::InvalidToken => StatusCode::UNAUTHORIZED, diff --git a/src/auth.rs b/src/auth.rs index 8756291..0541b8e 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -2,7 +2,7 @@ use argon2::{ password_hash::{rand_core::OsRng, SaltString}, Argon2, PasswordHash, PasswordHasher, PasswordVerifier, }; -use axum::{extract::State, http::StatusCode}; +use axum::{extract::State, http::StatusCode, Router}; use axum_extra::{ headers::{authorization::Basic, Authorization}, routing::Resource, @@ -20,8 +20,8 @@ pub mod claims; pub mod error; pub mod jwt; -pub fn router() -> Resource<AppState> { - Resource::named("auth").index(issue).create(create) +pub fn router() -> Router<AppState> { + axum::Router::new().merge(Resource::named("users").index(issue).create(create)) } pub async fn issue( diff --git a/src/error.rs b/src/error.rs index c9fae0f..89fad78 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,9 +11,6 @@ pub enum Error { #[error("Migration error: {0}")] Migration(#[from] sqlx::migrate::MigrateError), - #[error("Route not found: {0}")] - RouteNotFound(axum::http::Uri), - #[error("API error: {0}")] Api(#[from] crate::api::error::Error), @@ -29,9 +26,6 @@ impl axum::response::IntoResponse for Error { match self { Self::Api(err) => err.into_response(), Self::Auth(err) => err.into_response(), - err @ Self::RouteNotFound(_) => { - (StatusCode::NOT_FOUND, err.to_string()).into_response() - } err => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response(), } } @@ -1,4 +1,3 @@ -use axum::{http::Uri, response::IntoResponse}; use tower_http::{cors::CorsLayer, trace::TraceLayer}; pub use error::{Error, Result}; @@ -12,32 +11,16 @@ pub mod utils; pub fn router() -> axum::Router<state::AppState> { axum::Router::new() .nest("/api", api::router()) - .merge(auth::router()) - .fallback(fallback) + .nest("/auth", auth::router()) // TODO: do this correctly! .layer(CorsLayer::permissive()) .layer(TraceLayer::new_for_http()) } -pub async fn fallback(uri: Uri) -> impl IntoResponse { - Error::RouteNotFound(uri) -} - #[cfg(test)] pub(crate) mod tests { - use crate::state::AppState; - - use super::*; - use std::sync::Once; - use axum::{ - body::Body, - http::{Request, StatusCode}, - Router, - }; - use sqlx::PgPool; - use tower::ServiceExt; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; pub type TestResult<T = (), E = Box<dyn std::error::Error>> = std::result::Result<T, E>; @@ -56,21 +39,4 @@ pub(crate) mod tests { std::env::set_var("JWT_SECRET", JWT_SECRET); }); } - - #[sqlx::test] - async fn test_fallback_not_found(pool: PgPool) -> TestResult { - setup_test_env(); - - let router = Router::new().merge(router()).with_state(AppState { pool }); - - let request = Request::builder() - .uri("/does-not-exist") - .body(Body::empty())?; - - let response = router.oneshot(request).await?; - - assert_eq!(StatusCode::NOT_FOUND, response.status()); - - Ok(()) - } } |