refactor: change the format of www-authenticate (#312)
This commit is contained in:
parent
5c850256f4
commit
37800f630d
3 changed files with 28 additions and 17 deletions
28
src/auth.rs
28
src/auth.rs
|
@ -1,7 +1,9 @@
|
||||||
|
use crate::{args::Args, server::Response, utils::unix_now};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use headers::HeaderValue;
|
use headers::HeaderValue;
|
||||||
use hyper::Method;
|
use hyper::{header::WWW_AUTHENTICATE, Method};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use md5::Context;
|
use md5::Context;
|
||||||
|
@ -11,8 +13,6 @@ use std::{
|
||||||
};
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{args::Args, utils::unix_now};
|
|
||||||
|
|
||||||
const REALM: &str = "DUFS";
|
const REALM: &str = "DUFS";
|
||||||
const DIGEST_AUTH_TIMEOUT: u32 = 604800; // 7 days
|
const DIGEST_AUTH_TIMEOUT: u32 = 604800; // 7 days
|
||||||
|
|
||||||
|
@ -258,17 +258,21 @@ impl AccessPerm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn www_authenticate(args: &Args) -> Result<HeaderValue> {
|
pub fn www_authenticate(res: &mut Response, args: &Args) -> Result<()> {
|
||||||
let value = if args.auth.use_hashed_password {
|
if args.auth.use_hashed_password {
|
||||||
format!("Basic realm=\"{}\"", REALM)
|
let basic = HeaderValue::from_str(&format!("Basic realm=\"{}\"", REALM))?;
|
||||||
|
res.headers_mut().insert(WWW_AUTHENTICATE, basic);
|
||||||
} else {
|
} else {
|
||||||
let nonce = create_nonce()?;
|
let nonce = create_nonce()?;
|
||||||
format!(
|
let digest = HeaderValue::from_str(&format!(
|
||||||
"Digest realm=\"{}\", nonce=\"{}\", qop=\"auth\", Basic realm=\"{}\"",
|
"Digest realm=\"{}\", nonce=\"{}\", qop=\"auth\"",
|
||||||
REALM, nonce, REALM
|
REALM, nonce
|
||||||
)
|
))?;
|
||||||
};
|
let basic = HeaderValue::from_str(&format!("Basic realm=\"{}\"", REALM))?;
|
||||||
Ok(HeaderValue::from_str(&value)?)
|
res.headers_mut().append(WWW_AUTHENTICATE, digest);
|
||||||
|
res.headers_mut().append(WWW_AUTHENTICATE, basic);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_auth_user(authorization: &HeaderValue) -> Option<String> {
|
pub fn get_auth_user(authorization: &HeaderValue) -> Option<String> {
|
||||||
|
|
|
@ -21,7 +21,7 @@ use headers::{
|
||||||
};
|
};
|
||||||
use hyper::header::{
|
use hyper::header::{
|
||||||
HeaderValue, AUTHORIZATION, CONTENT_DISPOSITION, CONTENT_LENGTH, CONTENT_RANGE, CONTENT_TYPE,
|
HeaderValue, AUTHORIZATION, CONTENT_DISPOSITION, CONTENT_LENGTH, CONTENT_RANGE, CONTENT_TYPE,
|
||||||
RANGE, WWW_AUTHENTICATE,
|
RANGE,
|
||||||
};
|
};
|
||||||
use hyper::{Body, Method, StatusCode, Uri};
|
use hyper::{Body, Method, StatusCode, Uri};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -1056,9 +1056,8 @@ impl Server {
|
||||||
|
|
||||||
fn auth_reject(&self, res: &mut Response) -> Result<()> {
|
fn auth_reject(&self, res: &mut Response) -> Result<()> {
|
||||||
set_webdav_headers(res);
|
set_webdav_headers(res);
|
||||||
res.headers_mut()
|
|
||||||
.append(WWW_AUTHENTICATE, www_authenticate(&self.args)?);
|
www_authenticate(res, &self.args)?;
|
||||||
// set 401 to make the browser pop up the login box
|
|
||||||
*res.status_mut() = StatusCode::UNAUTHORIZED;
|
*res.status_mut() = StatusCode::UNAUTHORIZED;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,15 @@ use rstest::rstest;
|
||||||
fn no_auth(#[with(&["--auth", "user:pass@/:rw", "-A"])] server: TestServer) -> Result<(), Error> {
|
fn no_auth(#[with(&["--auth", "user:pass@/:rw", "-A"])] server: TestServer) -> Result<(), Error> {
|
||||||
let resp = reqwest::blocking::get(server.url())?;
|
let resp = reqwest::blocking::get(server.url())?;
|
||||||
assert_eq!(resp.status(), 401);
|
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 url = format!("{}file1", server.url());
|
||||||
let resp = fetch!(b"PUT", &url).body(b"abc".to_vec()).send()?;
|
let resp = fetch!(b"PUT", &url).body(b"abc".to_vec()).send()?;
|
||||||
assert_eq!(resp.status(), 401);
|
assert_eq!(resp.status(), 401);
|
||||||
|
|
Loading…
Reference in a new issue