feat: microservice ready
This commit is contained in:
1 parent
07a93ff0b7
commit
31f9b6cfea
80 files changed
+477
-240
No files matched your search
Generated
+114
@@ -1849,6 +1849,31 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "imphnen-backend-service"
|
name = "imphnen-backend-service"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"axum",
|
||||||
|
"axum-test",
|
||||||
|
"chrono",
|
||||||
|
"imphnen-entities",
|
||||||
|
"imphnen-gateway-service",
|
||||||
|
"imphnen-libs",
|
||||||
|
"imphnen-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"rand 0.9.0",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"surrealdb",
|
||||||
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
|
"utoipa",
|
||||||
|
"utoipa-swagger-ui",
|
||||||
|
"validator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imphnen-dimentorin-service"
|
||||||
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -1881,6 +1906,79 @@ dependencies = [
|
|||||||
"utoipa",
|
"utoipa",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imphnen-gacha-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"axum",
|
||||||
|
"axum-test",
|
||||||
|
"chrono",
|
||||||
|
"imphnen-entities",
|
||||||
|
"imphnen-libs",
|
||||||
|
"imphnen-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"rand 0.9.0",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"surrealdb",
|
||||||
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
|
"utoipa",
|
||||||
|
"utoipa-swagger-ui",
|
||||||
|
"validator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imphnen-gateway-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"axum",
|
||||||
|
"axum-test",
|
||||||
|
"chrono",
|
||||||
|
"imphnen-entities",
|
||||||
|
"imphnen-iam-service",
|
||||||
|
"imphnen-libs",
|
||||||
|
"imphnen-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"rand 0.9.0",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"surrealdb",
|
||||||
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
|
"utoipa",
|
||||||
|
"utoipa-swagger-ui",
|
||||||
|
"validator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imphnen-iam-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"axum",
|
||||||
|
"axum-test",
|
||||||
|
"chrono",
|
||||||
|
"imphnen-entities",
|
||||||
|
"imphnen-libs",
|
||||||
|
"imphnen-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"rand 0.9.0",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"surrealdb",
|
||||||
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
|
"utoipa",
|
||||||
|
"utoipa-swagger-ui",
|
||||||
|
"validator",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "imphnen-libs"
|
name = "imphnen-libs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -4159,6 +4257,22 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tests"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"axum-test",
|
||||||
|
"chrono",
|
||||||
|
"imphnen-entities",
|
||||||
|
"imphnen-iam-service",
|
||||||
|
"imphnen-libs",
|
||||||
|
"imphnen-utils",
|
||||||
|
"serde_json",
|
||||||
|
"surrealdb",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.69"
|
version = "1.0.69"
|
||||||
|
|||||||
+2
-4
@@ -1,10 +1,8 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"imphnen-apis",
|
"imphnen-*",
|
||||||
"imphnen-utils",
|
"tests",
|
||||||
"imphnen-libs",
|
|
||||||
"imphnen-entities",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
use crate::{AppState, Env, SurrealMemClient, SurrealWsClient};
|
|
||||||
use axum::{
|
|
||||||
http::{header, HeaderValue, Method},
|
|
||||||
response::Redirect,
|
|
||||||
routing::get,
|
|
||||||
Extension, Router,
|
|
||||||
};
|
|
||||||
use tower_http::cors::CorsLayer;
|
|
||||||
use utoipa_swagger_ui::SwaggerUi;
|
|
||||||
|
|
||||||
pub mod v1;
|
|
||||||
pub mod v2;
|
|
||||||
|
|
||||||
pub use v1::*;
|
|
||||||
|
|
||||||
pub async fn apps(
|
|
||||||
surrealdb_ws: SurrealWsClient,
|
|
||||||
surrealdb_mem: SurrealMemClient,
|
|
||||||
) -> Router {
|
|
||||||
let state = AppState {
|
|
||||||
surrealdb_ws,
|
|
||||||
surrealdb_mem,
|
|
||||||
};
|
|
||||||
let env = Env::new();
|
|
||||||
let cors_origins = match env.rust_env.as_str() {
|
|
||||||
"development" => vec!["http://localhost:3000"],
|
|
||||||
"production" => {
|
|
||||||
vec!["https://gacha.imphnen.dev", "https://imphnen.dev"]
|
|
||||||
}
|
|
||||||
_ => vec![
|
|
||||||
"http://localhost:3000",
|
|
||||||
"https://gacha.imphnen.dev",
|
|
||||||
"https://imphnen.dev",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
let allowed_origins: Vec<HeaderValue> = cors_origins
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|origin| origin.parse::<HeaderValue>().ok())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let cors_middleware = CorsLayer::new()
|
|
||||||
.allow_origin(allowed_origins)
|
|
||||||
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE])
|
|
||||||
.allow_headers([header::AUTHORIZATION, header::CONTENT_TYPE])
|
|
||||||
.allow_credentials(true);
|
|
||||||
|
|
||||||
Router::new()
|
|
||||||
.route("/", get(Redirect::to("/docs")))
|
|
||||||
.nest("/v1", v1::routes().await)
|
|
||||||
.nest("/v2", v2::routes().await)
|
|
||||||
.merge(SwaggerUi::new("/docs").url("/openapi.json", v1::docs_router()))
|
|
||||||
.layer(cors_middleware)
|
|
||||||
.layer(Extension(state))
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
use crate::{
|
|
||||||
common_response, extract_email, AppState, UsersItemDtoRaw, UsersRepository,
|
|
||||||
};
|
|
||||||
use axum::{
|
|
||||||
extract::Request, http::StatusCode, middleware::Next, response::Response,
|
|
||||||
Extension,
|
|
||||||
};
|
|
||||||
use std::convert::Infallible;
|
|
||||||
|
|
||||||
pub async fn auth_middleware(
|
|
||||||
Extension(state): Extension<AppState>,
|
|
||||||
mut req: Request,
|
|
||||||
next: Next,
|
|
||||||
) -> Result<Response, Infallible> {
|
|
||||||
let headers = req.headers();
|
|
||||||
|
|
||||||
let email = match extract_email(headers) {
|
|
||||||
Some(email) => email,
|
|
||||||
None => {
|
|
||||||
return Ok(common_response(
|
|
||||||
StatusCode::UNAUTHORIZED,
|
|
||||||
"Invalid or expired token",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let repository = UsersRepository::new(&state);
|
|
||||||
|
|
||||||
let user: Option<UsersItemDtoRaw> =
|
|
||||||
match repository.query_user_by_email(email).await {
|
|
||||||
Ok(user) => Some(user),
|
|
||||||
Err(err) => {
|
|
||||||
return Ok(common_response(
|
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
|
||||||
&err.to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if user.is_none() {
|
|
||||||
return Ok(common_response(
|
|
||||||
StatusCode::UNAUTHORIZED,
|
|
||||||
"Unauthorized user",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
req.extensions_mut().insert(user.unwrap());
|
|
||||||
|
|
||||||
Ok(next.run(req).await)
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
use utoipa::OpenApi;
|
|
||||||
|
|
||||||
pub mod docs_controller;
|
|
||||||
pub use docs_controller::*;
|
|
||||||
|
|
||||||
pub fn docs_router() -> utoipa::openapi::OpenApi {
|
|
||||||
ApiDoc::openapi()
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
use axum::{middleware::from_fn, Router};
|
|
||||||
pub mod auth;
|
|
||||||
pub mod docs;
|
|
||||||
pub mod gacha;
|
|
||||||
pub mod permissions;
|
|
||||||
pub mod roles;
|
|
||||||
pub mod users;
|
|
||||||
|
|
||||||
pub use auth::*;
|
|
||||||
pub use docs::*;
|
|
||||||
pub use permissions::*;
|
|
||||||
pub use roles::*;
|
|
||||||
pub use users::*;
|
|
||||||
|
|
||||||
pub async fn routes() -> Router {
|
|
||||||
let public_routes = Router::new().nest("/auth", auth_router());
|
|
||||||
let protected_routes = Router::new()
|
|
||||||
.nest("/users", users_router())
|
|
||||||
.nest("/roles", roles_router())
|
|
||||||
.nest("/permissions", permissions_router())
|
|
||||||
.layer(from_fn(auth::auth_middleware::auth_middleware));
|
|
||||||
Router::new().merge(public_routes).merge(protected_routes)
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use axum::{response::IntoResponse, routing::post, Router};
|
|
||||||
|
|
||||||
async fn dummy_login() -> impl IntoResponse {
|
|
||||||
"Logged in successfully"
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn auth_router() -> Router {
|
|
||||||
Router::new().route("/login", post(dummy_login))
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use axum::Router;
|
|
||||||
|
|
||||||
pub mod auth;
|
|
||||||
pub use auth::*;
|
|
||||||
|
|
||||||
pub async fn routes() -> Router {
|
|
||||||
let public_routes = Router::new().nest("/auth", auth::auth_router());
|
|
||||||
Router::new().merge(public_routes)
|
|
||||||
}
|
|
||||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -1,9 +0,0 @@
|
|||||||
use imphnen_backend_service::{apps, axum_init};
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
axum_init(|surrealdb_ws, surrealdb_mem| async {
|
|
||||||
apps(surrealdb_ws, surrealdb_mem).await
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use imphnen_backend_service::{apps, axum_init};
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
axum_init(|surrealdb_ws, surrealdb_mem| async {
|
|
||||||
apps(surrealdb_ws, surrealdb_mem).await
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[package]
|
||||||
|
name = "imphnen-backend-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
imphnen-entities = { version = "0.1.0", path = "../imphnen-entities" }
|
||||||
|
imphnen-libs = { version = "0.1.0", path = "../imphnen-libs" }
|
||||||
|
imphnen-utils = { version = "0.1.0", path = "../imphnen-utils" }
|
||||||
|
axum.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
utoipa.workspace = true
|
||||||
|
lazy_static.workspace = true
|
||||||
|
regex.workspace = true
|
||||||
|
validator.workspace = true
|
||||||
|
axum-test.workspace = true
|
||||||
|
surrealdb.workspace = true
|
||||||
|
rand.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
|
anyhow.workspace = true
|
||||||
|
tower-http.workspace = true
|
||||||
|
utoipa-swagger-ui.workspace = true
|
||||||
|
imphnen-gateway-service = { version = "0.1.0", path = "../imphnen-gateway-service" }
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
use imphnen_gateway_service::gateway_service;
|
||||||
|
use imphnen_libs::axum_init;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
axum_init(|surrealdb_ws, surrealdb_mem| async {
|
||||||
|
gateway_service(surrealdb_ws, surrealdb_mem).await
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,10 @@
|
|||||||
|
use imphnen_gateway_service::gateway_service;
|
||||||
|
use imphnen_libs::axum_init;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
axum_init(|surrealdb_ws, surrealdb_mem| async {
|
||||||
|
gateway_service(surrealdb_ws, surrealdb_mem).await
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[package]
|
||||||
|
name = "imphnen-dimentorin-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
imphnen-entities = { version = "0.1.0", path = "../imphnen-entities" }
|
||||||
|
imphnen-libs = { version = "0.1.0", path = "../imphnen-libs" }
|
||||||
|
imphnen-utils = { version = "0.1.0", path = "../imphnen-utils" }
|
||||||
|
axum.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
utoipa.workspace = true
|
||||||
|
lazy_static.workspace = true
|
||||||
|
regex.workspace = true
|
||||||
|
validator.workspace = true
|
||||||
|
axum-test.workspace = true
|
||||||
|
surrealdb.workspace = true
|
||||||
|
rand.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
|
anyhow.workspace = true
|
||||||
|
tower-http.workspace = true
|
||||||
|
utoipa-swagger-ui.workspace = true
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
pub fn add(left: u64, right: u64) -> u64 {
|
||||||
|
left + right
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "imphnen-backend-service"
|
name = "imphnen-gacha-service"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
imphnen-entities = { version = "0.1.0", path = "../imphnen-entities" }
|
imphnen-entities = { version = "0.1.0", path = "../imphnen-entities" }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
use imphnen_entities::*;
|
||||||
|
use imphnen_libs::*;
|
||||||
|
use imphnen_utils::*;
|
||||||
|
|
||||||
|
pub mod v1;
|
||||||
|
pub use imphnen_entities::*;
|
||||||
|
pub use imphnen_libs::*;
|
||||||
|
pub use imphnen_utils::*;
|
||||||
|
pub use v1::*;
|
||||||
File renamed without changes.
File renamed without changes.
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
use super::{GachaClaimSchema, GachaItemSchema, GachaRollSchema};
|
use super::{GachaClaimSchema, GachaItemSchema, GachaRollSchema};
|
||||||
use crate::{
|
use crate::{
|
||||||
get_id, make_thing, query_list_with_meta, AppState, MetaRequestDto, ResourceEnum,
|
AppState, MetaRequestDto, ResourceEnum, ResponseListSuccessDto, get_id,
|
||||||
ResponseListSuccessDto,
|
make_thing, query_list_with_meta,
|
||||||
};
|
};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{Result, bail};
|
||||||
|
|
||||||
pub struct GachaRepository<'a> {
|
pub struct GachaRepository<'a> {
|
||||||
state: &'a AppState,
|
state: &'a AppState,
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,2 @@
|
|||||||
|
pub mod gacha;
|
||||||
|
pub use gacha::*;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[package]
|
||||||
|
name = "imphnen-gateway-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
imphnen-iam-service = { version = "0.1.0", path = "../imphnen-iam-service" }
|
||||||
|
imphnen-entities = { version = "0.1.0", path = "../imphnen-entities" }
|
||||||
|
imphnen-libs = { version = "0.1.0", path = "../imphnen-libs" }
|
||||||
|
imphnen-utils = { version = "0.1.0", path = "../imphnen-utils" }
|
||||||
|
axum.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
utoipa.workspace = true
|
||||||
|
lazy_static.workspace = true
|
||||||
|
regex.workspace = true
|
||||||
|
validator.workspace = true
|
||||||
|
axum-test.workspace = true
|
||||||
|
surrealdb.workspace = true
|
||||||
|
rand.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
|
anyhow.workspace = true
|
||||||
|
tower-http.workspace = true
|
||||||
|
utoipa-swagger-ui.workspace = true
|
||||||
+7
-5
@@ -1,9 +1,7 @@
|
|||||||
use crate::{
|
use imphnen_iam_service::{
|
||||||
v1::{
|
auth, permissions, roles, users, AuthLoginRequestDto, AuthLoginResponsetDto, AuthResendOtpRequestDto, AuthVerifyEmailRequestDto,
|
||||||
auth, permissions, roles, users, AuthLoginRequestDto, AuthLoginResponsetDto, AuthResendOtpRequestDto, AuthVerifyEmailRequestDto
|
AuthNewPasswordRequestDto, AuthRefreshTokenRequestDto, MessageResponseDto, MetaRequestDto, MetaResponseDto, PermissionsItemDto, PermissionsRequestDto, ResponseListSuccessDto, ResponseSuccessDto, RolesItemDto, RolesRequestCreateDto, RolesRequestUpdateDto, TokenDto, UsersCreateRequestDto, UsersDetailItemDto, UsersItemDto, UsersListItemDto, UsersUpdateRequestDto
|
||||||
}, AuthNewPasswordRequestDto, AuthRefreshTokenRequestDto, MessageResponseDto, MetaRequestDto, MetaResponseDto, PermissionsItemDto, PermissionsRequestDto, ResponseListSuccessDto, ResponseSuccessDto, RolesItemDto, RolesRequestCreateDto, RolesRequestUpdateDto, TokenDto, UsersCreateRequestDto, UsersDetailItemDto, UsersItemDto, UsersListItemDto, UsersUpdateRequestDto
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use utoipa::{
|
use utoipa::{
|
||||||
openapi::security::{Http, HttpAuthScheme, SecurityScheme},
|
openapi::security::{Http, HttpAuthScheme, SecurityScheme},
|
||||||
Modify, OpenApi,
|
Modify, OpenApi,
|
||||||
@@ -101,3 +99,7 @@ impl Modify for SecurityAddon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn docs_router() -> utoipa::openapi::OpenApi {
|
||||||
|
ApiDoc::openapi()
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use axum::{
|
||||||
|
Extension, Router, middleware::from_fn, response::Redirect, routing::get,
|
||||||
|
};
|
||||||
|
use imphnen_entities::{AppState, SurrealMemClient, SurrealWsClient};
|
||||||
|
use imphnen_iam_service::{iam_protected_routes, iam_public_routes};
|
||||||
|
|
||||||
|
pub mod docs;
|
||||||
|
pub mod middleware;
|
||||||
|
|
||||||
|
pub use docs::*;
|
||||||
|
pub use middleware::*;
|
||||||
|
use utoipa_swagger_ui::SwaggerUi;
|
||||||
|
|
||||||
|
pub async fn gateway_service(
|
||||||
|
surrealdb_ws: SurrealWsClient,
|
||||||
|
surrealdb_mem: SurrealMemClient,
|
||||||
|
) -> Router {
|
||||||
|
let state = AppState {
|
||||||
|
surrealdb_ws,
|
||||||
|
surrealdb_mem,
|
||||||
|
};
|
||||||
|
|
||||||
|
let public_routes = iam_public_routes();
|
||||||
|
let protected_routes = iam_protected_routes().layer(from_fn(auth_middleware));
|
||||||
|
|
||||||
|
Router::new()
|
||||||
|
.route("/", get(Redirect::to("/docs")))
|
||||||
|
.nest("/v1", public_routes.merge(protected_routes))
|
||||||
|
.merge(SwaggerUi::new("/docs").url("/openapi.json", docs_router()))
|
||||||
|
.layer(cors_middleware())
|
||||||
|
.layer(Extension(state.clone()))
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
use axum::{
|
||||||
|
Extension,
|
||||||
|
extract::Request,
|
||||||
|
http::{HeaderValue, Method, StatusCode, header},
|
||||||
|
middleware::Next,
|
||||||
|
response::Response,
|
||||||
|
};
|
||||||
|
use imphnen_iam_service::{UsersItemDtoRaw, UsersRepository};
|
||||||
|
use imphnen_libs::{AppState, Env};
|
||||||
|
use imphnen_utils::{common_response, extract_email};
|
||||||
|
use std::convert::Infallible;
|
||||||
|
use tower_http::cors::CorsLayer;
|
||||||
|
|
||||||
|
pub async fn auth_middleware(
|
||||||
|
Extension(state): Extension<AppState>,
|
||||||
|
mut req: Request,
|
||||||
|
next: Next,
|
||||||
|
) -> Result<Response, Infallible> {
|
||||||
|
let headers = req.headers();
|
||||||
|
let email = match extract_email(headers) {
|
||||||
|
Some(email) => email,
|
||||||
|
None => {
|
||||||
|
return Ok(common_response(
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
|
"Invalid or expired token",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let repository = UsersRepository::new(&state);
|
||||||
|
let user: Option<UsersItemDtoRaw> =
|
||||||
|
match repository.query_user_by_email(email).await {
|
||||||
|
Ok(user) => Some(user),
|
||||||
|
Err(err) => {
|
||||||
|
return Ok(common_response(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
&err.to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if user.is_none() {
|
||||||
|
return Ok(common_response(
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
|
"Unauthorized user",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
req.extensions_mut().insert(user.unwrap());
|
||||||
|
Ok(next.run(req).await)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cors_middleware() -> CorsLayer {
|
||||||
|
let env = Env::new();
|
||||||
|
let cors_origins = match env.rust_env.as_str() {
|
||||||
|
"development" => vec!["http://localhost:3000"],
|
||||||
|
"production" => {
|
||||||
|
vec!["https://gacha.imphnen.dev", "https://imphnen.dev"]
|
||||||
|
}
|
||||||
|
_ => vec![
|
||||||
|
"http://localhost:3000",
|
||||||
|
"https://gacha.imphnen.dev",
|
||||||
|
"https://imphnen.dev",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
let allowed_origins: Vec<HeaderValue> = cors_origins
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|origin| origin.parse::<HeaderValue>().ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
CorsLayer::new()
|
||||||
|
.allow_origin(allowed_origins)
|
||||||
|
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE])
|
||||||
|
.allow_headers([header::AUTHORIZATION, header::CONTENT_TYPE])
|
||||||
|
.allow_credentials(true)
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[package]
|
||||||
|
name = "imphnen-iam-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
imphnen-entities = { version = "0.1.0", path = "../imphnen-entities" }
|
||||||
|
imphnen-libs = { version = "0.1.0", path = "../imphnen-libs" }
|
||||||
|
imphnen-utils = { version = "0.1.0", path = "../imphnen-utils" }
|
||||||
|
axum.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
utoipa.workspace = true
|
||||||
|
lazy_static.workspace = true
|
||||||
|
regex.workspace = true
|
||||||
|
validator.workspace = true
|
||||||
|
axum-test.workspace = true
|
||||||
|
surrealdb.workspace = true
|
||||||
|
rand.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
chrono.workspace = true
|
||||||
|
anyhow.workspace = true
|
||||||
|
tower-http.workspace = true
|
||||||
|
utoipa-swagger-ui.workspace = true
|
||||||
@@ -3,11 +3,11 @@ use imphnen_entities::*;
|
|||||||
use imphnen_libs::*;
|
use imphnen_libs::*;
|
||||||
use imphnen_utils::*;
|
use imphnen_utils::*;
|
||||||
|
|
||||||
pub mod apps;
|
pub mod v1;
|
||||||
|
|
||||||
pub use apps::*;
|
|
||||||
pub use imphnen_entities::*;
|
pub use imphnen_entities::*;
|
||||||
pub use imphnen_libs::*;
|
pub use imphnen_libs::*;
|
||||||
|
pub use v1::*;
|
||||||
|
|
||||||
pub fn create_test_user(
|
pub fn create_test_user(
|
||||||
email: &str,
|
email: &str,
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,17 +1,11 @@
|
|||||||
use axum::{routing::post, Router};
|
use axum::{Router, routing::post};
|
||||||
|
|
||||||
pub mod auth_controller;
|
pub mod auth_controller;
|
||||||
pub mod auth_dto;
|
pub mod auth_dto;
|
||||||
pub mod auth_middleware;
|
|
||||||
pub mod auth_repository;
|
pub mod auth_repository;
|
||||||
pub mod auth_schema;
|
pub mod auth_schema;
|
||||||
pub mod auth_service;
|
pub mod auth_service;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod auth_controller_test;
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod auth_repository_test;
|
|
||||||
|
|
||||||
pub use auth_dto::*;
|
pub use auth_dto::*;
|
||||||
pub use auth_repository::*;
|
pub use auth_repository::*;
|
||||||
pub use auth_schema::*;
|
pub use auth_schema::*;
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
use axum::Router;
|
||||||
|
|
||||||
|
pub mod auth;
|
||||||
|
pub mod permissions;
|
||||||
|
pub mod roles;
|
||||||
|
pub mod users;
|
||||||
|
|
||||||
|
pub use auth::*;
|
||||||
|
pub use permissions::*;
|
||||||
|
pub use roles::*;
|
||||||
|
pub use users::*;
|
||||||
|
|
||||||
|
pub fn iam_public_routes() -> Router {
|
||||||
|
Router::new().nest("/auth", auth_router())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iam_protected_routes() -> Router {
|
||||||
|
Router::new()
|
||||||
|
.nest("/users", users_router())
|
||||||
|
.nest("/roles", roles_router())
|
||||||
|
.nest("/permissions", permissions_router())
|
||||||
|
}
|
||||||
+1
-6
@@ -1,6 +1,6 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
routing::{delete, get, post, put},
|
|
||||||
Router,
|
Router,
|
||||||
|
routing::{delete, get, post, put},
|
||||||
};
|
};
|
||||||
pub mod permissions_controller;
|
pub mod permissions_controller;
|
||||||
pub mod permissions_dto;
|
pub mod permissions_dto;
|
||||||
@@ -10,11 +10,6 @@ pub mod permissions_repository;
|
|||||||
pub mod permissions_schema;
|
pub mod permissions_schema;
|
||||||
pub mod permissions_service;
|
pub mod permissions_service;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod permissions_controller_test;
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod permissions_repository_test;
|
|
||||||
|
|
||||||
pub use permissions_controller::*;
|
pub use permissions_controller::*;
|
||||||
pub use permissions_dto::*;
|
pub use permissions_dto::*;
|
||||||
pub use permissions_enum::*;
|
pub use permissions_enum::*;
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 50 of 80 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user