Compare commits
1 commit
8d1e26c305
...
cee9c9ff9e
Author | SHA1 | Date | |
---|---|---|---|
cee9c9ff9e |
2 changed files with 103 additions and 111 deletions
|
@ -62,123 +62,112 @@ impl CaptchaFinder for CaptchaFormFinder {
|
|||
async fn find_token(&self, req: &mut Request) -> Option<Option<String>> {
|
||||
req.form_data()
|
||||
.await
|
||||
.map(|form| form.fields.get(&self.token_name).cloned())
|
||||
.ok()
|
||||
.and_then(|form| form.fields.get(&self.token_name).cloned().map(Some))
|
||||
}
|
||||
|
||||
async fn find_answer(&self, req: &mut Request) -> Option<Option<String>> {
|
||||
req.form_data()
|
||||
.await
|
||||
.map(|form| form.fields.get(&self.answer_name).cloned())
|
||||
.ok()
|
||||
.and_then(|form| form.fields.get(&self.answer_name).cloned().map(Some))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use salvo_core::http::{header, HeaderValue, ReqBody};
|
||||
use salvo_core::http::{header, headers::ContentType, HeaderValue, ReqBody};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[rstest::rstest]
|
||||
#[case::not_found(
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
"application/x-www-form-urlencoded",
|
||||
None,
|
||||
None
|
||||
)]
|
||||
#[case::not_found(None, None, None, None, "text/plain", None, None)]
|
||||
#[case::normal(
|
||||
None,
|
||||
None,
|
||||
Some(("captcha_token", "token")),
|
||||
Some(("captcha_answer", "answer")),
|
||||
"application/x-www-form-urlencoded",
|
||||
Some(Some("token")),
|
||||
Some(Some("answer"))
|
||||
)]
|
||||
#[case::custom_keys(
|
||||
Some("custom_token"),
|
||||
Some("custom_answer"),
|
||||
Some(("custom_token", "token")),
|
||||
Some(("custom_answer", "answer")),
|
||||
"application/x-www-form-urlencoded",
|
||||
Some(Some("token")),
|
||||
Some(Some("answer"))
|
||||
)]
|
||||
#[case::custom_not_found(
|
||||
Some("custom_token"),
|
||||
Some("custom_answer"),
|
||||
None,
|
||||
None,
|
||||
"application/x-www-form-urlencoded",
|
||||
None,
|
||||
None
|
||||
)]
|
||||
#[case::custom_not_found_with_body(
|
||||
Some("custom_token"),
|
||||
Some("custom_answer"),
|
||||
Some(("captcha_token", "token")),
|
||||
Some(("captcha_answer", "answer")),
|
||||
"application/x-www-form-urlencoded",
|
||||
None,
|
||||
None
|
||||
)]
|
||||
#[case::invalid_type(
|
||||
None,
|
||||
None,
|
||||
Some(("captcha_token", "token")),
|
||||
Some(("captcha_answer", "answer")),
|
||||
"application/json",
|
||||
None,
|
||||
None
|
||||
)]
|
||||
async fn test_form_finder(
|
||||
#[case] custom_token_key: Option<&'static str>,
|
||||
#[case] custom_answer_key: Option<&'static str>,
|
||||
#[case] token_key_val: Option<(&'static str, &'static str)>,
|
||||
#[case] answer_key_val: Option<(&'static str, &'static str)>,
|
||||
#[case] content_type: &'static str,
|
||||
#[case] excepted_token: Option<Option<&'static str>>,
|
||||
#[case] excepted_answer: Option<Option<&'static str>>,
|
||||
) {
|
||||
async fn test_captcha_form_finder() {
|
||||
let finder = CaptchaFormFinder::new();
|
||||
let mut req = Request::default();
|
||||
let mut finder = CaptchaFormFinder::new();
|
||||
if let Some(token_key) = custom_token_key {
|
||||
finder = finder.token_name(token_key.to_string())
|
||||
}
|
||||
if let Some(answer_key) = custom_answer_key {
|
||||
finder = finder.answer_name(answer_key.to_string())
|
||||
}
|
||||
|
||||
let body = token_key_val
|
||||
.zip(answer_key_val)
|
||||
.map(|((t_k, t_v), (a_k, a_v))| format!("{t_k}={t_v}&{a_k}={a_v}"))
|
||||
.unwrap_or_else(|| {
|
||||
token_key_val
|
||||
.or(answer_key_val)
|
||||
.map(|(k, v)| format!("{k}={v}"))
|
||||
.unwrap_or_default()
|
||||
});
|
||||
|
||||
*req.body_mut() = ReqBody::Once(body.into());
|
||||
*req.body_mut() = ReqBody::Once("captcha_token=token&captcha_answer=answer".into());
|
||||
let headers = req.headers_mut();
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(content_type).unwrap(),
|
||||
HeaderValue::from_str(&ContentType::form_url_encoded().to_string()).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
finder.find_token(&mut req).await,
|
||||
excepted_token.map(|o| o.map(ToOwned::to_owned))
|
||||
Some(Some("token".to_owned()))
|
||||
);
|
||||
assert_eq!(
|
||||
finder.find_answer(&mut req).await,
|
||||
excepted_answer.map(|o| o.map(ToOwned::to_owned))
|
||||
Some(Some("answer".to_owned()))
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_captcha_form_finder_customized() {
|
||||
let finder = CaptchaFormFinder::new()
|
||||
.token_name("token".to_string())
|
||||
.answer_name("answer".to_string());
|
||||
let mut req = Request::default();
|
||||
*req.body_mut() = ReqBody::Once("token=token&answer=answer".into());
|
||||
let headers = req.headers_mut();
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(&ContentType::form_url_encoded().to_string()).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
finder.find_token(&mut req).await,
|
||||
Some(Some("token".to_owned()))
|
||||
);
|
||||
assert_eq!(
|
||||
finder.find_answer(&mut req).await,
|
||||
Some(Some("answer".to_owned()))
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_captcha_form_finder_none() {
|
||||
let finder = CaptchaFormFinder::new();
|
||||
let mut req = Request::default();
|
||||
*req.body_mut() = ReqBody::Once("".into());
|
||||
let headers = req.headers_mut();
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(&ContentType::form_url_encoded().to_string()).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(finder.find_token(&mut req).await, Some(None));
|
||||
assert_eq!(finder.find_answer(&mut req).await, Some(None));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_captcha_form_finder_customized_none() {
|
||||
let finder = CaptchaFormFinder::new()
|
||||
.token_name("token".to_string())
|
||||
.answer_name("answer".to_string());
|
||||
let mut req = Request::default();
|
||||
*req.body_mut() = ReqBody::Once("".into());
|
||||
let headers = req.headers_mut();
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(&ContentType::form_url_encoded().to_string()).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(finder.find_token(&mut req).await, Some(None));
|
||||
assert_eq!(finder.find_answer(&mut req).await, Some(None));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_captcha_form_finder_invalid() {
|
||||
let finder = CaptchaFormFinder::new();
|
||||
let mut req = Request::default();
|
||||
*req.body_mut() = ReqBody::Once("captcha_token=token&captcha_answer=answer".into());
|
||||
let headers = req.headers_mut();
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_str(&ContentType::json().to_string()).unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(finder.find_token(&mut req).await, None);
|
||||
assert_eq!(finder.find_answer(&mut req).await, None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,30 +81,33 @@ mod tests {
|
|||
#[rstest::rstest]
|
||||
#[case::not_found(None, None, None, None, None, None)]
|
||||
#[case::normal(
|
||||
None,
|
||||
None,
|
||||
Some(("x-captcha-token", "token")),
|
||||
Some(("x-captcha-answer", "answer")),
|
||||
Some(Some("token")),
|
||||
Some(Some("answer"))
|
||||
)]
|
||||
None,
|
||||
None,
|
||||
Some(("x-captcha-token", "token")),
|
||||
Some(("x-captcha-answer", "answer")),
|
||||
Some(Some("token")),
|
||||
Some(Some("answer"))
|
||||
)
|
||||
]
|
||||
#[case::custom_headers(
|
||||
Some("custom-token"),
|
||||
Some("custom-answer"),
|
||||
Some(("custom-token", "token")),
|
||||
Some(("custom-answer", "answer")),
|
||||
Some(Some("token")),
|
||||
Some(Some("answer"))
|
||||
)]
|
||||
Some("custom-token"),
|
||||
Some("custom-answer"),
|
||||
Some(("custom-token", "token")),
|
||||
Some(("custom-answer", "answer")),
|
||||
Some(Some("token")),
|
||||
Some(Some("answer"))
|
||||
)
|
||||
]
|
||||
#[case::custom_not_found(Some("custom-token"), Some("custom-answer"), None, None, None, None)]
|
||||
#[case::custom_not_found_with_headers(
|
||||
Some("custom-token"),
|
||||
Some("custom-answer"),
|
||||
Some(("x-captcha-token", "token")),
|
||||
Some(("x-captcha-answer", "answer")),
|
||||
None,
|
||||
None
|
||||
)]
|
||||
Some("custom-token"),
|
||||
Some("custom-answer"),
|
||||
Some(("x-captcha-token", "token")),
|
||||
Some(("x-captcha-answer", "answer")),
|
||||
None,
|
||||
None
|
||||
)
|
||||
]
|
||||
async fn test_header_finder(
|
||||
#[case] custom_token_header: Option<&'static str>,
|
||||
#[case] custom_answer_header: Option<&'static str>,
|
||||
|
|
Loading…
Reference in a new issue