821537186e
- Reorganized import statements in adapter tests for better readability - Replaced or_insert_with(Vec::new) with or_default() in test closures - Updated Cargo.lock with new dependency versions and checksums - Added TLS features to tonic dependency configuration - Included sqlx, chrono, and uuid dependencies with specific features - Added jsonwebtoken and arc-swap as project dependencies - Reformatted assertion statements to comply with line length limits - Adjusted base64 import order in engine codec module - Updated protobuf include statement formatting
109 lines
3.7 KiB
Rust
109 lines
3.7 KiB
Rust
//! Aggregate gRPC client holder for all appks core services.
|
|
//!
|
|
//! A single TCP `Channel` is shared across all four service clients
|
|
//! to avoid redundant connections.
|
|
|
|
use std::fs;
|
|
use std::time::Duration;
|
|
|
|
use tonic::transport::{Certificate, Channel, ClientTlsConfig, Endpoint, Identity};
|
|
|
|
use crate::pb::core::token_service_client::TokenServiceClient;
|
|
use crate::pb::im::{
|
|
channel_service_client::ChannelServiceClient, member_service_client::MemberServiceClient,
|
|
permission_service_client::PermissionServiceClient,
|
|
};
|
|
use crate::{ImksError, ImksResult};
|
|
|
|
use super::config::RpcConfig;
|
|
|
|
/// Holds gRPC clients for all appks core services consumed by imks.
|
|
///
|
|
/// Cheaply cloneable — each inner client wraps a shared `Arc<Channel>`.
|
|
#[derive(Clone)]
|
|
pub struct AppksClients {
|
|
/// JWT token lifecycle: issue, refresh, revoke, verify, signing keys.
|
|
pub token: TokenServiceClient<Channel>,
|
|
/// Channel and category CRUD + statistics.
|
|
pub channel: ChannelServiceClient<Channel>,
|
|
/// Channel member invite / kick / join / leave.
|
|
pub member: MemberServiceClient<Channel>,
|
|
/// Permission checks and overwrite rules.
|
|
pub permission: PermissionServiceClient<Channel>,
|
|
}
|
|
|
|
impl AppksClients {
|
|
/// Connect to all appks services using a shared gRPC channel.
|
|
pub async fn connect(config: &RpcConfig) -> ImksResult<Self> {
|
|
let mut endpoint = Endpoint::from_shared(config.appks_addr.clone())
|
|
.map_err(|e| ImksError::Internal(format!("Invalid gRPC endpoint: {e}")))?
|
|
.connect_timeout(Duration::from_secs(config.connect_timeout_secs));
|
|
|
|
if config.appks_addr.starts_with("https://")
|
|
|| config.tls_ca_cert_path.is_some()
|
|
|| config.tls_client_cert_path.is_some()
|
|
|| config.tls_client_key_path.is_some()
|
|
{
|
|
endpoint = endpoint.tls_config(build_tls_config(config)?)?;
|
|
}
|
|
|
|
let channel = endpoint
|
|
.connect()
|
|
.await
|
|
.map_err(|e| ImksError::Internal(format!("gRPC connect failed: {e}")))?;
|
|
|
|
tracing::info!(addr = %config.appks_addr, "Connected to appks gRPC services");
|
|
|
|
Ok(Self {
|
|
token: TokenServiceClient::new(channel.clone()),
|
|
channel: ChannelServiceClient::new(channel.clone()),
|
|
member: MemberServiceClient::new(channel.clone()),
|
|
permission: PermissionServiceClient::new(channel),
|
|
})
|
|
}
|
|
|
|
/// Build from pre-connected clients (useful for tests with mock servers).
|
|
pub fn new(
|
|
token: TokenServiceClient<Channel>,
|
|
channel: ChannelServiceClient<Channel>,
|
|
member: MemberServiceClient<Channel>,
|
|
permission: PermissionServiceClient<Channel>,
|
|
) -> Self {
|
|
Self {
|
|
token,
|
|
channel,
|
|
member,
|
|
permission,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn build_tls_config(config: &RpcConfig) -> ImksResult<ClientTlsConfig> {
|
|
let mut tls = ClientTlsConfig::new();
|
|
|
|
if let Some(domain) = &config.tls_domain_name {
|
|
tls = tls.domain_name(domain);
|
|
}
|
|
|
|
if let Some(path) = &config.tls_ca_cert_path {
|
|
let pem = fs::read(path)?;
|
|
tls = tls.ca_certificate(Certificate::from_pem(pem));
|
|
}
|
|
|
|
match (&config.tls_client_cert_path, &config.tls_client_key_path) {
|
|
(Some(cert_path), Some(key_path)) => {
|
|
let cert = fs::read(cert_path)?;
|
|
let key = fs::read(key_path)?;
|
|
tls = tls.identity(Identity::from_pem(cert, key));
|
|
}
|
|
(None, None) => {}
|
|
_ => {
|
|
return Err(ImksError::InvalidInput(
|
|
"Both APPKS_GRPC_TLS_CLIENT_CERT and APPKS_GRPC_TLS_CLIENT_KEY are required for mTLS".into(),
|
|
));
|
|
}
|
|
}
|
|
|
|
Ok(tls)
|
|
}
|