Skip to content

Commit

Permalink
Refuse duplicates within same submission
Browse files Browse the repository at this point in the history
  • Loading branch information
evanjt committed Oct 28, 2024
1 parent 56656d1 commit 56b8ec4
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
50 changes: 47 additions & 3 deletions src/external/tus/hooks.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::models::{ChangeFileInfo, PreCreateResponse};
use crate::external::tus::models::EventPayload;
use crate::external::tus::models::{EventPayload, HttpResponse};
use crate::submissions::db as SubmissionDB;
use crate::uploads::associations::db as AssociationDB;
use crate::uploads::db as InputObjectDB;
use anyhow::Result;
Expand All @@ -26,6 +27,41 @@ pub(super) async fn handle_pre_create(
println!("Submission ID: {}", submission_id);
println!("Filename: {}, Filetype: {}", filename, filetype);

// Check that the submission does not already have that same filename
// let existing_file = InputObjectDB::Entity::find()
// .filter(InputObjectDB::Column::Filename.eq(filename.clone()))
// .find_also_related(AssociationDB::Entity)
// .filter(AssociationDB::Column::SubmissionId.eq(submission_id))
// .one(&db)
// .await?;

let results: Vec<(SubmissionDB::Model, Vec<InputObjectDB::Model>)> =
SubmissionDB::Entity::find()
.filter(SubmissionDB::Column::Id.eq(submission_id))
.find_with_related(InputObjectDB::Entity)
.filter(InputObjectDB::Column::Filename.eq(filename.clone()))
.all(&db)
.await
.unwrap();

// Unpack the tuples, if there are any input objects, then the filename is already in use
if results.iter().any(|(_, objs)| objs.len() > 0) {
return Ok(PreCreateResponse {
// change_file_info: Some(ChangeFileInfo {
// id: object.last_insert_id.to_string(),
// }),
status: "success".to_string(),
http_response: Some(HttpResponse {
status_code: Some(400),
body: Some(
"File already uploaded with this filename in this submission".to_string(),
),
..Default::default()
}),
..Default::default()
});
}

let allowed_types: Vec<&str> = vec!["application/octet-stream"];
let allowed_file_extensions: Vec<&str> = vec!["pod5"];

Expand All @@ -36,6 +72,7 @@ pub(super) async fn handle_pre_create(
return Err(anyhow::anyhow!("File extension not allowed"));
}

// Check that the submission does not already have that same filename
let object = InputObjectDB::ActiveModel {
id: Set(Uuid::new_v4()),
created_on: Set(Utc::now().naive_utc()),
Expand All @@ -44,7 +81,7 @@ pub(super) async fn handle_pre_create(
all_parts_received: Set(false),
last_part_received: Set(Some(Utc::now().naive_utc())),
processing_message: Set(Some("Upload initiated".to_string())),
..Default::default() // Assuming other fields use default
..Default::default()
};

let object = match InputObjectDB::Entity::insert(object).exec(&db).await {
Expand Down Expand Up @@ -72,6 +109,7 @@ pub(super) async fn handle_pre_create(
id: object.last_insert_id.to_string(),
}),
status: "success".to_string(),
..Default::default()
})
}

Expand Down Expand Up @@ -113,6 +151,7 @@ pub(super) async fn handle_post_create(
Ok(_) => Ok(PreCreateResponse {
change_file_info: None,
status: "Upload accepted".to_string(),
..Default::default()
}),
_ => Err(anyhow::anyhow!("Failed to update after upload started")),
}
Expand Down Expand Up @@ -155,6 +194,7 @@ pub(super) async fn handle_post_receive(
return Ok(PreCreateResponse {
change_file_info: None,
status: "Upload progress updated".to_string(),
..Default::default()
});
}
let mut obj: InputObjectDB::ActiveModel = obj.unwrap().into();
Expand All @@ -169,6 +209,7 @@ pub(super) async fn handle_post_receive(
Ok(_) => Ok(PreCreateResponse {
change_file_info: None,
status: "Upload progress updated".to_string(),
..Default::default()
}),
_ => Err(anyhow::anyhow!("Failed to update upload progress")),
}
Expand All @@ -187,7 +228,7 @@ pub(super) async fn handle_pre_finish(
.and_then(|id_str| Uuid::parse_str(id_str).ok())
{
Some(id) => id,
None => {
_ => {
println!("Invalid object ID in upload_id");
return Err(anyhow::anyhow!("Invalid object ID in upload_id"));
}
Expand All @@ -212,6 +253,7 @@ pub(super) async fn handle_pre_finish(
Ok(_) => Ok(PreCreateResponse {
change_file_info: None,
status: "Upload completed".to_string(),
..Default::default()
}),
_ => Err(anyhow::anyhow!("Failed to update after upload completed")),
}
Expand Down Expand Up @@ -256,6 +298,7 @@ pub(super) async fn handle_post_finish(
Ok(_) => Ok(PreCreateResponse {
change_file_info: None,
status: "Upload completed".to_string(),
..Default::default()
}),
_ => Err(anyhow::anyhow!("Failed to update after upload completed")),
}
Expand Down Expand Up @@ -303,6 +346,7 @@ pub(super) async fn handle_post_terminate(
Ok(_) => Ok(PreCreateResponse {
change_file_info: None,
status: "Upload terminated".to_string(),
..Default::default()
}),
_ => Err(anyhow::anyhow!("Failed to delete object")),
}
Expand Down
32 changes: 32 additions & 0 deletions src/external/tus/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,41 @@ pub struct ChangeFileInfo {
pub id: String,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct HttpResponse {
#[serde(rename = "StatusCode")]
pub status_code: Option<u64>,
#[serde(rename = "Header")]
pub header: Option<Header>,
#[serde(rename = "Body")]
pub body: Option<String>,
}

impl Default for HttpResponse {
fn default() -> Self {
Self {
status_code: None,
header: None,
body: None,
}
}
}

#[derive(Debug, Deserialize, Serialize)]
pub struct PreCreateResponse {
#[serde(rename = "ChangeFileInfo")]
pub change_file_info: Option<ChangeFileInfo>,
#[serde(rename = "HTTPResponse")]
pub http_response: Option<HttpResponse>,
pub status: String,
}

impl Default for PreCreateResponse {
fn default() -> Self {
Self {
change_file_info: None,
http_response: None,
status: String::new(),
}
}
}
7 changes: 7 additions & 0 deletions src/external/tus/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "error".to_string(),
..Default::default()
}),
),
},
Expand All @@ -54,6 +55,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "error".to_string(),
..Default::default()
}),
),
},
Expand All @@ -64,6 +66,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "error".to_string(),
..Default::default()
}),
),
},
Expand All @@ -74,6 +77,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "error".to_string(),
..Default::default()
}),
),
},
Expand All @@ -85,6 +89,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "error".to_string(),
..Default::default()
}),
),
},
Expand All @@ -95,6 +100,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "error".to_string(),
..Default::default()
}),
),
},
Expand All @@ -103,6 +109,7 @@ pub async fn handle_tus_hooks(
Json(PreCreateResponse {
change_file_info: None,
status: "Unknown event type".to_string(),
..Default::default()
}),
),
}
Expand Down

0 comments on commit 56b8ec4

Please sign in to comment.