1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
use crate::{config::HttpBasicAuthConfig, error::ServiceError, FilterRequest, FilterResponseOut};
use base64::Engine;
use http_body_util::{combinators::BoxBody, BodyExt};
use hyper::{
header::{HeaderValue, AUTHORIZATION, WWW_AUTHENTICATE},
Response, StatusCode,
};
use log::debug;
use std::ops::ControlFlow;
pub fn http_basic(
config: &HttpBasicAuthConfig,
req: &FilterRequest,
resp: &mut FilterResponseOut,
) -> Result<ControlFlow<()>, ServiceError> {
if let Some(auth) = req.headers().get(AUTHORIZATION) {
let k = auth
.as_bytes()
.strip_prefix(b"Basic ")
.ok_or(ServiceError::BadAuth)?;
let k = base64::engine::general_purpose::STANDARD.decode(k)?;
let k = String::from_utf8(k)?;
if config.valid.contains(&k) {
debug!("valid auth");
return Ok(ControlFlow::Continue(()));
} else {
debug!("invalid auth");
}
}
debug!("unauthorized; sending auth challenge");
let mut r = Response::new(BoxBody::<_, ServiceError>::new(
String::new().map_err(|_| unreachable!()),
));
*r.status_mut() = StatusCode::UNAUTHORIZED;
r.headers_mut().insert(
WWW_AUTHENTICATE,
HeaderValue::from_str(&format!("Basic realm=\"{}\"", config.realm)).unwrap(),
);
*resp = Some(r);
Ok(ControlFlow::Break(()))
}
|