use crate::vcr_form_data::{encode_form_data, parse_form_data};
use http_client_vcr::{Filter, FilterChain, SerializableRequest, SerializableResponse};
#[derive(Debug)]
pub struct LastFmPasswordOnlyFilter;
impl Filter for LastFmPasswordOnlyFilter {
fn filter_request(&self, request: &mut SerializableRequest) {
if let Some(body) = &mut request.body {
if body.contains('=') && (body.contains('&') || !body.contains(' ')) {
let mut params = parse_form_data(body);
if params.contains_key("password") {
params.insert("password".to_string(), "test_password".to_string());
*body = encode_form_data(¶ms);
}
}
}
if let Some(cookie_values) = request.headers.get_mut("cookie") {
for cookie_header in cookie_values.iter_mut() {
*cookie_header = self.filter_session_cookies(cookie_header);
}
}
}
fn filter_response(&self, response: &mut SerializableResponse) {
if let Some(set_cookie_values) = response.headers.get_mut("set-cookie") {
for set_cookie_header in set_cookie_values.iter_mut() {
if set_cookie_header.contains("sessionid=") {
*set_cookie_header = self.filter_set_cookie_session(set_cookie_header);
}
}
}
}
}
impl LastFmPasswordOnlyFilter {
fn filter_session_cookies(&self, cookie_header: &str) -> String {
let mut filtered_cookies = Vec::new();
for cookie in cookie_header.split(';') {
let cookie = cookie.trim();
if cookie.starts_with("sessionid=") {
filtered_cookies.push("sessionid=test_session_id");
} else {
filtered_cookies.push(cookie);
}
}
filtered_cookies.join("; ")
}
fn filter_set_cookie_session(&self, set_cookie_header: &str) -> String {
if set_cookie_header.starts_with("sessionid=") {
if let Some(semicolon_pos) = set_cookie_header.find(';') {
let attributes = &set_cookie_header[semicolon_pos..];
format!("sessionid=test_session_id{attributes}")
} else {
"sessionid=test_session_id".to_string()
}
} else {
set_cookie_header.to_string()
}
}
}
pub const TEST_API_KEY: &str = "TEST_API_KEY";
#[derive(Debug)]
pub struct LastFmApiKeyFilter;
impl Filter for LastFmApiKeyFilter {
fn filter_request(&self, request: &mut SerializableRequest) {
if let Some(real_key) = std::env::var("LASTFM_EDIT_API_KEY")
.ok()
.filter(|k| !k.is_empty())
{
request.url = request.url.replace(&real_key, TEST_API_KEY);
}
}
fn filter_response(&self, _response: &mut SerializableResponse) {}
}
pub fn create_lastfm_test_filter_chain() -> Result<FilterChain, regex::Error> {
let filter_chain = FilterChain::new()
.add_filter(Box::new(LastFmPasswordOnlyFilter))
.add_filter(Box::new(LastFmApiKeyFilter));
Ok(filter_chain)
}