Skip to content

Commit

Permalink
Add endpoint to delete media
Browse files Browse the repository at this point in the history
  • Loading branch information
tomcur committed Dec 29, 2023
1 parent fa71a8f commit bf1e7d6
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 4 deletions.
3 changes: 2 additions & 1 deletion astroplant-api/src/authorization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub enum KitAction {
View,
SubscribeRealTimeMeasurements,
Delete,
DeleteMedia,
ResetPassword,
EditDetails,
EditConfiguration,
Expand Down Expand Up @@ -71,7 +72,7 @@ impl Permission for KitAction {
},
UserWithMembership(_user, membership) => match self {
View | SubscribeRealTimeMeasurements => true,
EditDetails | EditConfiguration => membership.access_configure,
EditDetails | EditConfiguration | DeleteMedia => membership.access_configure,
Delete | ResetPassword | EditMembers | SetSuperMember => membership.access_super,
RpcVersion | RpcUptime | RpcPeripheralCommand | RpcPeripheralCommandLock => {
membership.access_super
Expand Down
1 change: 1 addition & 0 deletions astroplant-api/src/bin/astroplant-api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ async fn main() -> anyhow::Result<()> {
"/media/:media_id/content",
get(media::download_media).layer(Extension(object_store)),
)
.route("/media/:media_id", delete(media::delete_media))
.route("/kits", get(kit::kits))
.route("/kits", post(kit::create_kit))
.route("/kits/:kit_serial", get(kit::kit_by_serial))
Expand Down
67 changes: 66 additions & 1 deletion astroplant-api/src/controllers/media/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,72 @@ pub async fn kit_media(
Ok(response.body(body))
}

/// Handles the `GET` /media/{mediaId}/content` route.
/// Handles the `DELETE /media/{mediaId}` route.
pub async fn delete_media(
Extension(pg): Extension<PgPool>,
user_id: Option<models::UserId>,
Path(media_id): Path<Uuid>,
) -> Result<Response, Problem> {
use crate::schema::media;
use diesel::prelude::*;
let media_id = models::MediaId(media_id);

// Check user authorization and make sure the configuration has never been activated.
let conn = pg.clone().get().await?;

{
let kit = conn
.interact_flatten_err(move |conn| {
let kit = media::table
.inner_join(crate::schema::kits::table)
.filter(crate::schema::media::id.eq(media_id.id()))
.select(crate::models::Kit::as_select())
.first(conn)
.optional()?
.ok_or(NOT_FOUND)?;

Ok::<_, Problem>(kit)
})
.await?;

// FIXME: this unnecessarily queries for the kit: we already have it.
helpers::fut_kit_permission_or_forbidden(
pg,
user_id,
kit.serial.to_owned(),
authorization::KitAction::DeleteMedia,
)
.await?;
}

conn.interact_flatten_err(move |conn| {
use crate::schema::queue_media_pending_deletion;

conn.transaction(|conn| {
let selected_media = media::dsl::media.find(media_id.id());

// 1. Add this media to the pending deletion queue.
selected_media
.select((media::id, media::datetime, media::size))
.insert_into(queue_media_pending_deletion::table)
.into_columns((
queue_media_pending_deletion::media_id,
queue_media_pending_deletion::media_datetime,
queue_media_pending_deletion::media_size,
))
.execute(conn)?;

// 2. Delete this media from the media table.
diesel::delete(selected_media).execute(conn)?;

Ok::<_, diesel::result::Error>(())
})?;

Ok::<_, Problem>(ResponseBuilder::ok().empty())
})
.await
}

/// Handles the `GET /media/{mediaId}/content` route.
pub async fn download_media(
Extension(pg): Extension<PgPool>,
Expand Down
4 changes: 2 additions & 2 deletions astroplant-api/src/models/kit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ use crate::schema::kits;
use bigdecimal::BigDecimal;
use diesel::pg::PgConnection;
use diesel::prelude::*;
use diesel::{Identifiable, QueryResult, Queryable};
use diesel::{Identifiable, QueryResult, Queryable, Selectable};
use validator::Validate;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Identifiable)]
#[diesel(table_name = kits)]
pub struct KitId(#[diesel(column_name = id)] pub i32);

#[derive(Clone, Debug, PartialEq, Eq, Queryable, Identifiable)]
#[derive(Clone, Debug, PartialEq, Eq, Queryable, Identifiable, Selectable)]
#[diesel(table_name = kits)]
pub struct Kit {
pub id: i32,
Expand Down
27 changes: 27 additions & 0 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,33 @@ paths:
$ref: "#/components/responses/ErrorRateLimit"
'500':
$ref: "#/components/responses/ErrorInternalServer"
"/media/{mediaId}":
delete:
summary: Delete media.
operationId: deleteMedia
security:
- bearerAuth: []
tags:
- kits
parameters:
- name: mediaId
in: path
required: true
description: The id of the media to delete.
schema:
type: string
format: uuid
responses:
'200':
description: The media was successfully deleted.
content:
"*": {}
'401':
$ref: "#/components/responses/ErrorUnauthorized"
'429':
$ref: "#/components/responses/ErrorRateLimit"
'500':
$ref: "#/components/responses/ErrorInternalServer"
"/media/{mediaId}/content":
get:
summary: Download media content.
Expand Down

0 comments on commit bf1e7d6

Please sign in to comment.