pub use broadcast_auth::{Authenticator, Credentials, RequestContext};
use crate::error::Error;
impl From<broadcast_auth::Error> for Error {
fn from(e: broadcast_auth::Error) -> Self {
Error::Auth(e.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
const CHALLENGE: &str = "Digest realm=\"IP Camera\",nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\",qop=\"auth\",algorithm=MD5";
#[test]
fn digest_authorization_contains_required_fields() {
let mut auth =
Authenticator::from_challenge(CHALLENGE, Credentials::new("admin", "12345")).unwrap();
let value = auth
.authorization(&RequestContext::new(
"DESCRIBE",
"rtsp://camera.example.com/live",
))
.unwrap();
assert!(value.starts_with("Digest "), "got: {value}");
for needle in ["response=", "realm=", "nonce=", "uri=", "cnonce=", "nc="] {
assert!(value.contains(needle), "missing {needle} in {value}");
}
assert!(value.contains("uri=\"rtsp://camera.example.com/live\""));
}
#[test]
fn basic_authorization_is_computed() {
let mut auth = Authenticator::from_challenge(
"Basic realm=\"IP Camera\"",
Credentials::new("admin", "12345"),
)
.unwrap();
let value = auth
.authorization(&RequestContext::new("DESCRIBE", "rtsp://c/live"))
.unwrap();
assert!(value.starts_with("Basic "));
assert_ne!(value, "Basic ");
}
#[test]
fn bearer_authorization_is_computed() {
let mut auth =
Authenticator::from_challenge("", Credentials::bearer("mytoken123")).unwrap();
let value = auth
.authorization(&RequestContext::new("DESCRIBE", "rtsp://c/live"))
.unwrap();
assert_eq!(value, "Bearer mytoken123");
}
}