feature: add mgraphql codegen

This commit is contained in:
2025-04-29 02:22:06 +08:00
parent 0300d7baf6
commit 9fdb778330
16 changed files with 3844 additions and 70 deletions

View File

@@ -9,7 +9,7 @@ use axum::{
use crate::{app::AppContextTrait, auth::AuthServiceTrait};
pub async fn header_www_authenticate_middleware(
pub async fn auth_middleware(
State(ctx): State<Arc<dyn AppContextTrait>>,
request: Request,
next: Next,

View File

@@ -7,5 +7,5 @@ pub mod service;
pub use config::{AuthConfig, BasicAuthConfig, OidcAuthConfig};
pub use errors::AuthError;
pub use middleware::header_www_authenticate_middleware;
pub use middleware::auth_middleware;
pub use service::{AuthService, AuthServiceTrait, AuthUserInfo};

View File

@@ -5,8 +5,8 @@ use axum::{Extension, Router, extract::State, middleware::from_fn_with_state, ro
use super::core::Controller;
use crate::{
app::AppContextTrait,
auth::{AuthUserInfo, header_www_authenticate_middleware},
app::{AppContextTrait, Environment},
auth::{AuthUserInfo, auth_middleware},
errors::RecorderResult,
};
@@ -25,9 +25,51 @@ async fn graphql_handler(
graphql_service.schema.execute(req).await.into()
}
// 检查是否是 introspection 查询
fn is_introspection_query(req: &async_graphql::Request) -> bool {
if let Some(operation) = &req.operation_name {
if operation.starts_with("__") {
return true;
}
}
// 检查查询内容是否包含 introspection 字段
let query = req.query.as_str();
query.contains("__schema") || query.contains("__type") || query.contains("__typename")
}
async fn graphql_introspection_handler(
State(ctx): State<Arc<dyn AppContextTrait>>,
req: GraphQLRequest,
) -> GraphQLResponse {
let graphql_service = ctx.graphql();
let req = req.into_inner();
if !is_introspection_query(&req) {
return GraphQLResponse::from(async_graphql::Response::from_errors(vec![
async_graphql::ServerError::new(
"Only introspection queries are allowed on this endpoint",
None,
),
]));
}
graphql_service.schema.execute(req).await.into()
}
pub async fn create(ctx: Arc<dyn AppContextTrait>) -> RecorderResult<Controller> {
let mut introspection_handler = post(graphql_introspection_handler);
if !matches!(ctx.environment(), Environment::Development) {
introspection_handler =
introspection_handler.layer(from_fn_with_state(ctx.clone(), auth_middleware));
}
let router = Router::<Arc<dyn AppContextTrait>>::new()
.route("/", post(graphql_handler))
.layer(from_fn_with_state(ctx, header_www_authenticate_middleware));
.route(
"/",
post(graphql_handler).layer(from_fn_with_state(ctx, auth_middleware)),
)
.route("/introspection", introspection_handler);
Ok(Controller::from_prefix(CONTROLLER_PREFIX, router))
}