#![ allow( clippy::unreadable_literal ) ]
#![ allow( clippy::uninlined_format_args ) ]
#![ allow( clippy::std_instead_of_core ) ]
#![ allow( clippy::useless_vec ) ]
#![ allow( clippy::unused_async ) ]
#![ allow( clippy::return_self_not_must_use ) ]
#![ allow( clippy::cast_sign_loss ) ]
#![ allow( clippy::let_and_return ) ]
#![ allow( clippy::no_effect_underscore_binding ) ]
#![ allow( clippy::doc_markdown ) ]
#![ allow( clippy::single_component_path_imports ) ]
#![ allow( clippy::ignore_without_reason ) ]
use api_openai::ClientApiAccessors;
use api_openai::exposed::
{
environment ::
{
OpenaiEnvironmentImpl,
},
secret ::Secret,
error ::OpenAIError,
client ::Client,
};
use std::
{
collections ::HashMap,
time ::{ Duration, Instant },
sync ::{ Arc, Mutex },
};
use tokio::time::sleep;
use futures;
use chrono;
#[ derive( Debug, Clone ) ]
pub struct AdvancedAuthConfig
{
pub primary_api_key : String,
pub secondary_api_key : Option< String >,
pub oauth_access_token : Option< String >,
pub oauth_refresh_token : Option< String >,
pub token_expires_at : Option< u64 >,
pub organization_context : Option< String >,
pub project_context : Option< String >,
pub audit_trail_enabled : bool,
pub max_auth_retries : u32,
pub auth_timeout : Duration,
}
impl Default for AdvancedAuthConfig
{
fn default() -> Self
{
Self
{
primary_api_key : "sk-test1234567890abcdef1234567890".to_string(),
secondary_api_key : None,
oauth_access_token : None,
oauth_refresh_token : None,
token_expires_at : None,
organization_context : None,
project_context : None,
audit_trail_enabled : false,
max_auth_retries : 3,
auth_timeout : Duration::from_secs(30),
}
}
}
#[ derive( Debug, Clone, serde::Deserialize, serde::Serialize ) ]
pub struct OAuthTokenResponse
{
pub access_token : String,
pub token_type : String,
pub expires_in : u64,
pub refresh_token : Option< String >,
pub scope : Option< String >,
}
#[ derive( Debug, Clone ) ]
pub struct MultiTenantAuthContext
{
pub primary_org_id : String,
pub secondary_org_id : Option< String >,
pub tenant_api_keys : HashMap< String, String >,
pub tenant_rate_limits : HashMap< String, u32 >,
pub isolation_enforced : bool,
}
#[ derive( Debug, Clone ) ]
pub struct AuthAuditLogEntry
{
pub timestamp : Instant,
pub event_type : String,
pub success : bool,
pub client_id : String,
pub context : HashMap< String, String >,
}
pub struct AdvancedAuthManager
{
pub config : AdvancedAuthConfig,
pub multi_tenant_context : Option< MultiTenantAuthContext >,
pub audit_log : Arc< Mutex< Vec< AuthAuditLogEntry > > >,
pub token_refresh_callback : Option< Box< dyn Fn() -> Result< OAuthTokenResponse, OpenAIError > + Send + Sync > >,
}
impl AdvancedAuthManager
{
#[ allow( clippy::must_use_candidate ) ]
pub fn new(config : AdvancedAuthConfig) -> Self
{
Self
{
config,
multi_tenant_context : None,
audit_log : Arc::new(Mutex::new(Vec::new())),
token_refresh_callback : None,
}
}
#[ allow( clippy::must_use_candidate ) ]
pub fn with_multi_tenant_context(mut self, context : MultiTenantAuthContext) -> Self
{
self.multi_tenant_context = Some(context);
self
}
pub fn with_token_refresh_callback< F >(mut self, callback : F) -> Self
where
F: Fn() -> Result< OAuthTokenResponse, OpenAIError > + Send + Sync + 'static,
{
self.token_refresh_callback = Some(Box::new(callback));
self
}
}
impl std::fmt::Debug for AdvancedAuthManager
{
fn fmt(&self, f : &mut std::fmt::Formatter< '_ >) -> std::fmt::Result
{
f.debug_struct("AdvancedAuthManager")
.field("config", &self.config)
.field("multi_tenant_context", &self.multi_tenant_context)
.field("audit_log", &self.audit_log)
.field("token_refresh_callback", &self.token_refresh_callback.is_some())
.finish()
}
}
#[ tokio::test ]
async fn test_oauth_token_refresh_mechanism()
{
let config = AdvancedAuthConfig
{
oauth_access_token : Some("expired_access_token_12345".to_string()),
oauth_refresh_token : Some("refresh_token_67890".to_string()),
token_expires_at : Some(chrono::Utc::now().timestamp() as u64 - 3600), ..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config)
.with_token_refresh_callback(|| {
Ok(OAuthTokenResponse
{
access_token : "new_access_token_54321".to_string(),
token_type : "Bearer".to_string(),
expires_in : 3600,
refresh_token : Some("new_refresh_token_09876".to_string()),
scope : Some("read write".to_string()),
})
});
assert!(auth_manager.config.oauth_access_token.is_some());
assert!(auth_manager.config.oauth_refresh_token.is_some());
assert!(auth_manager.token_refresh_callback.is_some());
}
#[ tokio::test ]
async fn test_multi_tenant_authentication_isolation()
{
let mut tenant_keys = HashMap::new();
tenant_keys.insert("tenant_a".to_string(), "sk-tenant_a_12345".to_string());
tenant_keys.insert("tenant_b".to_string(), "sk-tenant_b_67890".to_string());
let mut tenant_limits = HashMap::new();
tenant_limits.insert("tenant_a".to_string(), 100);
tenant_limits.insert("tenant_b".to_string(), 200);
let multi_tenant_context = MultiTenantAuthContext
{
primary_org_id : "org_primary_123".to_string(),
secondary_org_id : Some("org_secondary_456".to_string()),
tenant_api_keys : tenant_keys,
tenant_rate_limits : tenant_limits,
isolation_enforced : true,
};
let auth_manager = AdvancedAuthManager::new(AdvancedAuthConfig::default())
.with_multi_tenant_context(multi_tenant_context);
assert!(auth_manager.multi_tenant_context.is_some());
let context = auth_manager.multi_tenant_context.as_ref().unwrap();
assert_eq!(context.tenant_api_keys.len(), 2);
assert!(context.isolation_enforced);
}
#[ tokio::test ]
async fn test_authentication_failover_mechanism()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-invalid_primary_key".to_string(),
secondary_api_key : Some("sk-valid_secondary_key_12345".to_string()),
max_auth_retries : 2,
..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config);
assert!(auth_manager.config.secondary_api_key.is_some());
assert_eq!(auth_manager.config.max_auth_retries, 2);
}
#[ tokio::test ]
async fn test_authentication_with_rate_limiting()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-rate_limited_key_12345".to_string(),
auth_timeout : Duration::from_secs(60),
..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config);
assert_eq!(auth_manager.config.auth_timeout, Duration::from_secs(60));
}
#[ tokio::test ]
async fn test_authentication_security_hardening()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-secure_key_with_validation".to_string(),
audit_trail_enabled : true,
..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config);
assert!(auth_manager.config.audit_trail_enabled);
}
#[ tokio::test ]
async fn test_concurrent_authentication_performance()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-concurrent_test_key_12345".to_string(),
auth_timeout : Duration::from_secs(10),
..AdvancedAuthConfig::default()
};
let auth_manager = Arc::new(AdvancedAuthManager::new(config));
let concurrent_requests = 50;
let mut handles = Vec::new();
for _i in 0..concurrent_requests
{
let _manager_clone = Arc::clone(&auth_manager);
let handle = tokio::spawn(async move {
let start_time = Instant::now();
start_time.elapsed()
});
handles.push(handle);
}
let results = futures::future::join_all(handles).await;
assert_eq!(results.len(), concurrent_requests);
}
#[ tokio::test ]
async fn test_authentication_error_recovery()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-recovery_test_key".to_string(),
max_auth_retries : 5,
auth_timeout : Duration::from_secs(30),
..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config);
assert_eq!(auth_manager.config.max_auth_retries, 5);
}
#[ tokio::test ]
async fn test_authentication_performance_under_load()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-performance_test_key_12345".to_string(),
auth_timeout : Duration::from_secs(5),
..AdvancedAuthConfig::default()
};
let _auth_manager = AdvancedAuthManager::new(config);
let load_test_duration = Duration::from_secs(10);
let start_time = Instant::now();
let _successful_auths = 0;
let mut total_attempts = 0;
while start_time.elapsed() < load_test_duration
{
total_attempts += 1;
sleep(Duration::from_millis(10)).await;
}
assert!(load_test_duration.as_secs() > 0);
assert!(total_attempts > 0);
}
#[ tokio::test ]
async fn test_authentication_with_custom_headers()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-custom_headers_test_key".to_string(),
organization_context : Some("org_custom_123".to_string()),
project_context : Some("proj_custom_456".to_string()),
..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config);
assert!(auth_manager.config.organization_context.is_some());
assert!(auth_manager.config.project_context.is_some());
}
#[ tokio::test ]
async fn test_authentication_session_management()
{
let config = AdvancedAuthConfig
{
primary_api_key : "sk-session_test_key_12345".to_string(),
auth_timeout : Duration::from_secs(300), ..AdvancedAuthConfig::default()
};
let auth_manager = AdvancedAuthManager::new(config);
assert_eq!(auth_manager.config.auth_timeout, Duration::from_secs(300));
}
#[ tokio::test ]
async fn test_advanced_auth_real_integration()
{
let secret = Secret::load_with_fallbacks("OPENAI_API_KEY")
.expect("OPENAI_API_KEY required for real integration test");
let environment = OpenaiEnvironmentImpl::build(
secret,
None, None, api_openai ::environment::OpenAIRecommended::base_url().to_string(),
api_openai ::environment::OpenAIRecommended::realtime_base_url().to_string(),
).expect("Failed to create environment");
let client = Client::build(environment).expect("Failed to build client");
let models_response = client.models().list().await;
match models_response
{
Ok(models) =>
{
assert!(!models.data.is_empty(), "Should return list of available models");
println!("✅ Real authentication successful - got {} models", models.data.len());
},
Err(e) =>
{
panic!("Real authentication failed : {e:?}");
}
}
}