perf(struct): ddd
This commit is contained in:
270
src/presentation/http/api.rs
Normal file
270
src/presentation/http/api.rs
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user