-
Notifications
You must be signed in to change notification settings - Fork 580
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow crate version deletion in the first 24 hours from creation
- Loading branch information
Marco Napetti
committed
Feb 6, 2023
1 parent
5231704
commit c4cf991
Showing
3 changed files
with
73 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod delete; | ||
pub mod deprecated; | ||
pub mod downloads; | ||
pub mod metadata; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//! Functionality related to deleting a crate. | ||
|
||
use chrono::{Duration, Utc}; | ||
use diesel::dsl::count_star; | ||
|
||
use crate::controllers::cargo_prelude::*; | ||
|
||
use crate::schema::*; | ||
use crate::util::errors::internal; | ||
use crate::views::{EncodableCrate, GoodCrate, PublishWarnings}; | ||
|
||
use super::version_and_crate; | ||
|
||
/// Handles the `DELETE /crates/:crate_id/:version` route. | ||
/// | ||
/// Actually deletion is allowed only in the first 24 hours from creation | ||
pub async fn delete( | ||
app: AppState, | ||
Path((crate_name, semver)): Path<(String, String)>, | ||
) -> AppResult<Json<GoodCrate>> { | ||
let conn = app.db_read()?; | ||
let (version, krate) = version_and_crate(&conn, &crate_name, &semver)?; | ||
|
||
if Utc::now() | ||
.naive_utc() | ||
.signed_duration_since(version.created_at) | ||
> Duration::hours(24) | ||
{ | ||
return Err(cargo_err( | ||
"Version deletion is allowed only in the first 24 hours from creation", | ||
)); | ||
} | ||
|
||
// Create a transaction on the database, if there are no errors, | ||
// commit the transactions to delete the version. | ||
// If there are no remaining versions, delete the crate | ||
conn.transaction(|| { | ||
diesel::delete(versions::table.find(version.id)).execute(&*conn)?; | ||
|
||
let top_versions = krate.top_versions(&conn)?; | ||
|
||
// we can't check top_versions to know if there aren't remaining versions | ||
// because it excludes yanked versions | ||
let remaining: i64 = versions::table | ||
.filter(versions::crate_id.eq(krate.id)) | ||
.select(count_star()) | ||
.first(&*conn) | ||
.optional()? | ||
.unwrap_or_default(); | ||
if remaining <= 0 { | ||
diesel::delete(crates::table.find(krate.id)).execute(&*conn)?; | ||
|
||
let uploader = app.config.uploader(); | ||
uploader | ||
.delete_index(app.http_client(), &krate.name) | ||
.map_err(|e| internal(format_args!("failed to delete crate: {e}")))?; | ||
} | ||
|
||
Ok(Json(GoodCrate { | ||
krate: EncodableCrate::from_minimal(krate, Some(&top_versions), None, true, None), | ||
warnings: PublishWarnings { | ||
invalid_categories: vec![], | ||
invalid_badges: vec![], | ||
other: vec![], | ||
}, | ||
})) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters