pub mod config;
pub mod credentials;
use crate::error::{ZitiError, ZitiResult};
use config::Config;
use credentials::{Credentials, Identity as IdentityCredentials};
use serde_json;
use std::path::Path;
use tokio::fs;
pub use config::{Config as IdentityConfig, IdentityConfig as LegacyIdentityConfig};
pub use credentials::Identity;
#[derive(Debug, Clone)]
pub struct IdentityManager {
pub config: Config,
pub credentials: Credentials,
pub identity: IdentityCredentials,
}
impl IdentityManager {
pub fn new(config: Config, credentials: Credentials) -> Self {
let identity =
IdentityCredentials::from_config_and_credentials(&config, credentials.clone());
Self {
config,
credentials,
identity,
}
}
pub async fn load_from_file<P: AsRef<Path>>(path: P) -> ZitiResult<Self> {
load(path.as_ref()).await
}
pub fn id(&self) -> &str {
&self.config.id
}
pub fn zt_api(&self) -> &str {
&self.config.zt_api
}
pub fn identity(&self) -> &IdentityCredentials {
&self.identity
}
pub fn config(&self) -> &Config {
&self.config
}
pub fn credentials(&self) -> &Credentials {
&self.credentials
}
}
pub async fn load(path: &Path) -> ZitiResult<IdentityManager> {
let json_content = fs::read_to_string(path).await.map_err(|e| {
ZitiError::ConfigError(format!("Failed to read identity file {:?}: {}", path, e))
})?;
let config: Config = serde_json::from_str(&json_content).map_err(|e| {
ZitiError::ConfigError(format!(
"Failed to parse identity JSON from {:?}: {}",
path, e
))
})?;
let credentials = Credentials::load_from_config(&config).await?;
Ok(IdentityManager::new(config, credentials))
}
pub async fn load_from_file<P: AsRef<Path>>(path: P) -> ZitiResult<IdentityManager> {
load(path.as_ref()).await
}
#[cfg(test)]
mod tests {
use super::*;
use rustls::RootCertStore;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
fn create_mock_config() -> Config {
Config::new(
"https://controller.example.com".to_string(),
"test-identity".to_string(),
"cert.pem".to_string(),
"key.pem".to_string(),
"ca.pem".to_string(),
)
}
fn create_mock_credentials() -> Credentials {
Credentials::new(
vec![CertificateDer::from(vec![0u8; 32])], PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(vec![0u8; 32])), RootCertStore::empty(), )
}
#[test]
fn test_identity_manager_new() {
let config = create_mock_config();
let credentials = create_mock_credentials();
let manager = IdentityManager::new(config.clone(), credentials);
assert_eq!(manager.id(), "test-identity");
assert_eq!(manager.zt_api(), "https://controller.example.com");
assert_eq!(manager.config().id, config.id);
}
#[test]
fn test_identity_manager_getters() {
let config = create_mock_config();
let credentials = create_mock_credentials();
let manager = IdentityManager::new(config, credentials);
assert_eq!(manager.id(), "test-identity");
assert_eq!(manager.zt_api(), "https://controller.example.com");
assert!(manager.identity().id == "test-identity");
assert!(manager.config().zt_api == "https://controller.example.com");
assert!(manager.credentials().certificate_chain.len() == 1);
}
#[test]
fn test_identity_manager_clone() {
let config = create_mock_config();
let credentials = create_mock_credentials();
let original = IdentityManager::new(config, credentials);
let cloned = original.clone();
assert_eq!(cloned.id(), original.id());
assert_eq!(cloned.zt_api(), original.zt_api());
assert_eq!(cloned.config().id, original.config().id);
}
#[test]
fn test_identity_manager_with_different_values() {
let config = Config::new(
"https://different.controller.com:8443".to_string(),
"different-id".to_string(),
"different-cert.pem".to_string(),
"different-key.pem".to_string(),
"different-ca.pem".to_string(),
);
let credentials = create_mock_credentials();
let manager = IdentityManager::new(config, credentials);
assert_eq!(manager.id(), "different-id");
assert_eq!(manager.zt_api(), "https://different.controller.com:8443");
}
#[test]
fn test_identity_credentials_from_manager() {
let config = create_mock_config();
let credentials = create_mock_credentials();
let manager = IdentityManager::new(config, credentials);
let identity = manager.identity();
assert_eq!(identity.id, "test-identity");
assert_eq!(identity.certificate_chain.len(), 1);
}
}