summaryrefslogtreecommitdiff
path: root/src/auth.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/auth.rs')
-rw-r--r--src/auth.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/auth.rs b/src/auth.rs
new file mode 100644
index 0000000..92a9ba3
--- /dev/null
+++ b/src/auth.rs
@@ -0,0 +1,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(()))
+}