From 1b14475d05f88dd5652d327132b8105658741b1a Mon Sep 17 00:00:00 2001 From: su77ungr <69374354+su77ungr@users.noreply.github.com> Date: Mon, 13 Apr 2026 02:12:17 +0200 Subject: [PATCH] add WWW-Authenticate handshake for spec-compliancy --- src/interfaces/middleware/auth.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/interfaces/middleware/auth.rs b/src/interfaces/middleware/auth.rs index 90f56f68..149eb8e7 100644 --- a/src/interfaces/middleware/auth.rs +++ b/src/interfaces/middleware/auth.rs @@ -238,6 +238,21 @@ pub async fn auth_middleware( } Err(e) => { tracing::warn!("App password verification failed: {}", e); + // For WebDAV: include WWW-Authenticate so the client + // knows to re-prompt rather than silently failing. + if request.uri().path().starts_with("/webdav") { + return Ok(Response::builder() + .status(StatusCode::UNAUTHORIZED) + .header( + header::WWW_AUTHENTICATE, + r#"Basic realm="OxiCloud""#, + ) + .header(header::CONTENT_TYPE, "text/plain; charset=utf-8") + .body(axum::body::Body::from( + "Invalid username or app password", + )) + .unwrap()); + } return Err(AuthError::InvalidToken( "Invalid username or app password".to_string(), )); @@ -291,12 +306,26 @@ pub async fn auth_middleware( } } - // No valid credentials found via any method + // No valid credentials found via any method. if state.auth_service.is_none() { tracing::error!("Auth middleware invoked but auth service is not configured"); return Err(AuthError::AuthServiceUnavailable); } + // For WebDAV requests with no credentials at all: return 401 with + // WWW-Authenticate so that spec-compliant clients (Nautilus, Cyberduck, + // Windows Explorer, macOS Finder) know to prompt for a username/password. + // Non-WebDAV routes return the standard AuthError which renders without + // this header — keeping browser sessions redirecting to /login as before. + if request.uri().path().starts_with("/webdav") { + return Ok(Response::builder() + .status(StatusCode::UNAUTHORIZED) + .header(header::WWW_AUTHENTICATE, r#"Basic realm="OxiCloud""#) + .header(header::CONTENT_TYPE, "text/plain; charset=utf-8") + .body(axum::body::Body::from("Authentication required")) + .unwrap()); + } + Err(AuthError::TokenNotProvided) }