#![allow(missing_docs)]
#[test]
fn crypto_sha256_accessible_via_reexport() {
let hash = entropy_auth::Sha256::digest(b"hello");
assert_eq!(hash.len(), 32);
}
#[test]
fn crypto_sha512_accessible_via_reexport() {
let hash = entropy_auth::Sha512::digest(b"hello");
assert_eq!(hash.len(), 64);
}
#[test]
fn crypto_hmac_sha256_accessible_via_reexport() {
let tag = entropy_auth::HmacSha256::mac(b"key", b"data");
assert_eq!(tag.len(), 32);
assert!(entropy_auth::HmacSha256::verify(b"key", b"data", &tag));
}
#[test]
fn crypto_hmac_sha512_accessible_via_reexport() {
let tag = entropy_auth::HmacSha512::mac(b"key", b"data");
assert_eq!(tag.len(), 64);
assert!(entropy_auth::HmacSha512::verify(b"key", b"data", &tag));
}
#[test]
fn crypto_fill_random_accessible_via_reexport() {
let mut buf = [0u8; 16];
entropy_auth::fill_random(&mut buf).unwrap();
assert_ne!(buf, [0u8; 16]);
}
#[test]
fn crypto_random_token_hex_accessible_via_reexport() {
let token = entropy_auth::random_token_hex(16).unwrap();
assert_eq!(token.len(), 32);
}
#[test]
fn crypto_random_token_base64url_accessible_via_reexport() {
let token = entropy_auth::random_token_base64url(16).unwrap();
assert!(!token.is_empty());
}
#[test]
fn encoding_base64_round_trip_via_reexport() {
let encoded = entropy_auth::base64_encode(b"test data");
let decoded = entropy_auth::base64_decode(&encoded).unwrap();
assert_eq!(decoded, b"test data");
}
#[test]
fn encoding_base64url_round_trip_via_reexport() {
let encoded = entropy_auth::base64url_encode(b"test data");
let decoded = entropy_auth::base64url_decode(&encoded).unwrap();
assert_eq!(decoded, b"test data");
}
#[test]
fn encoding_hex_round_trip_via_reexport() {
let encoded = entropy_auth::hex_encode(b"\xde\xad\xbe\xef");
let decoded = entropy_auth::hex_decode(&encoded).unwrap();
assert_eq!(decoded, b"\xde\xad\xbe\xef");
}
#[test]
fn encoding_url_round_trip_via_reexport() {
let encoded = entropy_auth::url_encode("hello world");
let decoded = entropy_auth::url_decode(&encoded).unwrap();
assert_eq!(decoded, "hello world");
}
#[test]
fn encoding_url_encode_component_via_reexport() {
let encoded = entropy_auth::url_encode_component("a=b&c=d");
assert!(encoded.contains("%3D"));
assert!(encoded.contains("%26"));
}
#[test]
fn encoding_error_types_accessible() {
let _: Result<Vec<u8>, entropy_auth::Base64DecodeError> = entropy_auth::base64_decode("!!!");
let _: Result<Vec<u8>, entropy_auth::HexDecodeError> = entropy_auth::hex_decode("zz");
let _: Result<String, entropy_auth::UrlDecodeError> = entropy_auth::url_decode("%ZZ");
}
#[test]
fn password_config_default_via_reexport() {
let config = entropy_auth::PasswordConfig::default();
assert_eq!(config.memory_kib(), 65_536);
assert_eq!(config.iterations(), 3);
assert_eq!(config.parallelism(), 4);
}
#[test]
fn password_hash_type_accessible_via_reexport() {
let config = entropy_auth::PasswordConfig::new()
.with_memory_kib(entropy_auth::local::password::MIN_MEMORY_KIB)
.with_iterations(1)
.with_parallelism(1);
let hash = entropy_auth::PasswordHash::generate(b"pw", &config).unwrap();
assert!(hash.verify(b"pw"));
}
#[test]
fn password_error_type_accessible() {
let result: Result<entropy_auth::PasswordHash, entropy_auth::PasswordError> =
entropy_auth::PasswordHash::parse("invalid");
assert!(result.is_err());
}
#[test]
fn session_config_default_via_reexport() {
let config = entropy_auth::SessionConfig::default();
assert_eq!(config.token_bytes(), 32);
assert_eq!(config.lifetime_secs(), 3600);
}
#[test]
fn session_create_and_validate_via_reexport() {
let config = entropy_auth::SessionConfig::default();
let (token, session) = entropy_auth::Session::create(&config).unwrap();
let now = entropy_auth::Timestamp::now();
assert_eq!(
session.validate(&token, &now),
entropy_auth::SessionValidation::Valid,
);
}
#[test]
fn session_error_type_accessible() {
let _: fn() -> entropy_auth::SessionError = || {
let config = entropy_auth::SessionConfig::default().with_allow_refresh(false);
let (_, mut session) = entropy_auth::Session::create(&config).unwrap();
let now = entropy_auth::Timestamp::now();
session.refresh(&config, &now).unwrap_err()
};
}
#[test]
fn api_key_generate_via_reexport() {
let (key, hash) = entropy_auth::ApiKey::generate().unwrap();
assert!(key.verify(&hash));
}
#[test]
fn api_key_error_accessible() {
let _: Result<entropy_auth::ApiKey, entropy_auth::ApiKeyError> =
entropy_auth::ApiKey::parse("bad");
}
#[test]
fn api_key_hash_accessible() {
let (_, hash) = entropy_auth::ApiKey::generate().unwrap();
let _prefix: &str = hash.prefix();
let _secret_hash: &[u8; 32] = hash.secret_hash();
}
#[test]
fn hmac_request_signer_via_reexport() {
let signer = entropy_auth::HmacRequestSigner::new(b"secret".to_vec());
let sig = signer.sign("GET", "/", "0", b"");
assert_eq!(sig.len(), 64);
}
#[test]
fn hmac_request_verifier_via_reexport() {
let verifier = entropy_auth::HmacRequestVerifier::new(b"secret".to_vec());
let signer = entropy_auth::HmacRequestSigner::new(b"secret".to_vec());
let sig = signer.sign("GET", "/", "0", b"");
assert!(verifier.verify("GET", "/", "0", b"", &sig).is_ok());
}
#[test]
fn hmac_auth_error_accessible() {
let _: Result<(), entropy_auth::HmacAuthError> =
entropy_auth::HmacRequestVerifier::new(b"s".to_vec()).verify("GET", "/", "0", b"", "bad");
}
#[test]
fn bearer_token_extraction_via_reexport() {
let token = entropy_auth::extract_bearer_token("Bearer xyz").unwrap();
assert_eq!(token, "xyz");
}
#[test]
fn bearer_error_accessible() {
let _: Result<&str, entropy_auth::BearerError> = entropy_auth::extract_bearer_token("nope");
}
#[test]
fn json_value_parse_via_reexport() {
let val = entropy_auth::JsonValue::parse(r#"{"key":"value"}"#).unwrap();
assert_eq!(val.get_str("key"), Some("value"));
}
#[test]
fn json_parse_error_accessible() {
let _: Result<entropy_auth::JsonValue, entropy_auth::JsonParseError> =
entropy_auth::JsonValue::parse("bad json");
}
#[test]
fn jwt_types_accessible_via_reexport() {
let _: fn() -> &'static str = || {
let _ = entropy_auth::JwtAlgorithm::HS256;
"ok"
};
}
#[test]
fn oauth_config_builder_via_reexport() {
let config = entropy_auth::OAuthConfig::builder("client-id", "client-secret")
.authorization_endpoint("https://auth.example.com/authorize")
.token_endpoint("https://auth.example.com/token")
.redirect_uri("https://app.example.com/callback")
.scope("openid")
.build()
.unwrap();
assert_eq!(config.client_id(), "client-id");
}
#[test]
fn oauth_config_error_accessible() {
let _: Result<entropy_auth::OAuthConfig, entropy_auth::OAuthConfigError> =
entropy_auth::OAuthConfig::builder("", "s")
.authorization_endpoint("https://x.com/a")
.token_endpoint("https://x.com/t")
.redirect_uri("https://x.com/cb")
.build();
}
#[test]
fn authorization_request_via_reexport() {
let config = entropy_auth::OAuthConfig::builder("cid", "cs")
.authorization_endpoint("https://auth.example.com/authorize")
.token_endpoint("https://auth.example.com/token")
.redirect_uri("https://app.example.com/callback")
.build()
.unwrap();
let req = entropy_auth::AuthorizationRequest::build(&config).unwrap();
assert!(req.url().contains("client_id=cid"));
}
#[test]
fn pkce_challenge_via_reexport() {
let pkce = entropy_auth::PkceChallenge::generate().unwrap();
assert_eq!(pkce.method(), "S256");
assert!(!pkce.verifier().is_empty());
assert!(!pkce.challenge().is_empty());
}
#[test]
fn token_response_via_reexport() {
let json = r#"{"access_token":"tok","token_type":"Bearer"}"#;
let resp = entropy_auth::TokenResponse::parse(json).unwrap();
assert_eq!(resp.access_token(), "tok");
}
#[test]
fn token_response_error_accessible() {
let _: Result<entropy_auth::TokenResponse, entropy_auth::TokenResponseError> =
entropy_auth::TokenResponse::parse("bad");
}
#[test]
fn refresh_request_via_reexport() {
let config = entropy_auth::OAuthConfig::builder("cid", "cs")
.authorization_endpoint("https://auth.example.com/authorize")
.token_endpoint("https://auth.example.com/token")
.redirect_uri("https://app.example.com/callback")
.build()
.unwrap();
let req = entropy_auth::RefreshRequest::new(&config, "refresh-tok");
assert!(req.body().contains("grant_type=refresh_token"));
}
#[test]
fn auth_provider_kind_accessible() {
let kind = entropy_auth::AuthProviderKind::Local;
assert_eq!(kind.to_string(), "local");
}
#[test]
fn auth_identity_accessible() {
let id = entropy_auth::AuthIdentity::new("sub-1")
.with_email("a@b.com")
.with_display_name("Alice")
.with_claim("role", "admin");
assert_eq!(id.subject(), "sub-1");
assert_eq!(id.email(), Some("a@b.com"));
assert_eq!(id.display_name(), Some("Alice"));
assert_eq!(id.claims().len(), 1);
}
#[test]
fn auth_result_accessible() {
let identity = entropy_auth::AuthIdentity::new("user-1");
let ts = entropy_auth::Timestamp::now();
let result = entropy_auth::AuthResult::new(identity, entropy_auth::AuthProviderKind::OAuth, ts);
assert_eq!(result.provider(), entropy_auth::AuthProviderKind::OAuth);
assert!(result.session().is_none());
}
#[test]
fn auth_error_accessible() {
fn assert_auth_error_api(err: &entropy_auth::AuthError) {
let _ = err.is_invalid_credentials();
let _ = err.is_token_expired();
let _ = err.is_invalid_token();
let _ = err.is_invalid_configuration();
let _ = err.is_crypto();
let _ = err.is_session_expired();
let _ = err.is_provider();
let _ = err.detail();
let _ = err.to_string();
let _ = format!("{err:?}");
}
let _ = assert_auth_error_api;
}
#[test]
fn constant_time_eq_via_reexport() {
assert!(entropy_auth::constant_time_eq(b"abc", b"abc"));
assert!(!entropy_auth::constant_time_eq(b"abc", b"xyz"));
}
#[test]
fn timestamp_via_reexport() {
let ts = entropy_auth::Timestamp::now();
assert!(ts.unix_epoch_secs() > 0);
}
#[test]
fn zeroizing_via_reexport() {
let z = entropy_auth::Zeroizing::new(vec![1u8, 2, 3]);
assert_eq!(&*z, &[1, 2, 3]);
}
#[test]
fn generate_token_via_reexport() {
let token = entropy_auth::generate_token(16).unwrap();
assert_eq!(token.len(), 32);
}
#[test]
fn generate_token_with_hash_via_reexport() {
let (token, hash) = entropy_auth::generate_token_with_hash(16).unwrap();
assert_eq!(token.len(), 32);
assert_eq!(hash.len(), 32);
}
#[test]
fn credential_types_accessible_via_reexport() {
let _store = entropy_auth::InMemoryCredentialStore::new();
let creds = entropy_auth::Credentials::new("testuser", b"testpass".to_vec()).unwrap();
assert_eq!(creds.username().as_str(), "testuser");
}
#[test]
fn in_memory_store_error_is_nameable_via_reexport() {
fn assert_error<E: std::error::Error>() {}
assert_error::<entropy_auth::InMemoryStoreError>();
}