Skip to content

Commit

Permalink
fix: [torrust#216] allow updating torrent category after upload
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Jun 26, 2023
1 parent 5568bd0 commit b4ea3d5
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/databases/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};

use crate::databases::mysql::Mysql;
use crate::databases::sqlite::Sqlite;
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::TorrentsResponse;
use crate::models::torrent::TorrentListing;
Expand Down Expand Up @@ -233,6 +234,9 @@ pub trait Database: Sync + Send {
/// Update a torrent's description with `torrent_id` and `description`.
async fn update_torrent_description(&self, torrent_id: i64, description: &str) -> Result<(), Error>;

/// Update a torrent's category with `torrent_id` and `category_id`.
async fn update_torrent_category(&self, torrent_id: i64, category_id: CategoryId) -> Result<(), Error>;

/// Add a new tag.
async fn add_tag(&self, name: &str) -> Result<(), Error>;

Expand Down
17 changes: 17 additions & 0 deletions src/databases/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use sqlx::{query, query_as, Acquire, ConnectOptions, MySqlPool};

use crate::databases::database;
use crate::databases::database::{Category, Database, Driver, Sorting, TorrentCompact};
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::TorrentsResponse;
use crate::models::torrent::TorrentListing;
Expand Down Expand Up @@ -704,6 +705,22 @@ impl Database for Mysql {
})
}

async fn update_torrent_category(&self, torrent_id: i64, category_id: CategoryId) -> Result<(), database::Error> {
query("UPDATE torrust_torrents SET category_id = ? WHERE torrent_id = ?")
.bind(category_id)
.bind(torrent_id)
.execute(&self.pool)
.await
.map_err(|_| database::Error::Error)
.and_then(|v| {
if v.rows_affected() > 0 {
Ok(())
} else {
Err(database::Error::TorrentNotFound)
}
})
}

async fn add_tag(&self, name: &str) -> Result<(), database::Error> {
query("INSERT INTO torrust_torrent_tags (name) VALUES (?)")
.bind(name)
Expand Down
17 changes: 17 additions & 0 deletions src/databases/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use sqlx::{query, query_as, Acquire, ConnectOptions, SqlitePool};

use crate::databases::database;
use crate::databases::database::{Category, Database, Driver, Sorting, TorrentCompact};
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::TorrentsResponse;
use crate::models::torrent::TorrentListing;
Expand Down Expand Up @@ -694,6 +695,22 @@ impl Database for Sqlite {
})
}

async fn update_torrent_category(&self, torrent_id: i64, category_id: CategoryId) -> Result<(), database::Error> {
query("UPDATE torrust_torrents SET category_id = $1 WHERE torrent_id = $2")
.bind(category_id)
.bind(torrent_id)
.execute(&self.pool)
.await
.map_err(|_| database::Error::Error)
.and_then(|v| {
if v.rows_affected() > 0 {
Ok(())
} else {
Err(database::Error::TorrentNotFound)
}
})
}

async fn add_tag(&self, name: &str) -> Result<(), database::Error> {
query("INSERT INTO torrust_torrent_tags (name) VALUES (?)")
.bind(name)
Expand Down
9 changes: 8 additions & 1 deletion src/services/torrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::user::DbUserRepository;
use crate::config::Configuration;
use crate::databases::database::{Category, Database, Error, Sorting};
use crate::errors::ServiceError;
use crate::models::category::CategoryId;
use crate::models::info_hash::InfoHash;
use crate::models::response::{DeletedTorrentResponse, TorrentResponse, TorrentsResponse};
use crate::models::torrent::{AddTorrentRequest, TorrentId, TorrentListing};
Expand Down Expand Up @@ -358,6 +359,7 @@ impl Index {
info_hash: &InfoHash,
title: &Option<String>,
description: &Option<String>,
category_id: &Option<CategoryId>,
tags: &Option<Vec<TagId>>,
user_id: &UserId,
) -> Result<TorrentResponse, ServiceError> {
Expand All @@ -372,7 +374,7 @@ impl Index {
}

self.torrent_info_repository
.update(&torrent_listing.torrent_id, title, description, tags)
.update(&torrent_listing.torrent_id, title, description, category_id, tags)
.await?;

let torrent_listing = self
Expand Down Expand Up @@ -473,6 +475,7 @@ impl DbTorrentInfoRepository {
torrent_id: &TorrentId,
opt_title: &Option<String>,
opt_description: &Option<String>,
opt_category_id: &Option<CategoryId>,
opt_tags: &Option<Vec<TagId>>,
) -> Result<(), Error> {
if let Some(title) = &opt_title {
Expand All @@ -483,6 +486,10 @@ impl DbTorrentInfoRepository {
self.database.update_torrent_description(*torrent_id, description).await?;
}

if let Some(category_id) = &opt_category_id {
self.database.update_torrent_category(*torrent_id, *category_id).await?;
}

if let Some(tags) = opt_tags {
let mut current_tags: Vec<TagId> = self
.database
Expand Down
20 changes: 17 additions & 3 deletions src/tracker/service.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::sync::Arc;

use hyper::StatusCode;
use log::error;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -139,10 +140,23 @@ impl Service {
.await
.map_err(|_| ServiceError::InternalServerError)?;

if let Ok(torrent_info) = response.json::<TorrentInfo>().await {
Ok(torrent_info)
if response.status() == StatusCode::NOT_FOUND {
return Err(ServiceError::TorrentNotFound);
}

let body = response.text().await;

if let Ok(body) = body {
let torrent_info = serde_json::from_str(&body);

if let Ok(torrent_info) = torrent_info {
Ok(torrent_info)
} else {
error!("Failed to parse torrent info from tracker response");
Err(ServiceError::InternalServerError)
}
} else {
error!("Failed to parse torrent info from tracker response");
error!("Tracker API response without body");
Err(ServiceError::InternalServerError)
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/web/api/v1/contexts/torrent/forms.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use serde::Deserialize;

use crate::models::category::CategoryId;
use crate::models::torrent_tag::TagId;

#[derive(Debug, Deserialize)]
pub struct UpdateTorrentInfoForm {
pub title: Option<String>,
pub description: Option<String>,
pub category: Option<CategoryId>,
pub tags: Option<Vec<TagId>>,
}
1 change: 1 addition & 0 deletions src/web/api/v1/contexts/torrent/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ pub async fn update_torrent_info_handler(
&info_hash,
&update_torrent_info_form.title,
&update_torrent_info_form.description,
&update_torrent_info_form.category,
&update_torrent_info_form.tags,
&user_id,
)
Expand Down
2 changes: 2 additions & 0 deletions src/web/api/v1/contexts/torrent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@
//! ---|---|---|---|---
//! `title` | `Option<String>` | The torrent title | No | `MandelbrotSet`
//! `description` | `Option<String>` | The torrent description | No | `MandelbrotSet image`
//! `category` | `Option<CategoryId>` | The torrent category ID | No | `1`
//! `tags` | `Option<Vec<TagId>>` | The tag Id list | No | `[1,2,3]`
//!
//!
//! Refer to the [`UpdateTorrentInfoForm`](crate::web::api::v1::contexts::torrent::forms::UpdateTorrentInfoForm)
Expand Down
2 changes: 2 additions & 0 deletions tests/common/contexts/torrent/forms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use serde::{Deserialize, Serialize};
pub struct UpdateTorrentFrom {
pub title: Option<String>,
pub description: Option<String>,
pub category: Option<i64>,
pub tags: Option<Vec<i64>>,
}

use reqwest::multipart::Form;
Expand Down
8 changes: 7 additions & 1 deletion tests/e2e/web/api/v1/contexts/torrent/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ mod for_authenticated_users {
}

#[tokio::test]
async fn it_should_allow_non_admin_users_to_update_someone_elses_torrents() {
async fn it_should_not_allow_non_admin_users_to_update_someone_elses_torrents() {
let mut env = TestEnv::new();
env.start(api::Version::V1).await;

Expand All @@ -494,6 +494,8 @@ mod for_authenticated_users {
UpdateTorrentFrom {
title: Some(new_title.clone()),
description: Some(new_description.clone()),
category: None,
tags: None,
},
)
.await;
Expand Down Expand Up @@ -537,6 +539,8 @@ mod for_authenticated_users {
UpdateTorrentFrom {
title: Some(new_title.clone()),
description: Some(new_description.clone()),
category: None,
tags: None,
},
)
.await;
Expand Down Expand Up @@ -611,6 +615,8 @@ mod for_authenticated_users {
UpdateTorrentFrom {
title: Some(new_title.clone()),
description: Some(new_description.clone()),
category: None,
tags: None,
},
)
.await;
Expand Down

0 comments on commit b4ea3d5

Please sign in to comment.