fix: put auth errors in good place

This commit is contained in:
2026-07-14 11:20:06 +02:00
parent 63e57153dd
commit 67312cb7a4
7 changed files with 76 additions and 54 deletions
Generated
+33 -19
View File
@@ -257,7 +257,7 @@ dependencies = [
"thiserror 2.0.18", "thiserror 2.0.18",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tower-http", "tower-http 0.7.0",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"utoipa", "utoipa",
@@ -267,9 +267,9 @@ dependencies = [
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.44" version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [ dependencies = [
"iana-time-zone", "iana-time-zone",
"js-sys", "js-sys",
@@ -1222,14 +1222,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]] [[package]]
name = "libredox" name = "libredox"
version = "0.1.16" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"libc", "libc",
"plain", "plain",
"redox_syscall 0.7.5", "redox_syscall 0.9.0",
] ]
[[package]] [[package]]
@@ -1369,11 +1369,10 @@ dependencies = [
[[package]] [[package]]
name = "num-iter" name = "num-iter"
version = "0.1.45" version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b"
dependencies = [ dependencies = [
"autocfg",
"num-integer", "num-integer",
"num-traits", "num-traits",
] ]
@@ -1693,9 +1692,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.7.5" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@@ -1763,7 +1762,7 @@ dependencies = [
"tokio-rustls", "tokio-rustls",
"tokio-util", "tokio-util",
"tower", "tower",
"tower-http", "tower-http 0.6.11",
"tower-service", "tower-service",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
@@ -2021,9 +2020,9 @@ dependencies = [
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.6" version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures 0.2.17", "cpufeatures 0.2.17",
@@ -2617,6 +2616,21 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "tower-http"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b11f75e912b0c2be01b63d8cf8057b8c3f97cf34abb3d431a3a4c8675498e233"
dependencies = [
"bitflags",
"bytes",
"http",
"percent-encoding",
"pin-project-lite",
"tower-layer",
"tower-service",
]
[[package]] [[package]]
name = "tower-layer" name = "tower-layer"
version = "0.3.3" version = "0.3.3"
@@ -2793,9 +2807,9 @@ dependencies = [
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.23.2" version = "1.23.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" checksum = "ea5fab0d6c3c01ae70085a09cb03d4c7a1d6314e2b3e075392783396d724ca0a"
dependencies = [ dependencies = [
"getrandom 0.4.2", "getrandom 0.4.2",
"js-sys", "js-sys",
@@ -3007,14 +3021,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [ dependencies = [
"webpki-roots 1.0.7", "webpki-roots 1.0.8",
] ]
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "1.0.7" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
dependencies = [ dependencies = [
"rustls-pki-types", "rustls-pki-types",
] ]
+3 -3
View File
@@ -20,9 +20,9 @@ dotenvy = "0.15"
thiserror = "2.0.18" thiserror = "2.0.18"
tokio-stream = "0.1" tokio-stream = "0.1"
futures = "0.3" futures = "0.3"
chrono = { version = "0.4.44", features = ["serde"] } chrono = { version = "0.4.45", features = ["serde"] }
uuid = { version = "1.23.2", features = ["v4", "serde"] } uuid = { version = "1.23.5", features = ["v4", "serde"] }
tower-http = { version = "0.6.11", features = ["cors"] } tower-http = { version = "0.7.0", features = ["cors"] }
tracing = "0.1.44" tracing = "0.1.44"
tracing-subscriber = { version = "0.3", features = ["env-filter"]} tracing-subscriber = { version = "0.3", features = ["env-filter"]}
sqlx = { version = "0.8.6", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros"] } sqlx = { version = "0.8.6", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros"] }
+1 -13
View File
@@ -1,3 +1,4 @@
use crate::api::middlewares::errors::AuthMiddlewareError;
use crate::databases::errors::DbError; use crate::databases::errors::DbError;
use crate::providers::keycloak::errors::AuthError; use crate::providers::keycloak::errors::AuthError;
use crate::providers::ollama::errors::LlmError; use crate::providers::ollama::errors::LlmError;
@@ -7,7 +8,6 @@ use axum::Json;
use axum::http::StatusCode; use axum::http::StatusCode;
use axum::response::{IntoResponse, Response}; use axum::response::{IntoResponse, Response};
use serde::Serialize; use serde::Serialize;
use thiserror::Error;
use utoipa::ToSchema; use utoipa::ToSchema;
#[derive(Serialize, ToSchema)] #[derive(Serialize, ToSchema)]
@@ -25,18 +25,6 @@ pub struct ApiError {
pub message: String, pub message: String,
} }
#[derive(Debug, Error)]
pub enum AuthMiddlewareError {
#[error("invalid authorization format")]
InvalidAuthorizationFormat,
#[error("authentication required")]
AuthenticationRequired,
#[error("insufficient permissions")]
Forbidden,
}
impl From<AuthMiddlewareError> for ApiError { impl From<AuthMiddlewareError> for ApiError {
fn from(err: AuthMiddlewareError) -> Self { fn from(err: AuthMiddlewareError) -> Self {
match err { match err {
+2 -1
View File
@@ -1,4 +1,5 @@
use crate::api::errors::{ApiError, AuthMiddlewareError}; use crate::api::errors::ApiError;
use crate::api::middlewares::errors::AuthMiddlewareError;
use crate::api::state::SharedState; use crate::api::state::SharedState;
use axum::{ use axum::{
+13
View File
@@ -0,0 +1,13 @@
use thiserror::Error;
#[derive(Debug, Error)]
pub enum AuthMiddlewareError {
#[error("invalid authorization format")]
InvalidAuthorizationFormat,
#[error("authentication required")]
AuthenticationRequired,
#[error("insufficient permissions")]
Forbidden,
}
+1
View File
@@ -1 +1,2 @@
pub mod auth; pub mod auth;
pub mod errors;
+21 -16
View File
@@ -16,22 +16,23 @@ async fn openapi_json() -> Json<utoipa::openapi::OpenApi> {
Json(ApiDoc::openapi()) Json(ApiDoc::openapi())
} }
fn public_router() -> Router<SharedState> { fn llm_router() -> Router<SharedState> {
Router::new().route("/docs.json", get(openapi_json))
}
pub fn protected_router() -> Router<SharedState> {
Router::new() Router::new()
.route("/models", get(llm::list_models)) .route("/models", get(llm::list_models))
.route("/completions", post(llm::completions)) .route("/completions", post(llm::completions))
.route("/chat/completions", post(llm::chat_completions)) .route("/chat/completions", post(llm::chat_completions))
.route("/models/{model}/load", post(llm::load_model)) .route("/models/{model}/load", post(llm::load_model))
// .route("/models/{model}/unload", post(models::unload_model)) }
.route(
"/keys/generate", fn keys_router() -> Router<SharedState> {
post(apikey::create_api_key) // Usage Router::new().route(
.route_layer(role_guard!(Some("admin"), None)), "/generate",
post(apikey::create_api_key).route_layer(role_guard!(Some("admin"), None)),
) )
}
fn log_router() -> Router<SharedState> {
Router::new()
.route("/conversations", get(llm::get_conversations)) .route("/conversations", get(llm::get_conversations))
.route( .route(
"/conversations/{conversation_id}/messages", "/conversations/{conversation_id}/messages",
@@ -40,13 +41,17 @@ pub fn protected_router() -> Router<SharedState> {
} }
pub fn router(state: SharedState) -> Router<SharedState> { pub fn router(state: SharedState) -> Router<SharedState> {
Router::new() let protected = Router::new()
.merge(public_router()) .nest("/llm", llm_router())
.merge( .nest("/keys", keys_router())
protected_router().route_layer(middleware::from_fn_with_state( .nest("/log", log_router())
.route_layer(middleware::from_fn_with_state(
state.clone(), state.clone(),
auth_middleware, auth_middleware,
)), ));
)
Router::new()
.route("/docs.json", get(openapi_json))
.merge(protected)
.with_state(state) .with_state(state)
} }