#[cfg(feature = "security")]
pub use traits::*;
#[cfg(feature = "security")]
pub use types::*;
#[cfg(feature = "security")]
pub use api_key::{AppApiKeyAuth, AppApiKeyAuthBuilder};
#[cfg(feature = "security")]
pub use audit::{AppAuditLogger, AppAuditLoggerBuilder};
#[cfg(feature = "security")]
pub use bearer::{generate_secure_jwt_secret, BearerAuth, BearerAuthBuilder};
#[cfg(feature = "security")]
pub use middleware::auth_middleware;
#[cfg(feature = "security")]
mod api_key;
#[cfg(feature = "security")]
mod api_key_manager;
#[cfg(feature = "security")]
mod audit;
#[cfg(feature = "security")]
mod bearer;
#[cfg(feature = "security")]
mod middleware;
#[cfg(feature = "security")]
mod traits;
#[cfg(feature = "security")]
mod types;
#[cfg(any(feature = "security", feature = "ratelimit"))]
mod ip_util;
#[cfg(feature = "ratelimit")]
pub mod ratelimit;
#[cfg(feature = "security")]
pub use api_key_manager::{
ApiKeyMetadata, ApiKeyVersion, LruCacheManager, LruConfig, LruStats, RotationConfig,
};
#[cfg(feature = "security")]
impl traits::ApiKeyAuth for AppApiKeyAuth {
fn validate_key(&self, key: &str, client_ip: &str) -> Option<Vec<String>> {
AppApiKeyAuth::validate_key(self, key, client_ip)
}
fn add_key(&self, key: impl Into<String>, permissions: Vec<String>) {
AppApiKeyAuth::add_key(self, key, permissions);
}
}
#[cfg(all(test, feature = "security"))]
mod tests {
use super::*;
use crate::security::traits::ApiKeyAuth;
#[test]
fn trait_validate_key_returns_permissions_for_valid_key() {
let auth = AppApiKeyAuth::new();
auth.add_key("test-key", vec!["read".to_string()]);
let result = <AppApiKeyAuth as ApiKeyAuth>::validate_key(&auth, "test-key", "127.0.0.1");
assert_eq!(result, Some(vec!["read".to_string()]));
}
#[test]
fn trait_validate_key_returns_none_for_unknown_key() {
let auth = AppApiKeyAuth::new();
let result = <AppApiKeyAuth as ApiKeyAuth>::validate_key(&auth, "unknown-key", "127.0.0.1");
assert_eq!(result, None);
}
#[test]
fn trait_validate_key_returns_none_for_empty_key() {
let auth = AppApiKeyAuth::new();
let result = <AppApiKeyAuth as ApiKeyAuth>::validate_key(&auth, "", "127.0.0.1");
assert_eq!(result, None);
}
#[test]
fn trait_add_key_delegates_to_inherent_method() {
let auth = AppApiKeyAuth::new();
<AppApiKeyAuth as ApiKeyAuth>::add_key(&auth, "trait-key", vec!["admin".to_string()]);
let result = <AppApiKeyAuth as ApiKeyAuth>::validate_key(&auth, "trait-key", "127.0.0.1");
assert_eq!(result, Some(vec!["admin".to_string()]));
}
#[test]
fn trait_add_key_with_string_literal_works() {
let auth = AppApiKeyAuth::new();
<AppApiKeyAuth as ApiKeyAuth>::add_key(&auth, "literal-key", vec!["read".to_string()]);
let result = <AppApiKeyAuth as ApiKeyAuth>::validate_key(&auth, "literal-key", "127.0.0.1");
assert_eq!(result, Some(vec!["read".to_string()]));
}
#[test]
fn trait_dispatch_matches_inherent_dispatch() {
let auth1 = AppApiKeyAuth::new();
let auth2 = AppApiKeyAuth::new();
let perms = vec!["read".to_string(), "write".to_string()];
auth1.add_key("shared-key", perms.clone());
<AppApiKeyAuth as ApiKeyAuth>::add_key(&auth2, "shared-key", perms);
let inherent_result = auth1.validate_key("shared-key", "127.0.0.1");
let trait_result =
<AppApiKeyAuth as ApiKeyAuth>::validate_key(&auth2, "shared-key", "127.0.0.1");
assert_eq!(inherent_result, trait_result);
}
}