perf(struct): ddd

This commit is contained in:
2026-02-03 17:31:08 +08:00
parent 202b5eaad5
commit 4a071bd7c8
64 changed files with 1214 additions and 1189 deletions

View File

@@ -0,0 +1,270 @@
use axum::{
Router,
routing::{get, post, put},
};
use utoipa::OpenApi;
use utoipa_scalar::{Scalar, Servable};
use crate::constants::CANONICAL_BASE;
use crate::docs::ApiDoc;
use crate::middleware as core_middleware;
use crate::presentation::http::handlers::{
app, auth, authorization, client, jwks, permission, platform, role, sso, tenant, user,
};
use crate::presentation::http::state::AppState;
pub fn routes() -> Vec<(&'static str, &'static str)> {
vec![
("GET", "/.well-known/jwks.json"),
("POST", "/tenants/register"),
("POST", "/auth/register"),
("POST", "/auth/login"),
("POST", "/auth/login-code"),
("POST", "/auth/refresh"),
("POST", "/auth/logout"),
("POST", "/auth/code2token"),
("POST", "/internal/auth/code2token"),
("GET", "/me/permissions"),
("POST", "/authorize/check"),
("GET", "/users"),
("GET", "/users/{id}"),
("PATCH", "/users/{id}"),
("DELETE", "/users/{id}"),
("POST", "/users/me/password/reset"),
("POST", "/users/{id}/password/reset"),
("GET", "/users/{id}/roles"),
("PUT", "/users/{id}/roles"),
("GET", "/permissions"),
("GET", "/roles"),
("POST", "/roles"),
("GET", "/roles/{id}"),
("PATCH", "/roles/{id}"),
("DELETE", "/roles/{id}"),
("POST", "/roles/{id}/permissions/grant"),
("POST", "/roles/{id}/permissions/revoke"),
("POST", "/roles/{id}/users/grant"),
("POST", "/roles/{id}/users/revoke"),
("GET", "/platform/tenants/{tenant_id}/enabled-apps"),
("PUT", "/platform/tenants/{tenant_id}/enabled-apps"),
("GET", "/platform/clients"),
("POST", "/platform/clients"),
("PUT", "/platform/clients/{client_id}/redirect-uris"),
("POST", "/platform/clients/{client_id}/rotate-secret"),
("GET", "/platform/apps"),
("POST", "/platform/apps"),
("GET", "/platform/apps/{app_id}"),
("PATCH", "/platform/apps/{app_id}"),
("DELETE", "/platform/apps/{app_id}"),
("POST", "/platform/apps/{app_id}/status-change-requests"),
("GET", "/platform/app-status-change-requests"),
(
"POST",
"/platform/app-status-change-requests/{request_id}/approve",
),
(
"POST",
"/platform/app-status-change-requests/{request_id}/reject",
),
]
}
pub fn build_app(state: AppState) -> Router {
let tenant_required_auth = Router::new()
.route(
"/register",
post(auth::register_handler)
.layer(core_middleware::rate_limit::register_rate_limiter())
.layer(axum::middleware::from_fn(
core_middleware::rate_limit::log_rate_limit_register,
)),
)
.route(
"/login",
post(auth::login_handler)
.layer(core_middleware::rate_limit::login_rate_limiter())
.layer(axum::middleware::from_fn(
core_middleware::rate_limit::log_rate_limit_login,
)),
)
.route(
"/login-code",
post(sso::login_code_handler)
.layer(core_middleware::rate_limit::login_rate_limiter())
.layer(axum::middleware::from_fn(
core_middleware::rate_limit::log_rate_limit_login,
)),
)
.route("/code2token", post(sso::code2token_handler))
.layer(axum::middleware::from_fn(
core_middleware::auth_tenant::validate_auth_tenant,
));
let no_tenant_auth = Router::new().route(
"/refresh",
post(auth::refresh_handler)
.layer(core_middleware::rate_limit::login_rate_limiter())
.layer(axum::middleware::from_fn(
core_middleware::rate_limit::log_rate_limit_login,
)),
);
let public_v1 = Router::new()
.route("/.well-known/jwks.json", get(jwks::jwks_handler))
.route("/tenants/register", post(tenant::create_tenant_handler))
.route(
"/internal/auth/code2token",
post(sso::internal_code2token_handler),
)
.nest(
"/auth",
Router::new()
.merge(tenant_required_auth)
.merge(no_tenant_auth),
)
.with_state(state.clone());
let auth_cfg = core_middleware::auth::AuthMiddlewareConfig {
skip_exact_paths: vec![],
skip_path_prefixes: vec![],
jwt: auth_kit::jwt::JwtVerifyConfig::rs256_from_pem(
"iam-service",
&crate::utils::keys::get_keys().public_pem,
)
.expect("invalid JWT_PUBLIC_KEY_PEM"),
};
let tenant_cfg = core_middleware::TenantMiddlewareConfig {
skip_exact_paths: vec![],
skip_path_prefixes: vec![],
};
let protected_v1 = Router::new()
.route("/auth/logout", post(auth::logout_handler))
.route("/me/permissions", get(authorization::my_permissions_handler))
.route(
"/authorize/check",
post(authorization::authorization_check_handler),
)
.route("/users", get(user::list_users_handler))
.route(
"/users/me/password/reset",
post(user::reset_my_password_handler),
)
.route("/permissions", get(permission::list_permissions_handler))
.route(
"/users/{id}",
get(user::get_user_handler)
.patch(user::update_user_handler)
.delete(user::delete_user_handler),
)
.route(
"/users/{id}/password/reset",
post(user::reset_user_password_handler),
)
.route(
"/users/{id}/roles",
get(user::list_user_roles_handler).put(user::set_user_roles_handler),
)
.route(
"/roles",
get(role::list_roles_handler).post(role::create_role_handler),
)
.route(
"/roles/{id}",
get(role::get_role_handler)
.patch(role::update_role_handler)
.delete(role::delete_role_handler),
)
.route(
"/roles/{id}/permissions/grant",
post(role::grant_role_permissions_handler),
)
.route(
"/roles/{id}/permissions/revoke",
post(role::revoke_role_permissions_handler),
)
.route("/roles/{id}/users/grant", post(role::grant_role_users_handler))
.route(
"/roles/{id}/users/revoke",
post(role::revoke_role_users_handler),
)
.route(
"/tenants/me",
get(tenant::get_tenant_handler)
.patch(tenant::update_tenant_handler)
.delete(tenant::delete_tenant_handler),
)
.route("/tenants/me/status", post(tenant::update_tenant_status_handler))
.layer(axum::middleware::from_fn_with_state(
auth_cfg.clone(),
core_middleware::auth::authenticate_with_config,
))
.layer(axum::middleware::from_fn_with_state(
tenant_cfg.clone(),
core_middleware::resolve_tenant_with_config,
))
.with_state(state.clone());
let platform_v1 = Router::new()
.route(
"/platform/tenants/{tenant_id}/enabled-apps",
get(platform::get_tenant_enabled_apps_handler)
.put(platform::set_tenant_enabled_apps_handler),
)
.route(
"/platform/clients",
get(client::list_clients_handler).post(client::create_client_handler),
)
.route(
"/platform/clients/{client_id}/rotate-secret",
post(client::rotate_client_secret_handler),
)
.route(
"/platform/clients/{client_id}/redirect-uris",
put(client::update_client_redirect_uris_handler),
)
.route("/platform/apps", get(app::list_apps_handler).post(app::create_app_handler))
.route(
"/platform/apps/{app_id}",
get(app::get_app_handler)
.patch(app::update_app_handler)
.delete(app::delete_app_handler),
)
.route(
"/platform/apps/{app_id}/status-change-requests",
post(app::request_app_status_change_handler),
)
.route(
"/platform/app-status-change-requests",
get(app::list_app_status_change_requests_handler),
)
.route(
"/platform/app-status-change-requests/{request_id}/approve",
post(app::approve_app_status_change_handler),
)
.route(
"/platform/app-status-change-requests/{request_id}/reject",
post(app::reject_app_status_change_handler),
)
.layer(axum::middleware::from_fn_with_state(
auth_cfg,
core_middleware::auth::authenticate_with_config,
))
.with_state(state.clone());
let v1 = Router::new()
.merge(public_v1)
.merge(protected_v1)
.merge(platform_v1)
.layer(axum::middleware::from_fn(
common_telemetry::axum_middleware::trace_http_request,
));
Router::new()
.route(
"/favicon.ico",
get(|| async { axum::http::StatusCode::NO_CONTENT }),
)
.merge(Scalar::with_url("/scalar", ApiDoc::openapi()))
.nest(CANONICAL_BASE, v1)
.with_state(state)
}