1pub use broadcast_auth::{Authenticator, Credentials, RequestContext};
19
20use crate::error::Error;
21
22impl From<broadcast_auth::Error> for Error {
23 fn from(e: broadcast_auth::Error) -> Self {
24 Error::Auth(e.to_string())
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31
32 const CHALLENGE: &str = "Digest realm=\"IP Camera\",nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\",qop=\"auth\",algorithm=MD5";
33
34 #[test]
35 fn digest_authorization_contains_required_fields() {
36 let mut auth =
37 Authenticator::from_challenge(CHALLENGE, Credentials::new("admin", "12345")).unwrap();
38 let value = auth
39 .authorization(&RequestContext::new(
40 "DESCRIBE",
41 "rtsp://camera.example.com/live",
42 ))
43 .unwrap();
44 assert!(value.starts_with("Digest "), "got: {value}");
45 for needle in ["response=", "realm=", "nonce=", "uri=", "cnonce=", "nc="] {
46 assert!(value.contains(needle), "missing {needle} in {value}");
47 }
48 assert!(value.contains("uri=\"rtsp://camera.example.com/live\""));
49 }
50
51 #[test]
52 fn basic_authorization_is_computed() {
53 let mut auth = Authenticator::from_challenge(
54 "Basic realm=\"IP Camera\"",
55 Credentials::new("admin", "12345"),
56 )
57 .unwrap();
58 let value = auth
59 .authorization(&RequestContext::new("DESCRIBE", "rtsp://c/live"))
60 .unwrap();
61 assert!(value.starts_with("Basic "));
62 assert_ne!(value, "Basic ");
63 }
64
65 #[test]
66 fn bearer_authorization_is_computed() {
67 let mut auth =
68 Authenticator::from_challenge("", Credentials::bearer("mytoken123")).unwrap();
69 let value = auth
70 .authorization(&RequestContext::new("DESCRIBE", "rtsp://c/live"))
71 .unwrap();
72 assert_eq!(value, "Bearer mytoken123");
73 }
74}