//! Auth-specific unit tests driven by mock credential stores. #[path = "../support/mod.rs"] mod support; mod helpers; use helpers::*; use niom_turn::auth::{self, AuthStatus}; use niom_turn::traits::CredentialStore; use support::mocks; use crate::support::stun_builders::{build_allocate_request, parse}; fn realm_options(realm: &str) -> niom_turn::config::AuthOptions { let mut opts = default_options(); opts.realm = realm.to_string(); opts.nonce_secret = Some("static-secret".into()); opts } #[tokio::test(flavor = "current_thread")] async fn credential_store_mock_allows_lookup() { let mut store = mocks::MockCredentialStore::new(); store .expect_get_password() .with(mocks::predicates::eq("alice")) .returning(|_| Box::pin(async { Some("s3cret".to_string()) })); let password = CredentialStore::get_password(&store, "alice").await; assert_eq!(password.as_deref(), Some("s3cret")); } #[tokio::test(flavor = "current_thread")] async fn rejects_mismatched_realm_requests() { let peer = loopback_peer(); let mut store = niom_turn::auth::InMemoryStore::new(); store.insert("alice", "secret"); let auth = niom_turn::auth::AuthManager::new(store, &realm_options("expected.realm")); let nonce = auth.mint_nonce(&peer); let wrong_realm = "other.realm"; let key = auth::compute_a1_md5("alice", wrong_realm, "secret"); let buf = build_allocate_request( Some("alice"), Some(wrong_realm), Some(&nonce), Some(&key), Some(600), ); let msg = parse(&buf); match auth.authenticate(&msg, &peer).await { AuthStatus::Reject { code, reason } => { assert_eq!(code, 400); assert_eq!(reason, "Realm Mismatch"); } other => panic!("unexpected auth result: {:?}", other), } } #[tokio::test(flavor = "current_thread")] async fn rejects_unknown_user() { let peer = loopback_peer(); let auth = build_auth_manager(); let nonce = auth.mint_nonce(&peer); let key = auth::compute_a1_md5("intruder", auth.realm(), "badpass"); let buf = build_allocate_request( Some("intruder"), Some(auth.realm()), Some(&nonce), Some(&key), Some(600), ); let msg = parse(&buf); match auth.authenticate(&msg, &peer).await { AuthStatus::Reject { code, reason } => { assert_eq!(code, 401); assert_eq!(reason, "Unknown User"); } other => panic!("unexpected auth result: {:?}", other), } }