use crate::browser::views::AuthCredentials;
use base64::{Engine as _, engine::general_purpose};
use crate::error::Result;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct AuthManager {
client: Arc<crate::browser::cdp::CdpClient>,
}
impl AuthManager {
pub fn new(client: Arc<crate::browser::cdp::CdpClient>) -> Self {
Self { client }
}
pub async fn set_basic_auth(&self, creds: &AuthCredentials) -> Result<()> {
let combo = format!("{}:{}", creds.username, creds.password);
let encoded = general_purpose::STANDARD.encode(combo.as_bytes());
let header_value = format!("Basic {encoded}");
self.client
.send_command(
"Network.setExtraHTTPHeaders",
serde_json::json!({
"headers": {
"Authorization": header_value,
}
}),
)
.await?;
Ok(())
}
pub async fn set_proxy_auth(&self, creds: &AuthCredentials) -> Result<()> {
let combo = format!("{}:{}", creds.username, creds.password);
let encoded = general_purpose::STANDARD.encode(combo.as_bytes());
let header_value = format!("Basic {encoded}");
self.client
.send_command(
"Network.setExtraHTTPHeaders",
serde_json::json!({
"headers": {
"Proxy-Authorization": header_value,
}
}),
)
.await?;
Ok(())
}
pub async fn set_extra_headers(&self, headers: std::collections::HashMap<String, String>) -> Result<()> {
self.client
.send_command(
"Network.setExtraHTTPHeaders",
serde_json::json!({ "headers": headers }),
)
.await?;
Ok(())
}
pub async fn clear_auth(&self) -> Result<()> {
self.client
.send_command(
"Network.setExtraHTTPHeaders",
serde_json::json!({ "headers": {} }),
)
.await?;
Ok(())
}
pub async fn authenticate(&self, username: &str, password: &str) -> Result<()> {
let creds = AuthCredentials {
username: username.to_string(),
password: password.to_string(),
realm: None,
};
self.set_basic_auth(&creds).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_auth_credentials_creation() {
let creds = AuthCredentials {
username: "user".to_string(),
password: "pass".to_string(),
realm: Some("test-realm".to_string()),
};
assert_eq!(creds.username, "user");
assert_eq!(creds.password, "pass");
assert_eq!(creds.realm, Some("test-realm".to_string()));
}
#[test]
fn test_auth_credentials_serialization() {
let creds = AuthCredentials {
username: "admin".to_string(),
password: "secret".to_string(),
realm: None,
};
let json = serde_json::to_string(&creds).unwrap();
assert!(json.contains("admin"));
assert!(json.contains("secret"));
}
#[test]
fn test_basic_auth_encoding() {
let combo = "user:pass";
let encoded = general_purpose::STANDARD.encode(combo.as_bytes());
assert_eq!(encoded, "dXNlcjpwYXNz");
}
}