} else if is_miss {
status_not_found(&mut res);
} else {
- self.handle_copy(path, headers, &mut res).await?
+ self.handle_copy(path, &req, &mut res).await?
}
}
"MOVE" => {
} else if is_miss {
status_not_found(&mut res);
} else {
- self.handle_move(path, headers, &mut res).await?
+ self.handle_move(path, &req, &mut res).await?
}
}
"LOCK" => {
Ok(())
}
- async fn handle_copy(
- &self,
- path: &Path,
- headers: &HeaderMap<HeaderValue>,
- res: &mut Response,
- ) -> BoxResult<()> {
- let dest = match self.extract_dest(headers) {
+ async fn handle_copy(&self, path: &Path, req: &Request, res: &mut Response) -> BoxResult<()> {
+ let dest = match self.extract_dest(req, res) {
Some(dest) => dest,
None => {
- *res.status_mut() = StatusCode::BAD_REQUEST;
return Ok(());
}
};
Ok(())
}
- async fn handle_move(
- &self,
- path: &Path,
- headers: &HeaderMap<HeaderValue>,
- res: &mut Response,
- ) -> BoxResult<()> {
- let dest = match self.extract_dest(headers) {
+ async fn handle_move(&self, path: &Path, req: &Request, res: &mut Response) -> BoxResult<()> {
+ let dest = match self.extract_dest(req, res) {
Some(dest) => dest,
None => {
- *res.status_mut() = StatusCode::BAD_REQUEST;
return Ok(());
}
};
.unwrap_or_default()
}
- fn extract_dest(&self, headers: &HeaderMap<HeaderValue>) -> Option<PathBuf> {
+ fn extract_dest(&self, req: &Request, res: &mut Response) -> Option<PathBuf> {
+ let headers = req.headers();
+ let dest_path = match self.extract_destination_header(headers) {
+ Some(dest) => dest,
+ None => {
+ *res.status_mut() = StatusCode::BAD_REQUEST;
+ return None;
+ }
+ };
+ let authorization = headers.get(AUTHORIZATION);
+ let guard_type = self.args.auth.guard(
+ &dest_path,
+ req.method(),
+ authorization,
+ self.args.auth_method.clone(),
+ );
+ if guard_type.is_reject() {
+ *res.status_mut() = StatusCode::FORBIDDEN;
+ *res.body_mut() = Body::from("Forbidden");
+ return None;
+ }
+
+ let dest = match self.extract_path(&dest_path) {
+ Some(dest) => dest,
+ None => {
+ *res.status_mut() = StatusCode::BAD_REQUEST;
+ return None;
+ }
+ };
+
+ Some(dest)
+ }
+
+ fn extract_destination_header(&self, headers: &HeaderMap<HeaderValue>) -> Option<String> {
let dest = headers.get("Destination")?.to_str().ok()?;
let uri: Uri = dest.parse().ok()?;
- self.extract_path(uri.path())
+ Some(uri.path().to_string())
}
fn extract_path(&self, path: &str) -> Option<PathBuf> {
assert_eq!(resp.status(), 201);
Ok(())
}
+
+#[rstest]
+fn auth_webdav_move(
+ #[with(&["--auth", "/@user:pass@*", "--auth", "/dira@user3:pass3", "-A"])] server: TestServer,
+) -> Result<(), Error> {
+ let origin_url = format!("{}dira/test.html", server.url());
+ let new_url = format!("{}test2.html", server.url());
+ let resp = fetch!(b"MOVE", &origin_url)
+ .header("Destination", &new_url)
+ .send_with_digest_auth("user3", "pass3")?;
+ assert_eq!(resp.status(), 403);
+ Ok(())
+}
+
+#[rstest]
+fn auth_webdav_copy(
+ #[with(&["--auth", "/@user:pass@*", "--auth", "/dira@user3:pass3", "-A"])] server: TestServer,
+) -> Result<(), Error> {
+ let origin_url = format!("{}dira/test.html", server.url());
+ let new_url = format!("{}test2.html", server.url());
+ let resp = fetch!(b"COPY", &origin_url)
+ .header("Destination", &new_url)
+ .send_with_digest_auth("user3", "pass3")?;
+ assert_eq!(resp.status(), 403);
+ Ok(())
+}