aboutsummaryrefslogtreecommitdiffstats
path: root/src/auth.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/auth.rs86
1 files changed, 18 insertions, 68 deletions
diff --git a/src/auth.rs b/src/auth.rs
index 7c77758..0d97f11 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -1,12 +1,10 @@
use actix_web::dev::{Service, ServiceRequest, ServiceResponse};
-use actix_web::http::{header, StatusCode};
-use actix_web::{HttpRequest, HttpResponse};
+use actix_web::{HttpRequest, ResponseError};
use futures::future::Either;
use sha2::{Digest, Sha256, Sha512};
use std::future::{ready, Future};
-use crate::errors::{self, ContextualError};
-use crate::renderer;
+use crate::errors::ContextualError;
#[derive(Clone, Debug)]
/// HTTP Basic authentication parameters
@@ -77,86 +75,38 @@ pub fn get_hash<T: Digest>(text: &str) -> Vec<u8> {
hasher.finalize().to_vec()
}
-/// When authentication succedes, return the request to be passed to downstream services.
-/// Otherwise, return an error response
-fn handle_auth(req: ServiceRequest) -> Result<ServiceRequest, ServiceResponse> {
- let (req, pl) = req.into_parts();
+fn handle_auth(req: &HttpRequest) -> Result<(), ContextualError> {
let required_auth = &req.app_data::<crate::MiniserveConfig>().unwrap().auth;
if required_auth.is_empty() {
// auth is disabled by configuration
- return Ok(ServiceRequest::from_parts(req, pl));
- } else if let Ok(cred) = BasicAuthParams::try_from_request(&req) {
- if match_auth(cred, required_auth) {
- return Ok(ServiceRequest::from_parts(req, pl));
- }
+ return Ok(());
}
- // auth failed; render and return the error response
- let resp = HttpResponse::Unauthorized()
- .append_header((
- header::WWW_AUTHENTICATE,
- header::HeaderValue::from_static("Basic realm=\"miniserve\""),
- ))
- .body(build_unauthorized_response(
- &req,
- ContextualError::InvalidHttpCredentials,
- true,
- StatusCode::UNAUTHORIZED,
- ));
-
- Err(ServiceResponse::new(req, resp))
+ match BasicAuthParams::try_from_request(req) {
+ Ok(cred) => match match_auth(cred, required_auth) {
+ true => Ok(()),
+ false => Err(ContextualError::InvalidHttpCredentials),
+ },
+ Err(_) => Err(ContextualError::RequireHttpCredentials),
+ }
}
pub fn auth_middleware<S>(
- req: ServiceRequest,
+ mut req: ServiceRequest,
srv: &S,
) -> impl Future<Output = actix_web::Result<ServiceResponse>> + 'static
where
S: Service<ServiceRequest, Response = ServiceResponse, Error = actix_web::Error>,
S::Future: 'static,
{
- match handle_auth(req) {
- Ok(req) => Either::Left(srv.call(req)),
- Err(resp) => Either::Right(ready(Ok(resp))),
- }
-}
-
-/// Builds the unauthorized response body
-/// The reason why log_error_chain is optional is to handle cases where the auth pop-up appears and when the user clicks Cancel.
-/// In those case, we do not log the error to the terminal since it does not really matter.
-fn build_unauthorized_response(
- req: &HttpRequest,
- error: ContextualError,
- log_error_chain: bool,
- error_code: StatusCode,
-) -> String {
- let state = req.app_data::<crate::MiniserveConfig>().unwrap();
- let error = ContextualError::HttpAuthenticationError(Box::new(error));
-
- if log_error_chain {
- errors::log_error_chain(error.to_string());
+ match handle_auth(req.parts_mut().0) {
+ Ok(_) => Either::Left(srv.call(req)),
+ Err(err) => {
+ let resp = req.into_response(err.error_response());
+ Either::Right(ready(Ok(resp)))
+ }
}
- let return_path = match state.random_route {
- Some(ref random_route) => format!("/{}", random_route),
- None => "/".to_string(),
- };
-
- renderer::render_error(
- &error.to_string(),
- error_code,
- &return_path,
- None,
- None,
- false,
- false,
- &state.favicon_route,
- &state.css_route,
- &state.default_color_scheme,
- &state.default_color_scheme_dark,
- state.hide_version_footer,
- )
- .into_string()
}
#[rustfmt::skip]