#[cfg(feature = "security")]
use super::super::make_auth_interceptor;
#[cfg(feature = "security")]
use super::make_test_jwt;
#[cfg(feature = "security")]
use tonic::service::Interceptor;
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_valid_token() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let exp = chrono::Utc::now().timestamp() + 365 * 24 * 3600;
let valid_token = make_test_jwt(secret, exp);
let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from(format!("Bearer {}", valid_token).as_str())
.expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(
result.is_ok(),
"Valid token should be accepted by interceptor"
);
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_missing_auth_header() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let req = tonic::Request::new(());
let result = interceptor.call(req);
assert!(result.is_err(), "Missing auth header should be rejected");
let status = result.unwrap_err();
assert_eq!(status.code(), tonic::Code::Unauthenticated);
assert_eq!(
status.message(),
"Missing authorization header",
"Error message should match expected text"
);
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_invalid_token() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let wrong_secret = "WrongSecret000!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let exp = chrono::Utc::now().timestamp() + 365 * 24 * 3600;
let invalid_token = make_test_jwt(wrong_secret, exp);
let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from(format!("Bearer {}", invalid_token).as_str())
.expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(result.is_err(), "Invalid token should be rejected");
let status = result.unwrap_err();
assert_eq!(status.code(), tonic::Code::Unauthenticated);
assert_eq!(
status.message(),
"Invalid or expired token",
"Error message should match expected text"
);
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_expired_token() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let expired_token = make_test_jwt(secret, 946684799); let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from(format!("Bearer {}", expired_token).as_str())
.expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(result.is_err(), "Expired token should be rejected");
let status = result.unwrap_err();
assert_eq!(status.code(), tonic::Code::Unauthenticated);
assert_eq!(
status.message(),
"Invalid or expired token",
"Error message should match expected text"
);
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_no_auth_configured() {
let mut interceptor = make_auth_interceptor(None);
let req = tonic::Request::new(());
let result = interceptor.call(req);
assert!(
result.is_ok(),
"When no auth is configured, interceptor should pass through all requests"
);
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_with_malformed_bearer_prefix() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from("Bearerinvalid_token")
.expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(result.is_err());
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_with_basic_auth_instead_of_bearer() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from("Basic dXNlcjpwYXNz")
.expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(result.is_err());
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_with_empty_token() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from("Bearer ").expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(result.is_err());
}
#[cfg(feature = "security")]
#[test]
fn test_auth_interceptor_metadata_key_lowercase_required() {
let secret = "ValidSecret123!ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let auth = crate::security::BearerAuth::try_new(secret).expect("valid secret");
let mut interceptor = make_auth_interceptor(Some(auth));
let exp = chrono::Utc::now().timestamp() + 365 * 24 * 3600;
let valid_token = make_test_jwt(secret, exp);
let auth_value: tonic::metadata::MetadataValue<tonic::metadata::Ascii> =
tonic::metadata::MetadataValue::try_from(format!("Bearer {}", valid_token).as_str())
.expect("valid metadata value");
let mut req = tonic::Request::new(());
req.metadata_mut().insert("authorization", auth_value);
let result = interceptor.call(req);
assert!(result.is_ok(), "Lowercase 'authorization' key should work");
}