rustypaste/src/auth.rs

56 lines
1.9 KiB
Rust

use actix_web::http::header::{HeaderMap, AUTHORIZATION};
use actix_web::{error, Error};
/// Checks the authorization header for the specified token.
///
/// `Authorization: (type) <token>`
pub fn check(host: &str, headers: &HeaderMap, tokens: Option<Vec<String>>) -> Result<(), Error> {
if let Some(tokens) = tokens {
let auth_header = headers
.get(AUTHORIZATION)
.map(|v| v.to_str().unwrap_or_default())
.map(|v| v.split_whitespace().last().unwrap_or_default());
if !tokens.iter().any(|v| v == auth_header.unwrap_or_default()) {
#[cfg(debug_assertions)]
warn!(
"authorization failure for {host} (token: {})",
auth_header.unwrap_or("none"),
);
#[cfg(not(debug_assertions))]
warn!("authorization failure for {host}");
return Err(error::ErrorUnauthorized("unauthorized\n"));
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use actix_web::http::header::HeaderValue;
#[test]
fn test_check_auth() -> Result<(), Error> {
let mut headers = HeaderMap::new();
headers.insert(AUTHORIZATION, HeaderValue::from_static("basic test_token"));
assert!(check("", &headers, Some(vec!["test_token".to_string()])).is_ok());
assert!(check("", &headers, Some(vec!["invalid_token".to_string()])).is_err());
assert!(check(
"",
&headers,
Some(vec!["invalid1".to_string(), "test_token".to_string()])
)
.is_ok());
assert!(check(
"",
&headers,
Some(vec!["invalid1".to_string(), "invalid2".to_string()])
)
.is_err());
assert!(check("", &headers, None).is_ok());
assert!(check("", &HeaderMap::new(), None).is_ok());
assert!(check("", &HeaderMap::new(), Some(vec!["token".to_string()])).is_err());
Ok(())
}
}