77 lines
2.7 KiB
Rust
77 lines
2.7 KiB
Rust
use creditservice_api::{CreditServiceImpl, InMemoryStorage};
|
|
use creditservice_proto::credit_service_server::CreditServiceServer;
|
|
use creditservice_client::{Client, TlsConfig};
|
|
use rcgen::generate_simple_self_signed;
|
|
use std::net::SocketAddr;
|
|
use std::sync::Arc;
|
|
use tokio::sync::oneshot;
|
|
use tonic::transport::{Identity, Server, ServerTlsConfig};
|
|
|
|
#[tokio::test]
|
|
async fn mtls_connects_and_allows_rpc() {
|
|
// --- Generate self-signed server and client certs ---
|
|
let server = generate_simple_self_signed(vec!["creditservice.local".into()]).unwrap();
|
|
let server_cert_pem = server.cert.pem();
|
|
let server_key_pem = server.key_pair.serialize_pem();
|
|
|
|
let client = generate_simple_self_signed(vec!["creditservice-client".into()]).unwrap();
|
|
let client_cert_pem = client.cert.pem();
|
|
let client_key_pem = client.key_pair.serialize_pem();
|
|
|
|
// --- Start CreditService server with mTLS ---
|
|
let addr: SocketAddr = "127.0.0.1:50057".parse().unwrap();
|
|
let storage: Arc<dyn creditservice_api::CreditStorage> = InMemoryStorage::new();
|
|
let svc = Arc::new(CreditServiceImpl::new(storage));
|
|
|
|
let identity = Identity::from_pem(server_cert_pem.clone(), server_key_pem.clone());
|
|
let client_ca = tonic::transport::Certificate::from_pem(client_cert_pem.clone());
|
|
|
|
let (tx, rx) = oneshot::channel::<()>();
|
|
let server = Server::builder()
|
|
.tls_config(
|
|
ServerTlsConfig::new()
|
|
.identity(identity)
|
|
.client_ca_root(client_ca),
|
|
)
|
|
.unwrap()
|
|
.add_service(CreditServiceServer::new(svc.as_ref().clone()))
|
|
.serve_with_shutdown(addr, async {
|
|
let _ = rx.await;
|
|
});
|
|
|
|
let server_handle = tokio::spawn(server);
|
|
|
|
// Give the server a moment to start
|
|
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
|
|
|
|
// --- Client with mTLS ---
|
|
let mut client = Client::builder(format!("https://127.0.0.1:{}", addr.port()))
|
|
.tls(TlsConfig {
|
|
domain: Some("creditservice.local".into()),
|
|
ca_cert_pem: Some(server_cert_pem.clone()),
|
|
client_cert_pem: Some(client_cert_pem.clone()),
|
|
client_key_pem: Some(client_key_pem.clone()),
|
|
})
|
|
.build()
|
|
.await
|
|
.expect("client build");
|
|
|
|
// Simple RPC: create wallet then get wallet
|
|
let wallet = client
|
|
.create_wallet("proj-mtls", "org-mtls", 1000)
|
|
.await
|
|
.expect("create_wallet");
|
|
assert_eq!(wallet.project_id, "proj-mtls");
|
|
assert_eq!(wallet.org_id, "org-mtls");
|
|
|
|
let fetched = client
|
|
.get_wallet("proj-mtls", "org-mtls")
|
|
.await
|
|
.expect("get_wallet");
|
|
assert_eq!(fetched.balance, 1000);
|
|
|
|
// Shutdown server
|
|
let _ = tx.send(());
|
|
let _ = server_handle.await;
|
|
}
|
|
|