fix
ci / docker (frontend, frontend/Dockerfile, frontend) (push) Failing after 49s
ci / docker (backend, backend/Dockerfile, backend) (push) Failing after 17m1s

This commit is contained in:
2025-11-07 11:29:48 +01:00
parent 7f53bc900a
commit 9bf1fc1983
16 changed files with 152 additions and 196 deletions
+21 -22
View File
@@ -23,18 +23,18 @@ use crate::schema::{
document_versions::dsl as document_versions_dsl, documents::dsl as documents_dsl,
folders::dsl as folders_dsl, user_memberships::dsl as memberships_dsl, users::dsl as users_dsl,
};
use crate::state::AppState;
use crate::state::{AppState, PgPooledConnection};
use crate::tenants::{apply_tenant_guc, apply_user_guc, clear_user_guc};
use crate::utils::{error::StorageResultExt, http::inline_content_disposition, time::to_http_date};
const REALM: &str = "Papercrate WebDAV";
const DOWNLOAD_URL_TTL_SECONDS: u64 = 300;
#[derive(Clone, Debug)]
struct WebDavContext {
tenant_id: Uuid,
_user_id: Uuid,
_username: String,
conn: PgPooledConnection,
}
pub fn create_router() -> Router<AppState> {
@@ -72,7 +72,7 @@ async fn handle_propfind(
path: &str,
headers: HeaderMap,
) -> Result<Response, AppError> {
let context = match authenticate(state, &headers)? {
let mut context = match authenticate(state, &headers)? {
Some(user) => user,
None => return Ok(unauthorized_response()),
};
@@ -87,17 +87,18 @@ async fn handle_propfind(
let tenant_id = context.tenant_id;
let resources = if segments.is_empty() {
let contents = fetch_folder_contents(state, tenant_id, None)?;
let contents = fetch_folder_contents(&mut context.conn, tenant_id, None)?;
build_resources_for_folder(None, &[], &contents, depth)
} else {
let resolution = match resolve_path(state, tenant_id, &segments)? {
let resolution = match resolve_path(&mut context.conn, tenant_id, &segments)? {
Some(resolved) => resolved,
None => return Ok(not_found_response()),
};
match resolution {
ResolvedPath::Folder { folder, chain } => {
let contents = fetch_folder_contents(state, tenant_id, Some(folder.id))?;
let contents =
fetch_folder_contents(&mut context.conn, tenant_id, Some(folder.id))?;
build_resources_for_folder(Some(&folder), &chain, &contents, depth)
}
ResolvedPath::Document {
@@ -128,7 +129,7 @@ async fn handle_get_or_head(
headers: HeaderMap,
method: Method,
) -> Result<Response, AppError> {
let context = match authenticate(state, &headers)? {
let mut context = match authenticate(state, &headers)? {
Some(user) => user,
None => return Ok(unauthorized_response()),
};
@@ -139,7 +140,7 @@ async fn handle_get_or_head(
return Ok(method_not_allowed());
}
let resolution = match resolve_path(state, tenant_id, &segments)? {
let resolution = match resolve_path(&mut context.conn, tenant_id, &segments)? {
Some(resolved) => resolved,
None => return Ok(not_found_response()),
};
@@ -233,18 +234,16 @@ fn parse_segments(path: &str) -> AppResult<Vec<String>> {
}
fn fetch_folder_contents(
state: &AppState,
conn: &mut PgPooledConnection,
tenant_id: Uuid,
folder_id: Option<Uuid>,
) -> AppResult<WebDavFolderContents> {
let mut conn = state.db_for_tenant(tenant_id)?;
let folder = match folder_id {
Some(id) => Some(
folders_dsl::folders
.filter(folders_dsl::tenant_id.eq(tenant_id))
.find(id)
.first::<Folder>(&mut conn)?,
.first::<Folder>(conn)?,
),
None => None,
};
@@ -254,12 +253,12 @@ fn fetch_folder_contents(
.filter(folders_dsl::tenant_id.eq(tenant_id))
.filter(folders_dsl::parent_id.eq(Some(id)))
.order(folders_dsl::name.asc())
.load(&mut conn)?,
.load(conn)?,
None => folders_dsl::folders
.filter(folders_dsl::tenant_id.eq(tenant_id))
.filter(folders_dsl::parent_id.is_null())
.order(folders_dsl::name.asc())
.load(&mut conn)?,
.load(conn)?,
};
let mut docs_query = documents_dsl::documents
@@ -274,7 +273,7 @@ fn fetch_folder_contents(
let documents: Vec<Document> = docs_query
.order(documents_dsl::created_at.desc())
.load(&mut conn)?;
.load(conn)?;
let version_ids: Vec<Uuid> = documents.iter().map(|doc| doc.current_version_id).collect();
let versions: Vec<DocumentVersion> = if version_ids.is_empty() {
@@ -282,7 +281,7 @@ fn fetch_folder_contents(
} else {
document_versions_dsl::document_versions
.filter(document_versions_dsl::id.eq_any(&version_ids))
.load(&mut conn)?
.load(conn)?
};
let mut version_map = versions
@@ -498,6 +497,7 @@ fn authenticate(state: &AppState, headers: &HeaderMap) -> Result<Option<WebDavCo
tenant_id,
_user_id: user.id,
_username: user.username,
conn,
}))
}
@@ -689,11 +689,10 @@ enum ResolvedPath {
}
fn resolve_path(
state: &AppState,
conn: &mut PgPooledConnection,
tenant_id: Uuid,
segments: &[String],
) -> AppResult<Option<ResolvedPath>> {
let mut conn = state.db_for_tenant(tenant_id)?;
let mut parent_id: Option<Uuid> = None;
let mut chain: Vec<String> = Vec::new();
let mut current_folder: Option<Folder> = None;
@@ -701,7 +700,7 @@ fn resolve_path(
for (index, segment) in segments.iter().enumerate() {
let is_last = index == segments.len() - 1;
if let Some(folder) = find_folder_by_name(&mut conn, tenant_id, parent_id, segment)? {
if let Some(folder) = find_folder_by_name(conn, tenant_id, parent_id, segment)? {
chain.push(folder.name.clone());
if is_last {
return Ok(Some(ResolvedPath::Folder { folder, chain }));
@@ -713,7 +712,7 @@ fn resolve_path(
if is_last {
if let Some((document, version)) =
find_document_by_filename(&mut conn, tenant_id, parent_id, segment)?
find_document_by_filename(conn, tenant_id, parent_id, segment)?
{
chain.push(document.filename.clone());
return Ok(Some(ResolvedPath::Document {
@@ -725,7 +724,7 @@ fn resolve_path(
}
if let Ok(uuid) = Uuid::parse_str(segment) {
if let Some(folder) = find_folder_by_id(&mut conn, tenant_id, uuid)? {
if let Some(folder) = find_folder_by_id(conn, tenant_id, uuid)? {
if folder.parent_id != parent_id {
return Ok(None);
}
@@ -738,7 +737,7 @@ fn resolve_path(
continue;
}
if let Some((document, version)) = find_document_by_id(&mut conn, tenant_id, uuid)? {
if let Some((document, version)) = find_document_by_id(conn, tenant_id, uuid)? {
if document.folder_id != parent_id {
return Ok(None);
}