]> OzVa Git service - ozva-cloud/commitdiff
refactor: change the format of www-authenticate (#312)
authorsigoden <sigoden@gmail.com>
Thu, 7 Dec 2023 07:04:14 +0000 (15:04 +0800)
committerGitHub <noreply@github.com>
Thu, 7 Dec 2023 07:04:14 +0000 (15:04 +0800)
src/auth.rs
src/server.rs
tests/auth.rs

index 678079c1dfd3a5815b6a2ca07a0778bbe756c39b..6f87e0b2988f2190b9b4f830a650eebe9850245e 100644 (file)
@@ -1,7 +1,9 @@
+use crate::{args::Args, server::Response, utils::unix_now};
+
 use anyhow::{anyhow, bail, Result};
 use base64::{engine::general_purpose, Engine as _};
 use headers::HeaderValue;
-use hyper::Method;
+use hyper::{header::WWW_AUTHENTICATE, Method};
 use indexmap::IndexMap;
 use lazy_static::lazy_static;
 use md5::Context;
@@ -11,8 +13,6 @@ use std::{
 };
 use uuid::Uuid;
 
-use crate::{args::Args, utils::unix_now};
-
 const REALM: &str = "DUFS";
 const DIGEST_AUTH_TIMEOUT: u32 = 604800; // 7 days
 
@@ -258,17 +258,21 @@ impl AccessPerm {
     }
 }
 
-pub fn www_authenticate(args: &Args) -> Result<HeaderValue> {
-    let value = if args.auth.use_hashed_password {
-        format!("Basic realm=\"{}\"", REALM)
+pub fn www_authenticate(res: &mut Response, args: &Args) -> Result<()> {
+    if args.auth.use_hashed_password {
+        let basic = HeaderValue::from_str(&format!("Basic realm=\"{}\"", REALM))?;
+        res.headers_mut().insert(WWW_AUTHENTICATE, basic);
     } else {
         let nonce = create_nonce()?;
-        format!(
-            "Digest realm=\"{}\", nonce=\"{}\", qop=\"auth\", Basic realm=\"{}\"",
-            REALM, nonce, REALM
-        )
-    };
-    Ok(HeaderValue::from_str(&value)?)
+        let digest = HeaderValue::from_str(&format!(
+            "Digest realm=\"{}\", nonce=\"{}\", qop=\"auth\"",
+            REALM, nonce
+        ))?;
+        let basic = HeaderValue::from_str(&format!("Basic realm=\"{}\"", REALM))?;
+        res.headers_mut().append(WWW_AUTHENTICATE, digest);
+        res.headers_mut().append(WWW_AUTHENTICATE, basic);
+    }
+    Ok(())
 }
 
 pub fn get_auth_user(authorization: &HeaderValue) -> Option<String> {
index 41b7e2e726d6372a05af71f33de77193968774c6..8d9a5e374c5582b1de974fcde25e1e94319d746a 100644 (file)
@@ -21,7 +21,7 @@ use headers::{
 };
 use hyper::header::{
     HeaderValue, AUTHORIZATION, CONTENT_DISPOSITION, CONTENT_LENGTH, CONTENT_RANGE, CONTENT_TYPE,
-    RANGE, WWW_AUTHENTICATE,
+    RANGE,
 };
 use hyper::{Body, Method, StatusCode, Uri};
 use serde::Serialize;
@@ -1056,9 +1056,8 @@ impl Server {
 
     fn auth_reject(&self, res: &mut Response) -> Result<()> {
         set_webdav_headers(res);
-        res.headers_mut()
-            .append(WWW_AUTHENTICATE, www_authenticate(&self.args)?);
-        // set 401 to make the browser pop up the login box
+
+        www_authenticate(res, &self.args)?;
         *res.status_mut() = StatusCode::UNAUTHORIZED;
         Ok(())
     }
index fbf6347bf4798df5b5ae5dc62534a5c0f28e54a0..81e4d2a56243aa0bc207ba44e9df3a2e9e06ec89 100644 (file)
@@ -10,7 +10,15 @@ use rstest::rstest;
 fn no_auth(#[with(&["--auth", "user:pass@/:rw", "-A"])] server: TestServer) -> Result<(), Error> {
     let resp = reqwest::blocking::get(server.url())?;
     assert_eq!(resp.status(), 401);
-    assert!(resp.headers().contains_key("www-authenticate"));
+    let values: Vec<&str> = resp
+        .headers()
+        .get_all("www-authenticate")
+        .iter()
+        .map(|v| v.to_str().unwrap())
+        .collect();
+    assert!(values[0].starts_with("Digest"));
+    assert!(values[1].starts_with("Basic"));
+
     let url = format!("{}file1", server.url());
     let resp = fetch!(b"PUT", &url).body(b"abc".to_vec()).send()?;
     assert_eq!(resp.status(), 401);