perf(struct): ddd
This commit is contained in:
180
tests/code2token_modes.rs
Normal file
180
tests/code2token_modes.rs
Normal file
@@ -0,0 +1,180 @@
|
||||
use axum::body::Body;
|
||||
use axum::http::{Request, StatusCode};
|
||||
use iam_service::presentation::http::api;
|
||||
use iam_service::presentation::http::state::AppState;
|
||||
use iam_service::infrastructure::repositories::tenant_config_repo::TenantConfigRepoPg;
|
||||
use iam_service::models::CreateTenantRequest;
|
||||
use iam_service::models::CreateUserRequest;
|
||||
use iam_service::application::services::{
|
||||
AppService, AuthService, AuthorizationService, ClientService, PermissionService, RoleService,
|
||||
TenantService, UserService,
|
||||
};
|
||||
use redis::aio::ConnectionManager;
|
||||
use sqlx::PgPool;
|
||||
use tower::ServiceExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[tokio::test]
|
||||
async fn code2token_modes_requirements() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let database_url = match std::env::var("DATABASE_URL") {
|
||||
Ok(v) if !v.trim().is_empty() => v,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
let redis_url = match std::env::var("REDIS_URL") {
|
||||
Ok(v) if !v.trim().is_empty() => v,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
let auth_code_jwt_secret = match std::env::var("AUTH_CODE_JWT_SECRET") {
|
||||
Ok(v) if !v.trim().is_empty() => v,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
let internal_psk = match std::env::var("INTERNAL_EXCHANGE_PSK") {
|
||||
Ok(v) if !v.trim().is_empty() => v,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
let pool = PgPool::connect(&database_url).await?;
|
||||
|
||||
let redis = redis::Client::open(redis_url)?;
|
||||
let redis: ConnectionManager = ConnectionManager::new(redis).await?;
|
||||
|
||||
let auth_service = AuthService::new(pool.clone(), "test".to_string());
|
||||
let client_service = ClientService::new(pool.clone(), 30);
|
||||
let user_service = UserService::new(pool.clone());
|
||||
let role_service = RoleService::new(pool.clone());
|
||||
let tenant_service = TenantService::new(pool.clone());
|
||||
let authorization_service = AuthorizationService::new(pool.clone());
|
||||
let app_service = AppService::new(pool.clone());
|
||||
let permission_service = PermissionService::new(pool.clone());
|
||||
|
||||
let tenant_config_repo = std::sync::Arc::new(TenantConfigRepoPg::new(pool.clone()));
|
||||
|
||||
let state = AppState {
|
||||
auth_service: auth_service.clone(),
|
||||
client_service: client_service.clone(),
|
||||
user_service,
|
||||
role_service,
|
||||
tenant_service: tenant_service.clone(),
|
||||
authorization_service,
|
||||
app_service,
|
||||
permission_service,
|
||||
redis,
|
||||
auth_code_jwt_secret: auth_code_jwt_secret.clone(),
|
||||
tenant_config_repo,
|
||||
};
|
||||
|
||||
let tenant = tenant_service
|
||||
.create_tenant(CreateTenantRequest {
|
||||
name: format!("t-{}", Uuid::new_v4()),
|
||||
config: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
let email = format!("u{}@example.com", Uuid::new_v4());
|
||||
let password = "P@ssw0rd123!".to_string();
|
||||
let _user = auth_service
|
||||
.register(
|
||||
tenant.id,
|
||||
CreateUserRequest {
|
||||
email: email.clone(),
|
||||
password: password.clone(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
let client_id = format!("cms{}", Uuid::new_v4().to_string().replace('-', ""));
|
||||
let client_id = &client_id[..std::cmp::min(24, client_id.len())];
|
||||
let redirect_uri = "http://localhost:5031/auth/callback".to_string();
|
||||
let client_secret = client_service
|
||||
.create_client(
|
||||
client_id.to_string(),
|
||||
Some("CMS".to_string()),
|
||||
Some(vec![redirect_uri.clone()]),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let app = api::build_app(state);
|
||||
|
||||
let login_code_req = serde_json::json!({
|
||||
"clientId": client_id,
|
||||
"redirectUri": redirect_uri,
|
||||
"email": email,
|
||||
"password": password
|
||||
});
|
||||
let resp = app
|
||||
.clone()
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/api/v1/auth/login-code")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("X-Tenant-ID", tenant.id.to_string())
|
||||
.body(Body::from(login_code_req.to_string()))?,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
let body = axum::body::to_bytes(resp.into_body(), usize::MAX).await?;
|
||||
let v: serde_json::Value = serde_json::from_slice(&body)?;
|
||||
let redirect_to = v["data"]["redirectTo"].as_str().unwrap_or_default();
|
||||
let url = url::Url::parse(redirect_to)?;
|
||||
let code = url
|
||||
.query_pairs()
|
||||
.find(|(k, _)| k == "code")
|
||||
.map(|(_, v)| v.to_string())
|
||||
.unwrap_or_default();
|
||||
assert!(!code.is_empty());
|
||||
|
||||
let code2token_req = serde_json::json!({
|
||||
"code": code,
|
||||
"clientId": client_id,
|
||||
"clientSecret": "wrong"
|
||||
});
|
||||
let resp = app
|
||||
.clone()
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/api/v1/auth/code2token")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("X-Tenant-ID", tenant.id.to_string())
|
||||
.body(Body::from(code2token_req.to_string()))?,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
|
||||
|
||||
let code2token_req_missing_tenant = serde_json::json!({
|
||||
"code": url.query_pairs().find(|(k, _)| k == "code").unwrap().1,
|
||||
"clientId": client_id,
|
||||
"clientSecret": client_secret
|
||||
});
|
||||
let resp = app
|
||||
.clone()
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/api/v1/auth/code2token")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(Body::from(code2token_req_missing_tenant.to_string()))?,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
|
||||
let code2token_req_internal = serde_json::json!({
|
||||
"code": url.query_pairs().find(|(k, _)| k == "code").unwrap().1,
|
||||
"clientId": client_id,
|
||||
"clientSecret": client_secret
|
||||
});
|
||||
let resp = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/api/v1/internal/auth/code2token")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("X-Internal-Token", internal_psk)
|
||||
.body(Body::from(code2token_req_internal.to_string()))?,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user