From ab944564d8f1622c4ca28060a10cdb13303a1c47 Mon Sep 17 00:00:00 2001 From: Emmie Maeda Date: Mon, 7 Oct 2024 21:21:44 -0400 Subject: [PATCH] Add check for last revision ID. --- deepwell/src/services/file/service.rs | 28 +++++++++++++++++++++++++++ deepwell/src/services/file/structs.rs | 3 +++ 2 files changed, 31 insertions(+) diff --git a/deepwell/src/services/file/service.rs b/deepwell/src/services/file/service.rs index efdbf52818..50decc8b48 100644 --- a/deepwell/src/services/file/service.rs +++ b/deepwell/src/services/file/service.rs @@ -110,6 +110,7 @@ impl FileService { page_id, file_id, user_id, + last_revision_id, revision_comments, bypass_filter, body, @@ -121,6 +122,8 @@ impl FileService { let last_revision = FileRevisionService::get_latest(ctx, site_id, page_id, file_id).await?; + check_last_revision(&last_revision, last_revision_id)?; + let EditFileBody { name, licensing, @@ -203,6 +206,7 @@ impl FileService { destination_page_id, file_id, user_id, + last_revision_id, revision_comments, }: MoveFile, ) -> Result> { @@ -211,6 +215,8 @@ impl FileService { FileRevisionService::get_latest(ctx, site_id, current_page_id, file_id) .await?; + check_last_revision(&last_revision, last_revision_id)?; + // Get destination filename let name = name.unwrap_or_else(|| last_revision.name.clone()); @@ -261,6 +267,7 @@ impl FileService { pub async fn delete( ctx: &ServiceContext<'_>, DeleteFile { + last_revision_id, revision_comments, site_id, page_id, @@ -284,6 +291,8 @@ impl FileService { let last_revision = FileRevisionService::get_latest(ctx, site_id, page_id, file_id).await?; + check_last_revision(&last_revision, last_revision_id)?; + // Create tombstone revision // This outdates the page, etc let output = FileRevisionService::create_tombstone( @@ -567,3 +576,22 @@ impl FileService { Ok(()) } } + +/// Verifies that the `last_revision_id` argument is the most recent. +/// +/// See the helper function with the same name in `services/page/service.rs`. +fn check_last_revision( + last_revision_model: &FileRevisionModel, + arg_last_revision_id: i64, +) -> Result<()> { + if last_revision_model.revision_id != arg_last_revision_id { + error!( + "Latest revision ID in file table is {}, but user argument has ID {}", + last_revision_model.revision_id, arg_last_revision_id, + ); + + return Err(Error::NotLatestRevisionId); + } + + Ok(()) +} diff --git a/deepwell/src/services/file/structs.rs b/deepwell/src/services/file/structs.rs index 8969487426..1913b0f34e 100644 --- a/deepwell/src/services/file/structs.rs +++ b/deepwell/src/services/file/structs.rs @@ -85,6 +85,7 @@ pub struct EditFile { pub page_id: i64, pub file_id: i64, pub user_id: i64, + pub last_revision_id: i64, pub revision_comments: String, #[serde(flatten)] @@ -110,6 +111,7 @@ pub struct MoveFile { pub site_id: i64, pub file_id: i64, pub user_id: i64, + pub last_revision_id: i64, pub name: Option, pub current_page_id: i64, pub destination_page_id: i64, @@ -119,6 +121,7 @@ pub type MoveFileOutput = CreateFileRevisionOutput; #[derive(Deserialize, Debug, Clone)] pub struct DeleteFile<'a> { + pub last_revision_id: i64, pub revision_comments: String, pub site_id: i64, pub page_id: i64,