Compare commits

..

3 Commits

Author SHA1 Message Date
sigoden
7dc0b0e218 chore: release v0.34.2 2023-06-05 11:51:56 +08:00
sigoden
6be36b8e51 fix: webdav only see public folder even logging in (#231) 2023-06-05 11:40:31 +08:00
sigoden
8be545d3da fix: ui refresh page after login (#230) 2023-06-03 10:09:02 +08:00
7 changed files with 40 additions and 18 deletions

View File

@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [0.34.2] - 2023-06-05
### Bug Fixes
- Ui refresh page after login ([#230](https://github.com/sigoden/dufs/issues/230))
- Webdav only see public folder even logging in ([#231](https://github.com/sigoden/dufs/issues/231))
## [0.34.1] - 2023-06-02 ## [0.34.1] - 2023-06-02
### Bug Fixes ### Bug Fixes

2
Cargo.lock generated
View File

@@ -436,7 +436,7 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]] [[package]]
name = "dufs" name = "dufs"
version = "0.34.1" version = "0.34.2"
dependencies = [ dependencies = [
"alphanumeric-sort", "alphanumeric-sort",
"anyhow", "anyhow",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "dufs" name = "dufs"
version = "0.34.1" version = "0.34.2"
edition = "2021" edition = "2021"
authors = ["sigoden <sigoden@gmail.com>"] authors = ["sigoden <sigoden@gmail.com>"]
description = "Dufs is a distinctive utility file server" description = "Dufs is a distinctive utility file server"

View File

@@ -445,6 +445,7 @@ function setupAuth() {
$loginBtn.addEventListener("click", async () => { $loginBtn.addEventListener("click", async () => {
try { try {
await checkAuth() await checkAuth()
location.reload();
} catch (err) { } catch (err) {
alert(err.message); alert(err.message);
} }

View File

@@ -80,8 +80,8 @@ impl AccessControl {
Ok(Self { users, anony }) Ok(Self { users, anony })
} }
pub fn valid(&self) -> bool { pub fn exist(&self) -> bool {
!self.users.is_empty() || self.anony.is_some() !self.users.is_empty()
} }
pub fn guard( pub fn guard(
@@ -257,18 +257,14 @@ pub enum AuthMethod {
} }
impl AuthMethod { impl AuthMethod {
pub fn www_auth(&self, stale: bool) -> Result<String> { pub fn www_auth(&self) -> Result<String> {
match self { match self {
AuthMethod::Basic => Ok(format!("Basic realm=\"{REALM}\"")), AuthMethod::Basic => Ok(format!("Basic realm=\"{REALM}\"")),
AuthMethod::Digest => { AuthMethod::Digest => Ok(format!(
let str_stale = if stale { "stale=true," } else { "" }; "Digest realm=\"{}\",nonce=\"{}\",qop=\"auth\"",
Ok(format!(
"Digest realm=\"{}\",nonce=\"{}\",{}qop=\"auth\"",
REALM, REALM,
create_nonce()?, create_nonce()?,
str_stale )),
))
}
} }
} }

View File

@@ -1,6 +1,6 @@
#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_arguments)]
use crate::auth::AccessPaths; use crate::auth::{AccessPaths, AccessPerm};
use crate::streamer::Streamer; use crate::streamer::Streamer;
use crate::utils::{ use crate::utils::{
decode_uri, encode_uri, get_file_mtime_and_mode, get_file_name, glob, try_get_file_name, decode_uri, encode_uri, get_file_mtime_and_mode, get_file_name, glob, try_get_file_name,
@@ -340,6 +340,12 @@ impl Server {
method => match method.as_str() { method => match method.as_str() {
"PROPFIND" => { "PROPFIND" => {
if is_dir { if is_dir {
let access_paths = if access_paths.perm().indexonly() {
// see https://github.com/sigoden/dufs/issues/229
AccessPaths::new(AccessPerm::ReadOnly)
} else {
access_paths
};
self.handle_propfind_dir(path, headers, access_paths, &mut res) self.handle_propfind_dir(path, headers, access_paths, &mut res)
.await?; .await?;
} else if is_file { } else if is_file {
@@ -759,7 +765,7 @@ impl Server {
uri_prefix: self.args.uri_prefix.clone(), uri_prefix: self.args.uri_prefix.clone(),
allow_upload: self.args.allow_upload, allow_upload: self.args.allow_upload,
allow_delete: self.args.allow_delete, allow_delete: self.args.allow_delete,
auth: self.args.auth.valid(), auth: self.args.auth.exist(),
user, user,
editable, editable,
}; };
@@ -974,7 +980,7 @@ impl Server {
allow_search: self.args.allow_search, allow_search: self.args.allow_search,
allow_archive: self.args.allow_archive, allow_archive: self.args.allow_archive,
dir_exists: exist, dir_exists: exist,
auth: self.args.auth.valid(), auth: self.args.auth.exist(),
user, user,
paths, paths,
}; };
@@ -999,7 +1005,7 @@ impl Server {
} }
fn auth_reject(&self, res: &mut Response) -> Result<()> { fn auth_reject(&self, res: &mut Response) -> Result<()> {
let value = self.args.auth_method.www_auth(false)?; let value = self.args.auth_method.www_auth()?;
set_webdav_headers(res); set_webdav_headers(res);
res.headers_mut().insert(WWW_AUTHENTICATE, value.parse()?); res.headers_mut().insert(WWW_AUTHENTICATE, value.parse()?);
// set 401 to make the browser pop up the login box // set 401 to make the browser pop up the login box

View File

@@ -201,3 +201,15 @@ fn auth_partial_index(
); );
Ok(()) Ok(())
} }
#[rstest]
fn no_auth_propfind_dir(
#[with(&["--auth", "user:pass@/:rw", "--auth", "@/dir-assets", "-A"])] server: TestServer,
) -> Result<(), Error> {
let resp = fetch!(b"PROPFIND", server.url()).send()?;
assert_eq!(resp.status(), 207);
let body = resp.text()?;
assert!(body.contains("<D:href>/dir-assets/</D:href>"));
assert!(body.contains("<D:href>/dir1/</D:href>"));
Ok(())
}