pub mod api_key;
pub mod error;
pub mod guard;
pub mod oauth2;
pub mod password;
pub mod passwordless;
pub mod providers;
#[cfg(feature = "saml")]
pub mod saml;
pub mod strategy;
#[cfg(feature = "two-factor")]
pub mod two_factor;
pub mod user;
pub use api_key::{ApiKey, ApiKeyError, ApiKeyManager, ApiKeyStore};
pub use error::{AuthError, Result};
pub use guard::{AuthGuard, Guard, RoleGuard};
pub use oauth2::{OAuth2Provider, OAuth2Token, OAuth2UserInfo};
pub use password::{PasswordHasher, PasswordVerifier};
pub use passwordless::{MagicLinkToken, PasswordlessError, WebAuthnManager};
#[cfg(feature = "saml")]
pub use saml::{
ContactInfo, IdpMetadata, SamlAssertion, SamlAuthRequest, SamlConfig, SamlProvider,
SamlServiceProvider,
};
pub use strategy::{AuthStrategy, JwtStrategy, LocalStrategy};
#[cfg(feature = "two-factor")]
pub use two_factor::{BackupCodes, TotpSecret, TwoFactorError};
pub use user::{AuthUser, UserContext};
pub use providers::{
Auth0Provider, AwsCognitoProvider, DiscordProvider, DiscordUser, GitHubProvider, GitHubUser,
GitLabProvider, GitLabUser, GoogleProvider, LinkedInProvider, LinkedInUser,
MicrosoftEntraProvider, OktaProvider,
};
use armature_jwt::JwtManager;
use armature_log::{debug, trace};
use std::sync::Arc;
#[derive(Clone)]
pub struct AuthService {
jwt_manager: Option<Arc<JwtManager>>,
password_hasher: PasswordHasher,
}
impl AuthService {
pub fn new() -> Self {
debug!("Creating new AuthService");
Self {
jwt_manager: None,
password_hasher: PasswordHasher::default(),
}
}
pub fn with_jwt(jwt_manager: JwtManager) -> Self {
debug!("Creating AuthService with JWT manager");
Self {
jwt_manager: Some(Arc::new(jwt_manager)),
password_hasher: PasswordHasher::default(),
}
}
pub fn with_password_hasher(mut self, hasher: PasswordHasher) -> Self {
debug!("Setting password hasher");
self.password_hasher = hasher;
self
}
pub fn hash_password(&self, password: &str) -> Result<String> {
trace!("Hashing password");
self.password_hasher.hash(password)
}
pub fn verify_password(&self, password: &str, hash: &str) -> Result<bool> {
trace!("Verifying password");
self.password_hasher.verify(password, hash)
}
pub fn jwt_manager(&self) -> Option<&JwtManager> {
self.jwt_manager.as_deref()
}
pub fn validate<T: AuthUser>(&self, user: &T) -> Result<()> {
debug!("Validating user authentication");
if !user.is_active() {
debug!("User is inactive");
return Err(AuthError::InactiveUser);
}
trace!("User validation successful");
Ok(())
}
}
impl Default for AuthService {
fn default() -> Self {
Self::new()
}
}
pub mod prelude {
pub use crate::AuthService;
pub use crate::api_key::{ApiKey, ApiKeyManager, ApiKeyStore};
pub use crate::error::{AuthError, Result};
pub use crate::guard::{AuthGuard, Guard, RoleGuard};
pub use crate::oauth2::{OAuth2Provider, OAuth2Token, OAuth2UserInfo};
pub use crate::password::{PasswordHasher, PasswordVerifier};
pub use crate::strategy::{AuthStrategy, JwtStrategy, LocalStrategy};
pub use crate::user::{AuthUser, UserContext};
pub use crate::providers::{
Auth0Provider, AwsCognitoProvider, DiscordProvider, GitHubProvider, GitLabProvider,
GoogleProvider, LinkedInProvider, MicrosoftEntraProvider, OktaProvider,
};
#[cfg(feature = "saml")]
pub use crate::saml::{SamlConfig, SamlProvider, SamlServiceProvider};
#[cfg(feature = "two-factor")]
pub use crate::two_factor::{BackupCodes, TotpSecret, TwoFactorError};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_password_hashing() {
let service = AuthService::new();
let password = "test-password-123";
let hash = service.hash_password(password).unwrap();
assert!(service.verify_password(password, &hash).unwrap());
assert!(!service.verify_password("wrong-password", &hash).unwrap());
}
}