From 40eb805934567fd54619581567786e5ad05003ad Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 10:01:41 +0000 Subject: [PATCH 01/11] refactor: [1182] extract WhitelistManager --- src/core/mod.rs | 174 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 130 insertions(+), 44 deletions(-) diff --git a/src/core/mod.rs b/src/core/mod.rs index 6ba8e94ad..066792eb3 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -498,7 +498,7 @@ pub struct Tracker { keys: tokio::sync::RwLock>, /// The list of allowed torrents. Only for listed trackers. - whitelist: tokio::sync::RwLock>, + whitelist_manager: WhiteListManager, /// The in-memory torrents repository. torrents: Arc, @@ -510,6 +510,123 @@ pub struct Tracker { stats_repository: statistics::repository::Repository, } +pub struct WhiteListManager { + /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) + /// or [`MySQL`](crate::core::databases::mysql) + database: Arc>, + + /// The list of allowed torrents. Only for listed trackers. + whitelist: tokio::sync::RwLock>, +} + +impl WhiteListManager { + #[must_use] + pub fn new(database: Arc>) -> Self { + Self { + database, + whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), + } + } + + /// It adds a torrent to the whitelist. + /// Adding torrents is not relevant to public trackers. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. + pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + self.add_torrent_to_database_whitelist(info_hash)?; + self.add_torrent_to_memory_whitelist(info_hash).await; + Ok(()) + } + + /// It adds a torrent to the whitelist if it has not been whitelisted previously + fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if is_whitelisted { + return Ok(()); + } + + self.database.add_info_hash_to_whitelist(*info_hash)?; + + Ok(()) + } + + pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.insert(*info_hash) + } + + /// It removes a torrent from the whitelist. + /// Removing torrents is not relevant to public trackers. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. + pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + self.remove_torrent_from_database_whitelist(info_hash)?; + self.remove_torrent_from_memory_whitelist(info_hash).await; + Ok(()) + } + + /// It removes a torrent from the whitelist in the database. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. + pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if !is_whitelisted { + return Ok(()); + } + + self.database.remove_info_hash_from_whitelist(*info_hash)?; + + Ok(()) + } + + /// It removes a torrent from the whitelist in memory. + /// + /// # Context: Whitelist + pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.remove(info_hash) + } + + /// It checks if a torrent is whitelisted. + /// + /// # Context: Whitelist + pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { + self.whitelist.read().await.contains(info_hash) + } + + /// It loads the whitelist from the database. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. + pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { + let whitelisted_torrents_from_database = self.database.load_whitelist()?; + let mut whitelist = self.whitelist.write().await; + + whitelist.clear(); + + for info_hash in whitelisted_torrents_from_database { + let _: bool = whitelist.insert(info_hash); + } + + Ok(()) + } +} + /// How many peers the peer announcing wants in the announce response. #[derive(Clone, Debug, PartialEq, Default)] pub enum PeersWanted { @@ -587,7 +704,7 @@ impl Tracker { Ok(Tracker { config: config.clone(), keys: tokio::sync::RwLock::new(std::collections::HashMap::new()), - whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), + whitelist_manager: WhiteListManager::new(database.clone()), torrents: Arc::default(), stats_event_sender, stats_repository, @@ -1068,26 +1185,11 @@ impl Tracker { /// /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.add_torrent_to_database_whitelist(info_hash)?; - self.add_torrent_to_memory_whitelist(info_hash).await; - Ok(()) - } - - /// It adds a torrent to the whitelist if it has not been whitelisted previously - fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if is_whitelisted { - return Ok(()); - } - - self.database.add_info_hash_to_whitelist(*info_hash)?; - - Ok(()) + self.whitelist_manager.add_torrent_to_whitelist(info_hash).await } pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.insert(*info_hash) + self.whitelist_manager.add_torrent_to_memory_whitelist(info_hash).await } /// It removes a torrent from the whitelist. @@ -1099,9 +1201,7 @@ impl Tracker { /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.remove_torrent_from_database_whitelist(info_hash)?; - self.remove_torrent_from_memory_whitelist(info_hash).await; - Ok(()) + self.whitelist_manager.remove_torrent_from_whitelist(info_hash).await } /// It removes a torrent from the whitelist in the database. @@ -1112,29 +1212,21 @@ impl Tracker { /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if !is_whitelisted { - return Ok(()); - } - - self.database.remove_info_hash_from_whitelist(*info_hash)?; - - Ok(()) + self.whitelist_manager.remove_torrent_from_database_whitelist(info_hash) } /// It removes a torrent from the whitelist in memory. /// /// # Context: Whitelist pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.remove(info_hash) + self.whitelist_manager.remove_torrent_from_memory_whitelist(info_hash).await } /// It checks if a torrent is whitelisted. /// /// # Context: Whitelist pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { - self.whitelist.read().await.contains(info_hash) + self.whitelist_manager.is_info_hash_whitelisted(info_hash).await } /// It loads the whitelist from the database. @@ -1145,16 +1237,7 @@ impl Tracker { /// /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { - let whitelisted_torrents_from_database = self.database.load_whitelist()?; - let mut whitelist = self.whitelist.write().await; - - whitelist.clear(); - - for info_hash in whitelisted_torrents_from_database { - let _: bool = whitelist.insert(info_hash); - } - - Ok(()) + self.whitelist_manager.load_whitelist_from_database().await } /// It return the `Tracker` [`statistics::metrics::Metrics`]. @@ -1821,7 +1904,10 @@ mod tests { tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); // Remove torrent from the in-memory whitelist - tracker.whitelist.write().await.remove(&info_hash); + tracker + .whitelist_manager + .remove_torrent_from_memory_whitelist(&info_hash) + .await; assert!(!tracker.is_info_hash_whitelisted(&info_hash).await); tracker.load_whitelist_from_database().await.unwrap(); From 439493d7ecf7b051f0fc3b1041b346e0a7d69be7 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 10:09:23 +0000 Subject: [PATCH 02/11] refactor: [#1182] move extracted service to new mod --- src/core/mod.rs | 119 +------------------------------------ src/core/whitelist/mod.rs | 122 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 117 deletions(-) create mode 100644 src/core/whitelist/mod.rs diff --git a/src/core/mod.rs b/src/core/mod.rs index 066792eb3..4b5f97a92 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -445,6 +445,7 @@ pub mod error; pub mod services; pub mod statistics; pub mod torrent; +pub mod whitelist; pub mod peer_tests; @@ -470,6 +471,7 @@ use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch}; use torrust_tracker_torrent_repository::entry::EntrySync; use torrust_tracker_torrent_repository::repository::Repository; use tracing::instrument; +use whitelist::WhiteListManager; use self::auth::Key; use self::error::Error; @@ -510,123 +512,6 @@ pub struct Tracker { stats_repository: statistics::repository::Repository, } -pub struct WhiteListManager { - /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) - /// or [`MySQL`](crate::core::databases::mysql) - database: Arc>, - - /// The list of allowed torrents. Only for listed trackers. - whitelist: tokio::sync::RwLock>, -} - -impl WhiteListManager { - #[must_use] - pub fn new(database: Arc>) -> Self { - Self { - database, - whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), - } - } - - /// It adds a torrent to the whitelist. - /// Adding torrents is not relevant to public trackers. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. - pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.add_torrent_to_database_whitelist(info_hash)?; - self.add_torrent_to_memory_whitelist(info_hash).await; - Ok(()) - } - - /// It adds a torrent to the whitelist if it has not been whitelisted previously - fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if is_whitelisted { - return Ok(()); - } - - self.database.add_info_hash_to_whitelist(*info_hash)?; - - Ok(()) - } - - pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.insert(*info_hash) - } - - /// It removes a torrent from the whitelist. - /// Removing torrents is not relevant to public trackers. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. - pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.remove_torrent_from_database_whitelist(info_hash)?; - self.remove_torrent_from_memory_whitelist(info_hash).await; - Ok(()) - } - - /// It removes a torrent from the whitelist in the database. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. - pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if !is_whitelisted { - return Ok(()); - } - - self.database.remove_info_hash_from_whitelist(*info_hash)?; - - Ok(()) - } - - /// It removes a torrent from the whitelist in memory. - /// - /// # Context: Whitelist - pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.remove(info_hash) - } - - /// It checks if a torrent is whitelisted. - /// - /// # Context: Whitelist - pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { - self.whitelist.read().await.contains(info_hash) - } - - /// It loads the whitelist from the database. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. - pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { - let whitelisted_torrents_from_database = self.database.load_whitelist()?; - let mut whitelist = self.whitelist.write().await; - - whitelist.clear(); - - for info_hash in whitelisted_torrents_from_database { - let _: bool = whitelist.insert(info_hash); - } - - Ok(()) - } -} - /// How many peers the peer announcing wants in the announce response. #[derive(Clone, Debug, PartialEq, Default)] pub enum PeersWanted { diff --git a/src/core/whitelist/mod.rs b/src/core/whitelist/mod.rs new file mode 100644 index 000000000..266bcec23 --- /dev/null +++ b/src/core/whitelist/mod.rs @@ -0,0 +1,122 @@ +use std::sync::Arc; + +use bittorrent_primitives::info_hash::InfoHash; + +use super::databases::{self, Database}; + +pub struct WhiteListManager { + /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) + /// or [`MySQL`](crate::core::databases::mysql) + database: Arc>, + + /// The list of allowed torrents. Only for listed trackers. + whitelist: tokio::sync::RwLock>, +} + +impl WhiteListManager { + #[must_use] + pub fn new(database: Arc>) -> Self { + Self { + database, + whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), + } + } + + /// It adds a torrent to the whitelist. + /// Adding torrents is not relevant to public trackers. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. + pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + self.add_torrent_to_database_whitelist(info_hash)?; + self.add_torrent_to_memory_whitelist(info_hash).await; + Ok(()) + } + + /// It adds a torrent to the whitelist if it has not been whitelisted previously + fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if is_whitelisted { + return Ok(()); + } + + self.database.add_info_hash_to_whitelist(*info_hash)?; + + Ok(()) + } + + pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.insert(*info_hash) + } + + /// It removes a torrent from the whitelist. + /// Removing torrents is not relevant to public trackers. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. + pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + self.remove_torrent_from_database_whitelist(info_hash)?; + self.remove_torrent_from_memory_whitelist(info_hash).await; + Ok(()) + } + + /// It removes a torrent from the whitelist in the database. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. + pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if !is_whitelisted { + return Ok(()); + } + + self.database.remove_info_hash_from_whitelist(*info_hash)?; + + Ok(()) + } + + /// It removes a torrent from the whitelist in memory. + /// + /// # Context: Whitelist + pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.remove(info_hash) + } + + /// It checks if a torrent is whitelisted. + /// + /// # Context: Whitelist + pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { + self.whitelist.read().await.contains(info_hash) + } + + /// It loads the whitelist from the database. + /// + /// # Context: Whitelist + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. + pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { + let whitelisted_torrents_from_database = self.database.load_whitelist()?; + let mut whitelist = self.whitelist.write().await; + + whitelist.clear(); + + for info_hash in whitelisted_torrents_from_database { + let _: bool = whitelist.insert(info_hash); + } + + Ok(()) + } +} From 39d1620b338a31328ac96aaaa49e327443183c23 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 10:13:15 +0000 Subject: [PATCH 03/11] refactor: [#1182] remove unused methods --- src/core/mod.rs | 24 +----------------------- src/servers/udp/handlers.rs | 2 +- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/core/mod.rs b/src/core/mod.rs index 4b5f97a92..875992da5 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -500,7 +500,7 @@ pub struct Tracker { keys: tokio::sync::RwLock>, /// The list of allowed torrents. Only for listed trackers. - whitelist_manager: WhiteListManager, + pub whitelist_manager: WhiteListManager, /// The in-memory torrents repository. torrents: Arc, @@ -1073,10 +1073,6 @@ impl Tracker { self.whitelist_manager.add_torrent_to_whitelist(info_hash).await } - pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist_manager.add_torrent_to_memory_whitelist(info_hash).await - } - /// It removes a torrent from the whitelist. /// Removing torrents is not relevant to public trackers. /// @@ -1089,24 +1085,6 @@ impl Tracker { self.whitelist_manager.remove_torrent_from_whitelist(info_hash).await } - /// It removes a torrent from the whitelist in the database. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. - pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.whitelist_manager.remove_torrent_from_database_whitelist(info_hash) - } - - /// It removes a torrent from the whitelist in memory. - /// - /// # Context: Whitelist - pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist_manager.remove_torrent_from_memory_whitelist(info_hash).await - } - /// It checks if a torrent is whitelisted. /// /// # Context: Whitelist diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index 1a9c164e2..3d7d411ce 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -1391,7 +1391,7 @@ mod tests { add_a_seeder(tracker.clone(), &remote_addr, &info_hash).await; - tracker.add_torrent_to_memory_whitelist(&info_hash.0.into()).await; + tracker.whitelist_manager.add_torrent_to_memory_whitelist(&info_hash.0.into()).await; let request = build_scrape_request(&remote_addr, &info_hash); From ea35ba5fa7caae38ace7af089e87c63e19391f54 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 10:55:37 +0000 Subject: [PATCH 04/11] refactor: [#1182] extract struct InMemoryWhitelist --- src/core/whitelist/mod.rs | 134 +++++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 25 deletions(-) diff --git a/src/core/whitelist/mod.rs b/src/core/whitelist/mod.rs index 266bcec23..84469ca37 100644 --- a/src/core/whitelist/mod.rs +++ b/src/core/whitelist/mod.rs @@ -4,13 +4,14 @@ use bittorrent_primitives::info_hash::InfoHash; use super::databases::{self, Database}; +/// It handles the list of allowed torrents. Only for listed trackers. pub struct WhiteListManager { /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) /// or [`MySQL`](crate::core::databases::mysql) database: Arc>, - /// The list of allowed torrents. Only for listed trackers. - whitelist: tokio::sync::RwLock>, + /// The in-memory list of allowed torrents. + in_memory_whitelist: InMemoryWhitelist, } impl WhiteListManager { @@ -18,21 +19,19 @@ impl WhiteListManager { pub fn new(database: Arc>) -> Self { Self { database, - whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), + in_memory_whitelist: InMemoryWhitelist::new(), } } /// It adds a torrent to the whitelist. /// Adding torrents is not relevant to public trackers. /// - /// # Context: Whitelist - /// /// # Errors /// /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { self.add_torrent_to_database_whitelist(info_hash)?; - self.add_torrent_to_memory_whitelist(info_hash).await; + self.in_memory_whitelist.add(info_hash).await; Ok(()) } @@ -49,15 +48,9 @@ impl WhiteListManager { Ok(()) } - pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.insert(*info_hash) - } - /// It removes a torrent from the whitelist. /// Removing torrents is not relevant to public trackers. /// - /// # Context: Whitelist - /// /// # Errors /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. @@ -69,8 +62,6 @@ impl WhiteListManager { /// It removes a torrent from the whitelist in the database. /// - /// # Context: Whitelist - /// /// # Errors /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. @@ -86,37 +77,130 @@ impl WhiteListManager { Ok(()) } + /// It adds a torrent from the whitelist in memory. + pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { + self.in_memory_whitelist.add(info_hash).await + } + /// It removes a torrent from the whitelist in memory. - /// - /// # Context: Whitelist pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.remove(info_hash) + self.in_memory_whitelist.remove(info_hash).await } /// It checks if a torrent is whitelisted. - /// - /// # Context: Whitelist pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { - self.whitelist.read().await.contains(info_hash) + self.in_memory_whitelist.contains(info_hash).await } /// It loads the whitelist from the database. /// - /// # Context: Whitelist - /// /// # Errors /// /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { let whitelisted_torrents_from_database = self.database.load_whitelist()?; - let mut whitelist = self.whitelist.write().await; - whitelist.clear(); + self.in_memory_whitelist.clear().await; for info_hash in whitelisted_torrents_from_database { - let _: bool = whitelist.insert(info_hash); + let _: bool = self.in_memory_whitelist.add(&info_hash).await; } Ok(()) } } + +struct InMemoryWhitelist { + /// The list of allowed torrents. Only for listed trackers. + whitelist: tokio::sync::RwLock>, +} + +impl InMemoryWhitelist { + pub fn new() -> Self { + Self { + whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), + } + } + + /// It adds a torrent from the whitelist in memory. + pub async fn add(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.insert(*info_hash) + } + + /// It removes a torrent from the whitelist in memory. + pub async fn remove(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.remove(info_hash) + } + + /// It checks if it contains an info-hash. + pub async fn contains(&self, info_hash: &InfoHash) -> bool { + self.whitelist.read().await.contains(info_hash) + } + + /// It clears the whitelist. + pub async fn clear(&self) { + let mut whitelist = self.whitelist.write().await; + whitelist.clear(); + } +} + +#[cfg(test)] +mod tests { + use bittorrent_primitives::info_hash::InfoHash; + + fn sample_info_hash() -> InfoHash { + "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0".parse::().unwrap() // # DevSkim: ignore DS173237 + } + + mod in_memory_whitelist { + + use crate::core::whitelist::tests::sample_info_hash; + use crate::core::whitelist::InMemoryWhitelist; + + #[tokio::test] + async fn should_allow_adding_a_new_torrent_to_the_whitelist() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::new(); + + whitelist.add(&info_hash).await; + + assert!(whitelist.contains(&info_hash).await); + } + + #[tokio::test] + async fn should_allow_removing_a_new_torrent_to_the_whitelist() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::new(); + + whitelist.add(&info_hash).await; + whitelist.remove(&sample_info_hash()).await; + + assert!(!whitelist.contains(&info_hash).await); + } + + #[tokio::test] + async fn should_allow_clearing_the_whitelist() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::new(); + + whitelist.add(&info_hash).await; + whitelist.clear().await; + + assert!(!whitelist.contains(&info_hash).await); + } + + #[tokio::test] + async fn should_allow_checking_if_an_infohash_is_whitelisted() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::new(); + + whitelist.add(&info_hash).await; + + assert!(whitelist.contains(&info_hash).await); + } + } +} From 07f53a4ad665c33a2047867075c0657700cb7260 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 11:09:42 +0000 Subject: [PATCH 05/11] refactor: [#1182] extract strcut DatabaseWhitelist --- src/core/whitelist/mod.rs | 98 ++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/src/core/whitelist/mod.rs b/src/core/whitelist/mod.rs index 84469ca37..97affa1ea 100644 --- a/src/core/whitelist/mod.rs +++ b/src/core/whitelist/mod.rs @@ -6,20 +6,19 @@ use super::databases::{self, Database}; /// It handles the list of allowed torrents. Only for listed trackers. pub struct WhiteListManager { - /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) - /// or [`MySQL`](crate::core::databases::mysql) - database: Arc>, - /// The in-memory list of allowed torrents. in_memory_whitelist: InMemoryWhitelist, + + /// The persisted list of allowed torrents. + database_whitelist: DatabaseWhitelist, } impl WhiteListManager { #[must_use] pub fn new(database: Arc>) -> Self { Self { - database, in_memory_whitelist: InMemoryWhitelist::new(), + database_whitelist: DatabaseWhitelist::new(database), } } @@ -30,24 +29,11 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.add_torrent_to_database_whitelist(info_hash)?; + self.database_whitelist.add_torrent_to_database_whitelist(info_hash)?; self.in_memory_whitelist.add(info_hash).await; Ok(()) } - /// It adds a torrent to the whitelist if it has not been whitelisted previously - fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if is_whitelisted { - return Ok(()); - } - - self.database.add_info_hash_to_whitelist(*info_hash)?; - - Ok(()) - } - /// It removes a torrent from the whitelist. /// Removing torrents is not relevant to public trackers. /// @@ -55,8 +41,8 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.remove_torrent_from_database_whitelist(info_hash)?; - self.remove_torrent_from_memory_whitelist(info_hash).await; + self.database_whitelist.remove_torrent_from_database_whitelist(info_hash)?; + self.in_memory_whitelist.remove(info_hash).await; Ok(()) } @@ -66,15 +52,7 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if !is_whitelisted { - return Ok(()); - } - - self.database.remove_info_hash_from_whitelist(*info_hash)?; - - Ok(()) + self.database_whitelist.remove_torrent_from_database_whitelist(info_hash) } /// It adds a torrent from the whitelist in memory. @@ -98,7 +76,7 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { - let whitelisted_torrents_from_database = self.database.load_whitelist()?; + let whitelisted_torrents_from_database = self.database_whitelist.load_whitelist_from_database()?; self.in_memory_whitelist.clear().await; @@ -110,8 +88,9 @@ impl WhiteListManager { } } +/// The in-memory list of allowed torrents. struct InMemoryWhitelist { - /// The list of allowed torrents. Only for listed trackers. + /// The list of allowed torrents. whitelist: tokio::sync::RwLock>, } @@ -144,6 +123,59 @@ impl InMemoryWhitelist { } } +/// The persisted list of allowed torrents. +struct DatabaseWhitelist { + /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) + /// or [`MySQL`](crate::core::databases::mysql) + database: Arc>, +} + +impl DatabaseWhitelist { + #[must_use] + pub fn new(database: Arc>) -> Self { + Self { database } + } + + /// It adds a torrent to the whitelist if it has not been whitelisted previously + fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if is_whitelisted { + return Ok(()); + } + + self.database.add_info_hash_to_whitelist(*info_hash)?; + + Ok(()) + } + + /// It removes a torrent from the whitelist in the database. + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. + pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if !is_whitelisted { + return Ok(()); + } + + self.database.remove_info_hash_from_whitelist(*info_hash)?; + + Ok(()) + } + + /// It loads the whitelist from the database. + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. + pub fn load_whitelist_from_database(&self) -> Result, databases::error::Error> { + self.database.load_whitelist() + } +} + #[cfg(test)] mod tests { use bittorrent_primitives::info_hash::InfoHash; @@ -203,4 +235,6 @@ mod tests { assert!(whitelist.contains(&info_hash).await); } } + + mod database_whitelist {} } From cc2bc7bb8e54772fac42523dc8b412429df5a0b7 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 11:17:48 +0000 Subject: [PATCH 06/11] refactor: [#1182] move structs to new mods in whitelist --- src/core/whitelist/in_memory.rs | 88 +++++++++++++++++ src/core/whitelist/mod.rs | 166 ++------------------------------ src/core/whitelist/persisted.rs | 62 ++++++++++++ src/servers/udp/handlers.rs | 5 +- 4 files changed, 164 insertions(+), 157 deletions(-) create mode 100644 src/core/whitelist/in_memory.rs create mode 100644 src/core/whitelist/persisted.rs diff --git a/src/core/whitelist/in_memory.rs b/src/core/whitelist/in_memory.rs new file mode 100644 index 000000000..78e0eb11f --- /dev/null +++ b/src/core/whitelist/in_memory.rs @@ -0,0 +1,88 @@ +use bittorrent_primitives::info_hash::InfoHash; + +/// The in-memory list of allowed torrents. +#[derive(Debug, Default)] +pub struct InMemoryWhitelist { + /// The list of allowed torrents. + whitelist: tokio::sync::RwLock>, +} + +impl InMemoryWhitelist { + /// It adds a torrent from the whitelist in memory. + pub async fn add(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.insert(*info_hash) + } + + /// It removes a torrent from the whitelist in memory. + pub async fn remove(&self, info_hash: &InfoHash) -> bool { + self.whitelist.write().await.remove(info_hash) + } + + /// It checks if it contains an info-hash. + pub async fn contains(&self, info_hash: &InfoHash) -> bool { + self.whitelist.read().await.contains(info_hash) + } + + /// It clears the whitelist. + pub async fn clear(&self) { + let mut whitelist = self.whitelist.write().await; + whitelist.clear(); + } +} + +#[cfg(test)] +mod tests { + use bittorrent_primitives::info_hash::InfoHash; + + use crate::core::whitelist::in_memory::InMemoryWhitelist; + + fn sample_info_hash() -> InfoHash { + "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0".parse::().unwrap() // # DevSkim: ignore DS173237 + } + + #[tokio::test] + async fn should_allow_adding_a_new_torrent_to_the_whitelist() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::default(); + + whitelist.add(&info_hash).await; + + assert!(whitelist.contains(&info_hash).await); + } + + #[tokio::test] + async fn should_allow_removing_a_new_torrent_to_the_whitelist() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::default(); + + whitelist.add(&info_hash).await; + whitelist.remove(&sample_info_hash()).await; + + assert!(!whitelist.contains(&info_hash).await); + } + + #[tokio::test] + async fn should_allow_clearing_the_whitelist() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::default(); + + whitelist.add(&info_hash).await; + whitelist.clear().await; + + assert!(!whitelist.contains(&info_hash).await); + } + + #[tokio::test] + async fn should_allow_checking_if_an_infohash_is_whitelisted() { + let info_hash = sample_info_hash(); + + let whitelist = InMemoryWhitelist::default(); + + whitelist.add(&info_hash).await; + + assert!(whitelist.contains(&info_hash).await); + } +} diff --git a/src/core/whitelist/mod.rs b/src/core/whitelist/mod.rs index 97affa1ea..5096bacc9 100644 --- a/src/core/whitelist/mod.rs +++ b/src/core/whitelist/mod.rs @@ -1,6 +1,11 @@ +pub mod in_memory; +pub mod persisted; + use std::sync::Arc; use bittorrent_primitives::info_hash::InfoHash; +use in_memory::InMemoryWhitelist; +use persisted::DatabaseWhitelist; use super::databases::{self, Database}; @@ -17,7 +22,7 @@ impl WhiteListManager { #[must_use] pub fn new(database: Arc>) -> Self { Self { - in_memory_whitelist: InMemoryWhitelist::new(), + in_memory_whitelist: InMemoryWhitelist::default(), database_whitelist: DatabaseWhitelist::new(database), } } @@ -29,7 +34,7 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.database_whitelist.add_torrent_to_database_whitelist(info_hash)?; + self.database_whitelist.add(info_hash)?; self.in_memory_whitelist.add(info_hash).await; Ok(()) } @@ -41,7 +46,7 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.database_whitelist.remove_torrent_from_database_whitelist(info_hash)?; + self.database_whitelist.remove(info_hash)?; self.in_memory_whitelist.remove(info_hash).await; Ok(()) } @@ -52,7 +57,7 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.database_whitelist.remove_torrent_from_database_whitelist(info_hash) + self.database_whitelist.remove(info_hash) } /// It adds a torrent from the whitelist in memory. @@ -76,7 +81,7 @@ impl WhiteListManager { /// /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { - let whitelisted_torrents_from_database = self.database_whitelist.load_whitelist_from_database()?; + let whitelisted_torrents_from_database = self.database_whitelist.load_from_database()?; self.in_memory_whitelist.clear().await; @@ -87,154 +92,3 @@ impl WhiteListManager { Ok(()) } } - -/// The in-memory list of allowed torrents. -struct InMemoryWhitelist { - /// The list of allowed torrents. - whitelist: tokio::sync::RwLock>, -} - -impl InMemoryWhitelist { - pub fn new() -> Self { - Self { - whitelist: tokio::sync::RwLock::new(std::collections::HashSet::new()), - } - } - - /// It adds a torrent from the whitelist in memory. - pub async fn add(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.insert(*info_hash) - } - - /// It removes a torrent from the whitelist in memory. - pub async fn remove(&self, info_hash: &InfoHash) -> bool { - self.whitelist.write().await.remove(info_hash) - } - - /// It checks if it contains an info-hash. - pub async fn contains(&self, info_hash: &InfoHash) -> bool { - self.whitelist.read().await.contains(info_hash) - } - - /// It clears the whitelist. - pub async fn clear(&self) { - let mut whitelist = self.whitelist.write().await; - whitelist.clear(); - } -} - -/// The persisted list of allowed torrents. -struct DatabaseWhitelist { - /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) - /// or [`MySQL`](crate::core::databases::mysql) - database: Arc>, -} - -impl DatabaseWhitelist { - #[must_use] - pub fn new(database: Arc>) -> Self { - Self { database } - } - - /// It adds a torrent to the whitelist if it has not been whitelisted previously - fn add_torrent_to_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if is_whitelisted { - return Ok(()); - } - - self.database.add_info_hash_to_whitelist(*info_hash)?; - - Ok(()) - } - - /// It removes a torrent from the whitelist in the database. - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. - pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; - - if !is_whitelisted { - return Ok(()); - } - - self.database.remove_info_hash_from_whitelist(*info_hash)?; - - Ok(()) - } - - /// It loads the whitelist from the database. - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. - pub fn load_whitelist_from_database(&self) -> Result, databases::error::Error> { - self.database.load_whitelist() - } -} - -#[cfg(test)] -mod tests { - use bittorrent_primitives::info_hash::InfoHash; - - fn sample_info_hash() -> InfoHash { - "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0".parse::().unwrap() // # DevSkim: ignore DS173237 - } - - mod in_memory_whitelist { - - use crate::core::whitelist::tests::sample_info_hash; - use crate::core::whitelist::InMemoryWhitelist; - - #[tokio::test] - async fn should_allow_adding_a_new_torrent_to_the_whitelist() { - let info_hash = sample_info_hash(); - - let whitelist = InMemoryWhitelist::new(); - - whitelist.add(&info_hash).await; - - assert!(whitelist.contains(&info_hash).await); - } - - #[tokio::test] - async fn should_allow_removing_a_new_torrent_to_the_whitelist() { - let info_hash = sample_info_hash(); - - let whitelist = InMemoryWhitelist::new(); - - whitelist.add(&info_hash).await; - whitelist.remove(&sample_info_hash()).await; - - assert!(!whitelist.contains(&info_hash).await); - } - - #[tokio::test] - async fn should_allow_clearing_the_whitelist() { - let info_hash = sample_info_hash(); - - let whitelist = InMemoryWhitelist::new(); - - whitelist.add(&info_hash).await; - whitelist.clear().await; - - assert!(!whitelist.contains(&info_hash).await); - } - - #[tokio::test] - async fn should_allow_checking_if_an_infohash_is_whitelisted() { - let info_hash = sample_info_hash(); - - let whitelist = InMemoryWhitelist::new(); - - whitelist.add(&info_hash).await; - - assert!(whitelist.contains(&info_hash).await); - } - } - - mod database_whitelist {} -} diff --git a/src/core/whitelist/persisted.rs b/src/core/whitelist/persisted.rs new file mode 100644 index 000000000..993060139 --- /dev/null +++ b/src/core/whitelist/persisted.rs @@ -0,0 +1,62 @@ +use std::sync::Arc; + +use bittorrent_primitives::info_hash::InfoHash; + +use super::databases::{self, Database}; + +/// The persisted list of allowed torrents. +pub struct DatabaseWhitelist { + /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite) + /// or [`MySQL`](crate::core::databases::mysql) + database: Arc>, +} + +impl DatabaseWhitelist { + #[must_use] + pub fn new(database: Arc>) -> Self { + Self { database } + } + + /// It adds a torrent to the whitelist if it has not been whitelisted previously + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to add the `info_hash` to the whitelist database. + pub fn add(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if is_whitelisted { + return Ok(()); + } + + self.database.add_info_hash_to_whitelist(*info_hash)?; + + Ok(()) + } + + /// It removes a torrent from the whitelist in the database. + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. + pub fn remove(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { + let is_whitelisted = self.database.is_info_hash_whitelisted(*info_hash)?; + + if !is_whitelisted { + return Ok(()); + } + + self.database.remove_info_hash_from_whitelist(*info_hash)?; + + Ok(()) + } + + /// It loads the whitelist from the database. + /// + /// # Errors + /// + /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. + pub fn load_from_database(&self) -> Result, databases::error::Error> { + self.database.load_whitelist() + } +} diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index 3d7d411ce..62f7d0a02 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -1391,7 +1391,10 @@ mod tests { add_a_seeder(tracker.clone(), &remote_addr, &info_hash).await; - tracker.whitelist_manager.add_torrent_to_memory_whitelist(&info_hash.0.into()).await; + tracker + .whitelist_manager + .add_torrent_to_memory_whitelist(&info_hash.0.into()) + .await; let request = build_scrape_request(&remote_addr, &info_hash); From 2f1abeb873a7c9d273247d064f61163ef3bf0168 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 16:14:51 +0000 Subject: [PATCH 07/11] refactor: [#1182] inject database and whitelist in tracker as dep Inject the database (persistence) and whitelist manager into the Tracker via the contructor to be able to use the whitelist manager directly in Axum handlers. --- src/core/mod.rs | 17 ++-- src/core/services/mod.rs | 38 +++++++- src/core/whitelist/mod.rs | 8 +- src/servers/http/v1/services/announce.rs | 43 +++++---- src/servers/http/v1/services/scrape.rs | 67 ++++++-------- src/servers/udp/handlers.rs | 109 ++++++++++------------- 6 files changed, 140 insertions(+), 142 deletions(-) diff --git a/src/core/mod.rs b/src/core/mod.rs index 875992da5..5f9d44fdb 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -457,11 +457,9 @@ use std::time::Duration; use auth::PeerKey; use bittorrent_primitives::info_hash::InfoHash; -use databases::driver::Driver; use error::PeerKeyError; use tokio::sync::mpsc::error::SendError; use torrust_tracker_clock::clock::Time; -use torrust_tracker_configuration::v2_0_0::database; use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT}; use torrust_tracker_located_error::Located; use torrust_tracker_primitives::core::{AnnounceData, ScrapeData}; @@ -500,7 +498,7 @@ pub struct Tracker { keys: tokio::sync::RwLock>, /// The list of allowed torrents. Only for listed trackers. - pub whitelist_manager: WhiteListManager, + pub whitelist_manager: Arc, /// The in-memory torrents repository. torrents: Arc, @@ -576,24 +574,19 @@ impl Tracker { /// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence. pub fn new( config: &Core, + database: &Arc>, + whitelist_manager: &Arc, stats_event_sender: Option>, stats_repository: statistics::repository::Repository, ) -> Result { - let driver = match config.database.driver { - database::Driver::Sqlite3 => Driver::Sqlite3, - database::Driver::MySQL => Driver::MySQL, - }; - - let database = Arc::new(databases::driver::build(&driver, &config.database.path)?); - Ok(Tracker { config: config.clone(), + database: database.clone(), keys: tokio::sync::RwLock::new(std::collections::HashMap::new()), - whitelist_manager: WhiteListManager::new(database.clone()), + whitelist_manager: whitelist_manager.clone(), torrents: Arc::default(), stats_event_sender, stats_repository, - database, }) } diff --git a/src/core/services/mod.rs b/src/core/services/mod.rs index 166f40df4..67d5113bc 100644 --- a/src/core/services/mod.rs +++ b/src/core/services/mod.rs @@ -9,8 +9,13 @@ pub mod torrent; use std::sync::Arc; +use databases::driver::Driver; +use torrust_tracker_configuration::v2_0_0::database; use torrust_tracker_configuration::Configuration; +use super::databases::{self, Database}; +use super::whitelist::persisted::DatabaseWhitelist; +use super::whitelist::WhiteListManager; use crate::core::Tracker; /// It returns a new tracker building its dependencies. @@ -20,14 +25,41 @@ use crate::core::Tracker; /// Will panic if tracker cannot be instantiated. #[must_use] pub fn tracker_factory(config: &Configuration) -> Tracker { - // Initialize statistics + let database = initialize_database(config); + + let whitelist_manager = initialize_whitelist(database.clone()); + let (stats_event_sender, stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics); - // Initialize Torrust tracker - match Tracker::new(&Arc::new(config).core, stats_event_sender, stats_repository) { + match Tracker::new( + &Arc::new(config).core, + &database, + &whitelist_manager, + stats_event_sender, + stats_repository, + ) { Ok(tracker) => tracker, Err(error) => { panic!("{}", error) } } } + +/// # Panics +/// +/// Will panic if database cannot be initialized. +#[must_use] +pub fn initialize_database(config: &Configuration) -> Arc> { + let driver = match config.core.database.driver { + database::Driver::Sqlite3 => Driver::Sqlite3, + database::Driver::MySQL => Driver::MySQL, + }; + + Arc::new(databases::driver::build(&driver, &config.core.database.path).expect("Database driver build failed.")) +} + +#[must_use] +pub fn initialize_whitelist(database: Arc>) -> Arc { + let database_whitelist = Arc::new(DatabaseWhitelist::new(database)); + Arc::new(WhiteListManager::new(database_whitelist)) +} diff --git a/src/core/whitelist/mod.rs b/src/core/whitelist/mod.rs index 5096bacc9..3a88b404c 100644 --- a/src/core/whitelist/mod.rs +++ b/src/core/whitelist/mod.rs @@ -7,7 +7,7 @@ use bittorrent_primitives::info_hash::InfoHash; use in_memory::InMemoryWhitelist; use persisted::DatabaseWhitelist; -use super::databases::{self, Database}; +use super::databases::{self}; /// It handles the list of allowed torrents. Only for listed trackers. pub struct WhiteListManager { @@ -15,15 +15,15 @@ pub struct WhiteListManager { in_memory_whitelist: InMemoryWhitelist, /// The persisted list of allowed torrents. - database_whitelist: DatabaseWhitelist, + database_whitelist: Arc, } impl WhiteListManager { #[must_use] - pub fn new(database: Arc>) -> Self { + pub fn new(database_whitelist: Arc) -> Self { Self { in_memory_whitelist: InMemoryWhitelist::default(), - database_whitelist: DatabaseWhitelist::new(database), + database_whitelist, } } diff --git a/src/servers/http/v1/services/announce.rs b/src/servers/http/v1/services/announce.rs index df827aee2..06aad669f 100644 --- a/src/servers/http/v1/services/announce.rs +++ b/src/servers/http/v1/services/announce.rs @@ -107,10 +107,28 @@ mod tests { use torrust_tracker_test_helpers::configuration; use super::{sample_peer_using_ipv4, sample_peer_using_ipv6}; + use crate::core::services::{initialize_database, initialize_whitelist}; use crate::core::{statistics, PeersWanted, Tracker}; use crate::servers::http::v1::services::announce::invoke; use crate::servers::http::v1::services::announce::tests::{public_tracker, sample_info_hash, sample_peer}; + fn test_tracker_factory(stats_event_sender: Option>) -> Tracker { + let config = configuration::ephemeral(); + + let database = initialize_database(&config); + + let whitelist_manager = initialize_whitelist(database.clone()); + + Tracker::new( + &config.core, + &database, + &whitelist_manager, + stats_event_sender, + statistics::repository::Repository::new(), + ) + .unwrap() + } + #[tokio::test] async fn it_should_return_the_announce_data() { let tracker = Arc::new(public_tracker()); @@ -142,14 +160,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - Tracker::new( - &configuration::ephemeral().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let mut peer = sample_peer_using_ipv4(); @@ -162,12 +173,7 @@ mod tests { 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, ))); - Tracker::new( - &configuration.core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap() + test_tracker_factory(Some(stats_event_sender)) } fn peer_with_the_ipv4_loopback_ip() -> peer::Peer { @@ -213,14 +219,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - Tracker::new( - &configuration::ephemeral().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let mut peer = sample_peer_using_ipv6(); diff --git a/src/servers/http/v1/services/scrape.rs b/src/servers/http/v1/services/scrape.rs index 80d81d78a..6ab11bb4a 100644 --- a/src/servers/http/v1/services/scrape.rs +++ b/src/servers/http/v1/services/scrape.rs @@ -67,8 +67,8 @@ mod tests { use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch}; use torrust_tracker_test_helpers::configuration; - use crate::core::services::tracker_factory; - use crate::core::Tracker; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::core::{statistics, Tracker}; fn public_tracker() -> Tracker { tracker_factory(&configuration::ephemeral_public()) @@ -94,6 +94,23 @@ mod tests { } } + fn test_tracker_factory(stats_event_sender: Option>) -> Tracker { + let config = configuration::ephemeral(); + + let database = initialize_database(&config); + + let whitelist_manager = initialize_whitelist(database.clone()); + + Tracker::new( + &config.core, + &database, + &whitelist_manager, + stats_event_sender, + statistics::repository::Repository::new(), + ) + .unwrap() + } + mod with_real_data { use std::future; @@ -103,12 +120,11 @@ mod tests { use mockall::predicate::eq; use torrust_tracker_primitives::core::ScrapeData; use torrust_tracker_primitives::swarm_metadata::SwarmMetadata; - use torrust_tracker_test_helpers::configuration; - use crate::core::{statistics, PeersWanted, Tracker}; + use crate::core::{statistics, PeersWanted}; use crate::servers::http::v1::services::scrape::invoke; use crate::servers::http::v1::services::scrape::tests::{ - public_tracker, sample_info_hash, sample_info_hashes, sample_peer, + public_tracker, sample_info_hash, sample_info_hashes, sample_peer, test_tracker_factory, }; #[tokio::test] @@ -148,14 +164,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - Tracker::new( - &configuration::ephemeral().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let peer_ip = IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)); @@ -172,14 +181,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - Tracker::new( - &configuration::ephemeral().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let peer_ip = IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)); @@ -195,12 +197,11 @@ mod tests { use mockall::predicate::eq; use torrust_tracker_primitives::core::ScrapeData; - use torrust_tracker_test_helpers::configuration; - use crate::core::{statistics, PeersWanted, Tracker}; + use crate::core::{statistics, PeersWanted}; use crate::servers::http::v1::services::scrape::fake; use crate::servers::http::v1::services::scrape::tests::{ - public_tracker, sample_info_hash, sample_info_hashes, sample_peer, + public_tracker, sample_info_hash, sample_info_hashes, sample_peer, test_tracker_factory, }; #[tokio::test] @@ -232,14 +233,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - Tracker::new( - &configuration::ephemeral().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let peer_ip = IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)); @@ -256,14 +250,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - Tracker::new( - &configuration::ephemeral().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let peer_ip = IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969)); diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index 62f7d0a02..5fc695f88 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -435,8 +435,8 @@ mod tests { use torrust_tracker_test_helpers::configuration; use super::gen_remote_fingerprint; - use crate::core::services::tracker_factory; - use crate::core::Tracker; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::core::{statistics, Tracker}; use crate::CurrentClock; fn tracker_configuration() -> Configuration { @@ -553,6 +553,23 @@ mod tests { } } + fn test_tracker_factory(stats_event_sender: Option>) -> Tracker { + let config = tracker_configuration(); + + let database = initialize_database(&config); + + let whitelist_manager = initialize_whitelist(database.clone()); + + Tracker::new( + &config.core, + &database, + &whitelist_manager, + stats_event_sender, + statistics::repository::Repository::new(), + ) + .unwrap() + } + mod connect_request { use std::future; @@ -561,13 +578,13 @@ mod tests { use aquatic_udp_protocol::{ConnectRequest, ConnectResponse, Response, TransactionId}; use mockall::predicate::eq; - use super::{sample_ipv4_socket_address, sample_ipv6_remote_addr, tracker_configuration}; - use crate::core::{self, statistics}; + use super::{sample_ipv4_socket_address, sample_ipv6_remote_addr}; + use crate::core::statistics; use crate::servers::udp::connection_cookie::make; use crate::servers::udp::handlers::handle_connect; use crate::servers::udp::handlers::tests::{ public_tracker, sample_ipv4_remote_addr, sample_ipv4_remote_addr_fingerprint, sample_ipv6_remote_addr_fingerprint, - sample_issue_time, + sample_issue_time, test_tracker_factory, }; fn sample_connect_request() -> ConnectRequest { @@ -639,14 +656,7 @@ mod tests { let client_socket_address = sample_ipv4_socket_address(); - let torrent_tracker = Arc::new( - core::Tracker::new( - &tracker_configuration().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let torrent_tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); handle_connect( client_socket_address, &sample_connect_request(), @@ -666,14 +676,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let torrent_tracker = Arc::new( - core::Tracker::new( - &tracker_configuration().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let torrent_tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); handle_connect( sample_ipv6_remote_addr(), &sample_connect_request(), @@ -774,7 +777,7 @@ mod tests { use crate::servers::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::servers::udp::handlers::tests::{ gen_remote_fingerprint, public_tracker, sample_cookie_valid_range, sample_ipv4_socket_address, sample_issue_time, - tracker_configuration, TorrentPeerBuilder, + test_tracker_factory, TorrentPeerBuilder, }; use crate::servers::udp::handlers::{handle_announce, AnnounceResponseFixedData}; @@ -927,14 +930,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - core::Tracker::new( - &tracker_configuration().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); handle_announce( sample_ipv4_socket_address(), @@ -1013,7 +1009,7 @@ mod tests { use crate::servers::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::servers::udp::handlers::tests::{ gen_remote_fingerprint, public_tracker, sample_cookie_valid_range, sample_ipv6_remote_addr, sample_issue_time, - tracker_configuration, TorrentPeerBuilder, + test_tracker_factory, TorrentPeerBuilder, }; use crate::servers::udp::handlers::{handle_announce, AnnounceResponseFixedData}; @@ -1173,14 +1169,7 @@ mod tests { .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let stats_event_sender = Box::new(stats_event_sender_mock); - let tracker = Arc::new( - core::Tracker::new( - &tracker_configuration().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); let remote_addr = sample_ipv6_remote_addr(); @@ -1200,6 +1189,7 @@ mod tests { use aquatic_udp_protocol::{InfoHash as AquaticInfoHash, PeerId as AquaticPeerId}; use crate::core; + use crate::core::services::{initialize_database, initialize_whitelist}; use crate::core::statistics::keeper::Keeper; use crate::servers::udp::connection_cookie::make; use crate::servers::udp::handlers::handle_announce; @@ -1211,9 +1201,20 @@ mod tests { #[tokio::test] async fn the_peer_ip_should_be_changed_to_the_external_ip_in_the_tracker_configuration() { let configuration = Arc::new(TrackerConfigurationBuilder::default().with_external_ip("::126.0.0.1").into()); + let database = initialize_database(&configuration); + let whitelist_manager = initialize_whitelist(database.clone()); let (stats_event_sender, stats_repository) = Keeper::new_active_instance(); - let tracker = - Arc::new(core::Tracker::new(&configuration.core, Some(stats_event_sender), stats_repository).unwrap()); + + let tracker = Arc::new( + core::Tracker::new( + &configuration.core, + &database, + &whitelist_manager, + Some(stats_event_sender), + stats_repository, + ) + .unwrap(), + ); let loopback_ipv4 = Ipv4Addr::new(127, 0, 0, 1); let loopback_ipv6 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); @@ -1456,10 +1457,10 @@ mod tests { use mockall::predicate::eq; use super::sample_scrape_request; - use crate::core::{self, statistics}; + use crate::core::statistics; use crate::servers::udp::handlers::handle_scrape; use crate::servers::udp::handlers::tests::{ - sample_cookie_valid_range, sample_ipv4_remote_addr, tracker_configuration, + sample_cookie_valid_range, sample_ipv4_remote_addr, test_tracker_factory, }; #[tokio::test] @@ -1473,14 +1474,7 @@ mod tests { let stats_event_sender = Box::new(stats_event_sender_mock); let remote_addr = sample_ipv4_remote_addr(); - let tracker = Arc::new( - core::Tracker::new( - &tracker_configuration().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); handle_scrape( remote_addr, @@ -1500,10 +1494,10 @@ mod tests { use mockall::predicate::eq; use super::sample_scrape_request; - use crate::core::{self, statistics}; + use crate::core::statistics; use crate::servers::udp::handlers::handle_scrape; use crate::servers::udp::handlers::tests::{ - sample_cookie_valid_range, sample_ipv6_remote_addr, tracker_configuration, + sample_cookie_valid_range, sample_ipv6_remote_addr, test_tracker_factory, }; #[tokio::test] @@ -1517,14 +1511,7 @@ mod tests { let stats_event_sender = Box::new(stats_event_sender_mock); let remote_addr = sample_ipv6_remote_addr(); - let tracker = Arc::new( - core::Tracker::new( - &tracker_configuration().core, - Some(stats_event_sender), - statistics::repository::Repository::new(), - ) - .unwrap(), - ); + let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender))); handle_scrape( remote_addr, From 4253d0f7b62d5e8bf9bb1e757ef3b20347992491 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 16:30:18 +0000 Subject: [PATCH 08/11] refactor: [#1182] use WhitelistManager in API handlers directly, instead of using it via the Tracker. --- src/servers/apis/v1/context/whitelist/handlers.rs | 14 +++++++------- src/servers/apis/v1/context/whitelist/routes.rs | 11 +++++++---- src/servers/apis/v1/routes.rs | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/servers/apis/v1/context/whitelist/handlers.rs b/src/servers/apis/v1/context/whitelist/handlers.rs index 04085f8ab..f548f5dc4 100644 --- a/src/servers/apis/v1/context/whitelist/handlers.rs +++ b/src/servers/apis/v1/context/whitelist/handlers.rs @@ -10,7 +10,7 @@ use bittorrent_primitives::info_hash::InfoHash; use super::responses::{ failed_to_reload_whitelist_response, failed_to_remove_torrent_from_whitelist_response, failed_to_whitelist_torrent_response, }; -use crate::core::Tracker; +use crate::core::whitelist::WhiteListManager; use crate::servers::apis::v1::responses::{invalid_info_hash_param_response, ok_response}; use crate::servers::apis::InfoHashParam; @@ -24,12 +24,12 @@ use crate::servers::apis::InfoHashParam; /// Refer to the [API endpoint documentation](crate::servers::apis::v1::context::whitelist#add-a-torrent-to-the-whitelist) /// for more information about this endpoint. pub async fn add_torrent_to_whitelist_handler( - State(tracker): State>, + State(whitelist_manager): State>, Path(info_hash): Path, ) -> Response { match InfoHash::from_str(&info_hash.0) { Err(_) => invalid_info_hash_param_response(&info_hash.0), - Ok(info_hash) => match tracker.add_torrent_to_whitelist(&info_hash).await { + Ok(info_hash) => match whitelist_manager.add_torrent_to_whitelist(&info_hash).await { Ok(()) => ok_response(), Err(e) => failed_to_whitelist_torrent_response(e), }, @@ -47,12 +47,12 @@ pub async fn add_torrent_to_whitelist_handler( /// Refer to the [API endpoint documentation](crate::servers::apis::v1::context::whitelist#remove-a-torrent-from-the-whitelist) /// for more information about this endpoint. pub async fn remove_torrent_from_whitelist_handler( - State(tracker): State>, + State(whitelist_manager): State>, Path(info_hash): Path, ) -> Response { match InfoHash::from_str(&info_hash.0) { Err(_) => invalid_info_hash_param_response(&info_hash.0), - Ok(info_hash) => match tracker.remove_torrent_from_whitelist(&info_hash).await { + Ok(info_hash) => match whitelist_manager.remove_torrent_from_whitelist(&info_hash).await { Ok(()) => ok_response(), Err(e) => failed_to_remove_torrent_from_whitelist_response(e), }, @@ -69,8 +69,8 @@ pub async fn remove_torrent_from_whitelist_handler( /// /// Refer to the [API endpoint documentation](crate::servers::apis::v1::context::whitelist#reload-the-whitelist) /// for more information about this endpoint. -pub async fn reload_whitelist_handler(State(tracker): State>) -> Response { - match tracker.load_whitelist_from_database().await { +pub async fn reload_whitelist_handler(State(whitelist_manager): State>) -> Response { + match whitelist_manager.load_whitelist_from_database().await { Ok(()) => ok_response(), Err(e) => failed_to_reload_whitelist_response(e), } diff --git a/src/servers/apis/v1/context/whitelist/routes.rs b/src/servers/apis/v1/context/whitelist/routes.rs index 35312ea97..c58aa7177 100644 --- a/src/servers/apis/v1/context/whitelist/routes.rs +++ b/src/servers/apis/v1/context/whitelist/routes.rs @@ -14,19 +14,22 @@ use super::handlers::{add_torrent_to_whitelist_handler, reload_whitelist_handler use crate::core::Tracker; /// It adds the routes to the router for the [`whitelist`](crate::servers::apis::v1::context::whitelist) API context. -pub fn add(prefix: &str, router: Router, tracker: Arc) -> Router { +pub fn add(prefix: &str, router: Router, tracker: &Arc) -> Router { let prefix = format!("{prefix}/whitelist"); router // Whitelisted torrents .route( &format!("{prefix}/{{info_hash}}"), - post(add_torrent_to_whitelist_handler).with_state(tracker.clone()), + post(add_torrent_to_whitelist_handler).with_state(tracker.whitelist_manager.clone()), ) .route( &format!("{prefix}/{{info_hash}}"), - delete(remove_torrent_from_whitelist_handler).with_state(tracker.clone()), + delete(remove_torrent_from_whitelist_handler).with_state(tracker.whitelist_manager.clone()), ) // Whitelist commands - .route(&format!("{prefix}/reload"), get(reload_whitelist_handler).with_state(tracker)) + .route( + &format!("{prefix}/reload"), + get(reload_whitelist_handler).with_state(tracker.whitelist_manager.clone()), + ) } diff --git a/src/servers/apis/v1/routes.rs b/src/servers/apis/v1/routes.rs index 23ef6c47e..4c97c7578 100644 --- a/src/servers/apis/v1/routes.rs +++ b/src/servers/apis/v1/routes.rs @@ -14,7 +14,7 @@ pub fn add(prefix: &str, router: Router, tracker: Arc, ban_service: Arc let router = auth_key::routes::add(&v1_prefix, router, tracker.clone()); let router = stats::routes::add(&v1_prefix, router, tracker.clone(), ban_service); - let router = whitelist::routes::add(&v1_prefix, router, tracker.clone()); + let router = whitelist::routes::add(&v1_prefix, router, &tracker); torrent::routes::add(&v1_prefix, router, tracker) } From 658d2be631be303eaaaf4e35260d3bfe0f89769a Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 17:09:56 +0000 Subject: [PATCH 09/11] refactor: [#1182] inject database and whitelist manager in tracker factory Refactor in progress. The final goal is to inject the whitelist manager directly wherever is needed (for example, test evns) to avoid injecting the whole tracker. Adn to finally remove the whitelist manager from the Tracker (A higer level refator in progress: remove responsabilities fromcore Tracker). --- src/bootstrap/app.rs | 8 +++-- src/core/mod.rs | 25 ++++++++++----- src/core/services/mod.rs | 14 ++++----- src/core/services/statistics/mod.rs | 7 +++-- src/core/services/torrent.rs | 39 ++++++++++++++++++------ src/servers/http/v1/handlers/announce.rs | 22 ++++++++++--- src/servers/http/v1/handlers/scrape.rs | 22 ++++++++++--- src/servers/http/v1/services/announce.rs | 7 +++-- src/servers/http/v1/services/scrape.rs | 5 ++- src/servers/udp/handlers.rs | 4 ++- 10 files changed, 112 insertions(+), 41 deletions(-) diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs index 38b7d40c5..9be52359b 100644 --- a/src/bootstrap/app.rs +++ b/src/bootstrap/app.rs @@ -21,7 +21,7 @@ use tracing::instrument; use super::config::initialize_configuration; use crate::bootstrap; -use crate::core::services::tracker_factory; +use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; use crate::core::Tracker; use crate::servers::udp::server::banning::BanService; use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP; @@ -105,7 +105,11 @@ pub fn initialize_static() { #[must_use] #[instrument(skip(config))] pub fn initialize_tracker(config: &Configuration) -> Tracker { - tracker_factory(config) + let database = initialize_database(config); + + let whitelist_manager = initialize_whitelist(database.clone()); + + tracker_factory(config, &database, &whitelist_manager) } /// It initializes the log threshold, format and channel. diff --git a/src/core/mod.rs b/src/core/mod.rs index 5f9d44fdb..51d330880 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1154,25 +1154,36 @@ mod tests { use torrust_tracker_test_helpers::configuration; use crate::core::peer::Peer; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; use crate::core::{TorrentsMetrics, Tracker}; fn public_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_public()) + let config = configuration::ephemeral_public(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn private_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_private()) + let config = configuration::ephemeral_private(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn whitelisted_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_listed()) + let config = configuration::ephemeral_listed(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } pub fn tracker_persisting_torrents_in_database() -> Tracker { - let mut configuration = configuration::ephemeral(); - configuration.core.tracker_policy.persistent_torrent_completed_stat = true; - tracker_factory(&configuration) + let mut config = configuration::ephemeral_listed(); + config.core.tracker_policy.persistent_torrent_completed_stat = true; + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn sample_info_hash() -> InfoHash { diff --git a/src/core/services/mod.rs b/src/core/services/mod.rs index 67d5113bc..a6b5e3371 100644 --- a/src/core/services/mod.rs +++ b/src/core/services/mod.rs @@ -24,17 +24,17 @@ use crate::core::Tracker; /// /// Will panic if tracker cannot be instantiated. #[must_use] -pub fn tracker_factory(config: &Configuration) -> Tracker { - let database = initialize_database(config); - - let whitelist_manager = initialize_whitelist(database.clone()); - +pub fn tracker_factory( + config: &Configuration, + database: &Arc>, + whitelist_manager: &Arc, +) -> Tracker { let (stats_event_sender, stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics); match Tracker::new( &Arc::new(config).core, - &database, - &whitelist_manager, + database, + whitelist_manager, stats_event_sender, stats_repository, ) { diff --git a/src/core/services/statistics/mod.rs b/src/core/services/statistics/mod.rs index 4143aaf1f..2352953eb 100644 --- a/src/core/services/statistics/mod.rs +++ b/src/core/services/statistics/mod.rs @@ -114,7 +114,7 @@ mod tests { use crate::core; use crate::core::services::statistics::{get_metrics, TrackerMetrics}; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; use crate::servers::udp::server::banning::BanService; use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP; @@ -124,7 +124,10 @@ mod tests { #[tokio::test] async fn the_statistics_service_should_return_the_tracker_metrics() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&tracker_configuration(), &database, &whitelist_manager)); let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); let tracker_metrics = get_metrics(tracker.clone(), ban_service.clone()).await; diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs index e63d2efa2..0b89de7ef 100644 --- a/src/core/services/torrent.rs +++ b/src/core/services/torrent.rs @@ -131,7 +131,7 @@ mod tests { use crate::core::services::torrent::tests::sample_peer; use crate::core::services::torrent::{get_torrent_info, Info}; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; pub fn tracker_configuration() -> Configuration { configuration::ephemeral() @@ -139,7 +139,10 @@ mod tests { #[tokio::test] async fn should_return_none_if_the_tracker_does_not_have_the_torrent() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let torrent_info = get_torrent_info( tracker.clone(), @@ -152,7 +155,10 @@ mod tests { #[tokio::test] async fn should_return_the_torrent_info_if_the_tracker_has_the_torrent() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); @@ -184,7 +190,7 @@ mod tests { use crate::core::services::torrent::tests::sample_peer; use crate::core::services::torrent::{get_torrents_page, BasicInfo, Pagination}; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; pub fn tracker_configuration() -> Configuration { configuration::ephemeral() @@ -192,7 +198,10 @@ mod tests { #[tokio::test] async fn should_return_an_empty_result_if_the_tracker_does_not_have_any_torrent() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await; @@ -201,7 +210,10 @@ mod tests { #[tokio::test] async fn should_return_a_summarized_info_for_all_torrents() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); @@ -223,7 +235,10 @@ mod tests { #[tokio::test] async fn should_allow_limiting_the_number_of_torrents_in_the_result() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash1 = InfoHash::from_str(&hash1).unwrap(); @@ -243,7 +258,10 @@ mod tests { #[tokio::test] async fn should_allow_using_pagination_in_the_result() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash1 = InfoHash::from_str(&hash1).unwrap(); @@ -272,7 +290,10 @@ mod tests { #[tokio::test] async fn should_return_torrents_ordered_by_info_hash() { - let tracker = Arc::new(tracker_factory(&tracker_configuration())); + let config = tracker_configuration(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash1 = InfoHash::from_str(&hash1).unwrap(); diff --git a/src/servers/http/v1/handlers/announce.rs b/src/servers/http/v1/handlers/announce.rs index a17e877fa..fc2739db4 100644 --- a/src/servers/http/v1/handlers/announce.rs +++ b/src/servers/http/v1/handlers/announce.rs @@ -185,23 +185,35 @@ mod tests { use bittorrent_primitives::info_hash::InfoHash; use torrust_tracker_test_helpers::configuration; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; use crate::core::Tracker; fn private_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_private()) + let config = configuration::ephemeral_private(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn whitelisted_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_listed()) + let config = configuration::ephemeral_listed(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn tracker_on_reverse_proxy() -> Tracker { - tracker_factory(&configuration::ephemeral_with_reverse_proxy()) + let config = configuration::ephemeral_with_reverse_proxy(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn tracker_not_on_reverse_proxy() -> Tracker { - tracker_factory(&configuration::ephemeral_without_reverse_proxy()) + let config = configuration::ephemeral_without_reverse_proxy(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn sample_announce_request() -> Announce { diff --git a/src/servers/http/v1/handlers/scrape.rs b/src/servers/http/v1/handlers/scrape.rs index 2aa1bd9f8..88d4c92de 100644 --- a/src/servers/http/v1/handlers/scrape.rs +++ b/src/servers/http/v1/handlers/scrape.rs @@ -121,23 +121,35 @@ mod tests { use bittorrent_primitives::info_hash::InfoHash; use torrust_tracker_test_helpers::configuration; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; use crate::core::Tracker; fn private_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_private()) + let config = configuration::ephemeral_private(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn whitelisted_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_listed()) + let config = configuration::ephemeral_listed(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn tracker_on_reverse_proxy() -> Tracker { - tracker_factory(&configuration::ephemeral_with_reverse_proxy()) + let config = configuration::ephemeral_with_reverse_proxy(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn tracker_not_on_reverse_proxy() -> Tracker { - tracker_factory(&configuration::ephemeral_without_reverse_proxy()) + let config = configuration::ephemeral_without_reverse_proxy(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn sample_scrape_request() -> Scrape { diff --git a/src/servers/http/v1/services/announce.rs b/src/servers/http/v1/services/announce.rs index 06aad669f..937560692 100644 --- a/src/servers/http/v1/services/announce.rs +++ b/src/servers/http/v1/services/announce.rs @@ -59,11 +59,14 @@ mod tests { use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch}; use torrust_tracker_test_helpers::configuration; - use crate::core::services::tracker_factory; + use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; use crate::core::Tracker; fn public_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_public()) + let config = configuration::ephemeral_public(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn sample_info_hash() -> InfoHash { diff --git a/src/servers/http/v1/services/scrape.rs b/src/servers/http/v1/services/scrape.rs index 6ab11bb4a..ea2712b6e 100644 --- a/src/servers/http/v1/services/scrape.rs +++ b/src/servers/http/v1/services/scrape.rs @@ -71,7 +71,10 @@ mod tests { use crate::core::{statistics, Tracker}; fn public_tracker() -> Tracker { - tracker_factory(&configuration::ephemeral_public()) + let config = configuration::ephemeral_public(); + let database = initialize_database(&config); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(&config, &database, &whitelist_manager) } fn sample_info_hashes() -> Vec { diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index 5fc695f88..6110af530 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -456,7 +456,9 @@ mod tests { } fn initialized_tracker(configuration: &Configuration) -> Arc { - tracker_factory(configuration).into() + let database = initialize_database(configuration); + let whitelist_manager = initialize_whitelist(database.clone()); + tracker_factory(configuration, &database, &whitelist_manager).into() } fn sample_ipv4_remote_addr() -> SocketAddr { From 882af33a179290a817a532a8eeaf7d3d4b9979c6 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 17:25:21 +0000 Subject: [PATCH 10/11] refactor: [#1182] remove duplicate code --- src/bootstrap/app.rs | 12 +++++++++-- src/core/mod.rs | 15 ++++++------- src/core/services/statistics/mod.rs | 6 +++--- src/core/services/torrent.rs | 27 ++++++++++-------------- src/servers/http/v1/handlers/announce.rs | 15 ++++++------- src/servers/http/v1/handlers/scrape.rs | 15 ++++++------- src/servers/http/v1/services/announce.rs | 12 +++++------ src/servers/http/v1/services/scrape.rs | 10 ++++----- src/servers/udp/handlers.rs | 23 +++++++++----------- 9 files changed, 61 insertions(+), 74 deletions(-) diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs index 9be52359b..788037b0b 100644 --- a/src/bootstrap/app.rs +++ b/src/bootstrap/app.rs @@ -21,7 +21,9 @@ use tracing::instrument; use super::config::initialize_configuration; use crate::bootstrap; +use crate::core::databases::Database; use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; +use crate::core::whitelist::WhiteListManager; use crate::core::Tracker; use crate::servers::udp::server::banning::BanService; use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP; @@ -105,11 +107,17 @@ pub fn initialize_static() { #[must_use] #[instrument(skip(config))] pub fn initialize_tracker(config: &Configuration) -> Tracker { - let database = initialize_database(config); + let (database, whitelist_manager) = initialize_tracker_dependencies(config); + + tracker_factory(config, &database, &whitelist_manager) +} +#[must_use] +pub fn initialize_tracker_dependencies(config: &Configuration) -> (Arc>, Arc) { + let database = initialize_database(config); let whitelist_manager = initialize_whitelist(database.clone()); - tracker_factory(config, &database, &whitelist_manager) + (database, whitelist_manager) } /// It initializes the log threshold, format and channel. diff --git a/src/core/mod.rs b/src/core/mod.rs index 51d330880..c8bb7f6a9 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1153,36 +1153,33 @@ mod tests { use torrust_tracker_primitives::DurationSinceUnixEpoch; use torrust_tracker_test_helpers::configuration; + use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core::peer::Peer; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::core::services::tracker_factory; use crate::core::{TorrentsMetrics, Tracker}; fn public_tracker() -> Tracker { let config = configuration::ephemeral_public(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn private_tracker() -> Tracker { let config = configuration::ephemeral_private(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn whitelisted_tracker() -> Tracker { let config = configuration::ephemeral_listed(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } pub fn tracker_persisting_torrents_in_database() -> Tracker { let mut config = configuration::ephemeral_listed(); config.core.tracker_policy.persistent_torrent_completed_stat = true; - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } diff --git a/src/core/services/statistics/mod.rs b/src/core/services/statistics/mod.rs index 2352953eb..d4e77ce4c 100644 --- a/src/core/services/statistics/mod.rs +++ b/src/core/services/statistics/mod.rs @@ -112,9 +112,10 @@ mod tests { use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics; use torrust_tracker_test_helpers::configuration; + use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core; use crate::core::services::statistics::{get_metrics, TrackerMetrics}; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::core::services::tracker_factory; use crate::servers::udp::server::banning::BanService; use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP; @@ -125,8 +126,7 @@ mod tests { #[tokio::test] async fn the_statistics_service_should_return_the_tracker_metrics() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&tracker_configuration(), &database, &whitelist_manager)); let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs index 0b89de7ef..1be2acc93 100644 --- a/src/core/services/torrent.rs +++ b/src/core/services/torrent.rs @@ -129,9 +129,10 @@ mod tests { use torrust_tracker_configuration::Configuration; use torrust_tracker_test_helpers::configuration; + use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core::services::torrent::tests::sample_peer; use crate::core::services::torrent::{get_torrent_info, Info}; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::core::services::tracker_factory; pub fn tracker_configuration() -> Configuration { configuration::ephemeral() @@ -140,8 +141,7 @@ mod tests { #[tokio::test] async fn should_return_none_if_the_tracker_does_not_have_the_torrent() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let torrent_info = get_torrent_info( @@ -156,8 +156,7 @@ mod tests { #[tokio::test] async fn should_return_the_torrent_info_if_the_tracker_has_the_torrent() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); @@ -188,9 +187,10 @@ mod tests { use torrust_tracker_configuration::Configuration; use torrust_tracker_test_helpers::configuration; + use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core::services::torrent::tests::sample_peer; use crate::core::services::torrent::{get_torrents_page, BasicInfo, Pagination}; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::core::services::tracker_factory; pub fn tracker_configuration() -> Configuration { configuration::ephemeral() @@ -199,8 +199,7 @@ mod tests { #[tokio::test] async fn should_return_an_empty_result_if_the_tracker_does_not_have_any_torrent() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await; @@ -211,8 +210,7 @@ mod tests { #[tokio::test] async fn should_return_a_summarized_info_for_all_torrents() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); @@ -236,8 +234,7 @@ mod tests { #[tokio::test] async fn should_allow_limiting_the_number_of_torrents_in_the_result() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); @@ -259,8 +256,7 @@ mod tests { #[tokio::test] async fn should_allow_using_pagination_in_the_result() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); @@ -291,8 +287,7 @@ mod tests { #[tokio::test] async fn should_return_torrents_ordered_by_info_hash() { let config = tracker_configuration(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let tracker = Arc::new(tracker_factory(&config, &database, &whitelist_manager)); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); diff --git a/src/servers/http/v1/handlers/announce.rs b/src/servers/http/v1/handlers/announce.rs index fc2739db4..df4658420 100644 --- a/src/servers/http/v1/handlers/announce.rs +++ b/src/servers/http/v1/handlers/announce.rs @@ -185,34 +185,31 @@ mod tests { use bittorrent_primitives::info_hash::InfoHash; use torrust_tracker_test_helpers::configuration; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::bootstrap::app::initialize_tracker_dependencies; + use crate::core::services::tracker_factory; use crate::core::Tracker; fn private_tracker() -> Tracker { let config = configuration::ephemeral_private(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn whitelisted_tracker() -> Tracker { let config = configuration::ephemeral_listed(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn tracker_on_reverse_proxy() -> Tracker { let config = configuration::ephemeral_with_reverse_proxy(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn tracker_not_on_reverse_proxy() -> Tracker { let config = configuration::ephemeral_without_reverse_proxy(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } diff --git a/src/servers/http/v1/handlers/scrape.rs b/src/servers/http/v1/handlers/scrape.rs index 88d4c92de..dd144d898 100644 --- a/src/servers/http/v1/handlers/scrape.rs +++ b/src/servers/http/v1/handlers/scrape.rs @@ -121,34 +121,31 @@ mod tests { use bittorrent_primitives::info_hash::InfoHash; use torrust_tracker_test_helpers::configuration; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::bootstrap::app::initialize_tracker_dependencies; + use crate::core::services::tracker_factory; use crate::core::Tracker; fn private_tracker() -> Tracker { let config = configuration::ephemeral_private(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn whitelisted_tracker() -> Tracker { let config = configuration::ephemeral_listed(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn tracker_on_reverse_proxy() -> Tracker { let config = configuration::ephemeral_with_reverse_proxy(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } fn tracker_not_on_reverse_proxy() -> Tracker { let config = configuration::ephemeral_without_reverse_proxy(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } diff --git a/src/servers/http/v1/services/announce.rs b/src/servers/http/v1/services/announce.rs index 937560692..f19c69c2f 100644 --- a/src/servers/http/v1/services/announce.rs +++ b/src/servers/http/v1/services/announce.rs @@ -59,13 +59,13 @@ mod tests { use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch}; use torrust_tracker_test_helpers::configuration; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::bootstrap::app::initialize_tracker_dependencies; + use crate::core::services::tracker_factory; use crate::core::Tracker; fn public_tracker() -> Tracker { let config = configuration::ephemeral_public(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } @@ -110,7 +110,7 @@ mod tests { use torrust_tracker_test_helpers::configuration; use super::{sample_peer_using_ipv4, sample_peer_using_ipv6}; - use crate::core::services::{initialize_database, initialize_whitelist}; + use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core::{statistics, PeersWanted, Tracker}; use crate::servers::http::v1::services::announce::invoke; use crate::servers::http::v1::services::announce::tests::{public_tracker, sample_info_hash, sample_peer}; @@ -118,9 +118,7 @@ mod tests { fn test_tracker_factory(stats_event_sender: Option>) -> Tracker { let config = configuration::ephemeral(); - let database = initialize_database(&config); - - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); Tracker::new( &config.core, diff --git a/src/servers/http/v1/services/scrape.rs b/src/servers/http/v1/services/scrape.rs index ea2712b6e..0a96031a0 100644 --- a/src/servers/http/v1/services/scrape.rs +++ b/src/servers/http/v1/services/scrape.rs @@ -67,13 +67,13 @@ mod tests { use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch}; use torrust_tracker_test_helpers::configuration; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::bootstrap::app::initialize_tracker_dependencies; + use crate::core::services::tracker_factory; use crate::core::{statistics, Tracker}; fn public_tracker() -> Tracker { let config = configuration::ephemeral_public(); - let database = initialize_database(&config); - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); tracker_factory(&config, &database, &whitelist_manager) } @@ -100,9 +100,7 @@ mod tests { fn test_tracker_factory(stats_event_sender: Option>) -> Tracker { let config = configuration::ephemeral(); - let database = initialize_database(&config); - - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); Tracker::new( &config.core, diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index 6110af530..292ccfd3a 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -435,7 +435,8 @@ mod tests { use torrust_tracker_test_helpers::configuration; use super::gen_remote_fingerprint; - use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory}; + use crate::bootstrap::app::initialize_tracker_dependencies; + use crate::core::services::tracker_factory; use crate::core::{statistics, Tracker}; use crate::CurrentClock; @@ -455,10 +456,9 @@ mod tests { initialized_tracker(&configuration::ephemeral_listed()) } - fn initialized_tracker(configuration: &Configuration) -> Arc { - let database = initialize_database(configuration); - let whitelist_manager = initialize_whitelist(database.clone()); - tracker_factory(configuration, &database, &whitelist_manager).into() + fn initialized_tracker(config: &Configuration) -> Arc { + let (database, whitelist_manager) = initialize_tracker_dependencies(config); + tracker_factory(config, &database, &whitelist_manager).into() } fn sample_ipv4_remote_addr() -> SocketAddr { @@ -558,9 +558,7 @@ mod tests { fn test_tracker_factory(stats_event_sender: Option>) -> Tracker { let config = tracker_configuration(); - let database = initialize_database(&config); - - let whitelist_manager = initialize_whitelist(database.clone()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); Tracker::new( &config.core, @@ -1190,8 +1188,8 @@ mod tests { use aquatic_udp_protocol::{InfoHash as AquaticInfoHash, PeerId as AquaticPeerId}; + use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core; - use crate::core::services::{initialize_database, initialize_whitelist}; use crate::core::statistics::keeper::Keeper; use crate::servers::udp::connection_cookie::make; use crate::servers::udp::handlers::handle_announce; @@ -1202,14 +1200,13 @@ mod tests { #[tokio::test] async fn the_peer_ip_should_be_changed_to_the_external_ip_in_the_tracker_configuration() { - let configuration = Arc::new(TrackerConfigurationBuilder::default().with_external_ip("::126.0.0.1").into()); - let database = initialize_database(&configuration); - let whitelist_manager = initialize_whitelist(database.clone()); + let config = Arc::new(TrackerConfigurationBuilder::default().with_external_ip("::126.0.0.1").into()); + let (database, whitelist_manager) = initialize_tracker_dependencies(&config); let (stats_event_sender, stats_repository) = Keeper::new_active_instance(); let tracker = Arc::new( core::Tracker::new( - &configuration.core, + &config.core, &database, &whitelist_manager, Some(stats_event_sender), From 57455cabc88556b432a9eaf15f360ca8f428d0f2 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 15 Jan 2025 17:51:12 +0000 Subject: [PATCH 11/11] refactor: [#1182] remove whitelist context methods from core tracker --- src/app.rs | 1 + src/core/mod.rs | 95 ++++++------------- tests/servers/api/environment.rs | 8 ++ .../api/v1/contract/context/whitelist.rs | 16 ++-- tests/servers/http/environment.rs | 7 ++ tests/servers/http/v1/contract.rs | 4 +- 6 files changed, 55 insertions(+), 76 deletions(-) diff --git a/src/app.rs b/src/app.rs index abfe75256..1cfc57c2e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -67,6 +67,7 @@ pub async fn start( // Load whitelisted torrents if tracker.is_listed() { tracker + .whitelist_manager .load_whitelist_from_database() .await .expect("Could not load whitelist from database."); diff --git a/src/core/mod.rs b/src/core/mod.rs index c8bb7f6a9..f142fa26e 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1044,7 +1044,7 @@ impl Tracker { return Ok(()); } - if self.is_info_hash_whitelisted(info_hash).await { + if self.whitelist_manager.is_info_hash_whitelisted(info_hash).await { return Ok(()); } @@ -1054,48 +1054,6 @@ impl Tracker { }) } - /// It adds a torrent to the whitelist. - /// Adding torrents is not relevant to public trackers. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database. - pub async fn add_torrent_to_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.whitelist_manager.add_torrent_to_whitelist(info_hash).await - } - - /// It removes a torrent from the whitelist. - /// Removing torrents is not relevant to public trackers. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. - pub async fn remove_torrent_from_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.whitelist_manager.remove_torrent_from_whitelist(info_hash).await - } - - /// It checks if a torrent is whitelisted. - /// - /// # Context: Whitelist - pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { - self.whitelist_manager.is_info_hash_whitelisted(info_hash).await - } - - /// It loads the whitelist from the database. - /// - /// # Context: Whitelist - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database. - pub async fn load_whitelist_from_database(&self) -> Result<(), databases::error::Error> { - self.whitelist_manager.load_whitelist_from_database().await - } - /// It return the `Tracker` [`statistics::metrics::Metrics`]. /// /// # Context: Statistics @@ -1156,6 +1114,7 @@ mod tests { use crate::bootstrap::app::initialize_tracker_dependencies; use crate::core::peer::Peer; use crate::core::services::tracker_factory; + use crate::core::whitelist::WhiteListManager; use crate::core::{TorrentsMetrics, Tracker}; fn public_tracker() -> Tracker { @@ -1170,10 +1129,12 @@ mod tests { tracker_factory(&config, &database, &whitelist_manager) } - fn whitelisted_tracker() -> Tracker { + fn whitelisted_tracker() -> (Tracker, Arc) { let config = configuration::ephemeral_listed(); let (database, whitelist_manager) = initialize_tracker_dependencies(&config); - tracker_factory(&config, &database, &whitelist_manager) + let tracker = tracker_factory(&config, &database, &whitelist_manager); + + (tracker, whitelist_manager) } pub fn tracker_persisting_torrents_in_database() -> Tracker { @@ -1707,11 +1668,11 @@ mod tests { #[tokio::test] async fn it_should_authorize_the_announce_and_scrape_actions_on_whitelisted_torrents() { - let tracker = whitelisted_tracker(); + let (tracker, whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); - let result = tracker.add_torrent_to_whitelist(&info_hash).await; + let result = whitelist_manager.add_torrent_to_whitelist(&info_hash).await; assert!(result.is_ok()); let result = tracker.authorize(&info_hash).await; @@ -1720,7 +1681,7 @@ mod tests { #[tokio::test] async fn it_should_not_authorize_the_announce_and_scrape_actions_on_not_whitelisted_torrents() { - let tracker = whitelisted_tracker(); + let (tracker, _whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); @@ -1732,28 +1693,33 @@ mod tests { mod handling_the_torrent_whitelist { use crate::core::tests::the_tracker::{sample_info_hash, whitelisted_tracker}; + // todo: after extracting the WhitelistManager from the Tracker, + // there is no need to use the tracker to test the whitelist. + // Test not using the `tracker` (`_tracker` variable) should be + // moved to the whitelist module. + #[tokio::test] async fn it_should_add_a_torrent_to_the_whitelist() { - let tracker = whitelisted_tracker(); + let (_tracker, whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); - tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); - assert!(tracker.is_info_hash_whitelisted(&info_hash).await); + assert!(whitelist_manager.is_info_hash_whitelisted(&info_hash).await); } #[tokio::test] async fn it_should_remove_a_torrent_from_the_whitelist() { - let tracker = whitelisted_tracker(); + let (_tracker, whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); - tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); - tracker.remove_torrent_from_whitelist(&info_hash).await.unwrap(); + whitelist_manager.remove_torrent_from_whitelist(&info_hash).await.unwrap(); - assert!(!tracker.is_info_hash_whitelisted(&info_hash).await); + assert!(!whitelist_manager.is_info_hash_whitelisted(&info_hash).await); } mod persistence { @@ -1761,22 +1727,19 @@ mod tests { #[tokio::test] async fn it_should_load_the_whitelist_from_the_database() { - let tracker = whitelisted_tracker(); + let (_tracker, whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); - tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); + + whitelist_manager.remove_torrent_from_memory_whitelist(&info_hash).await; - // Remove torrent from the in-memory whitelist - tracker - .whitelist_manager - .remove_torrent_from_memory_whitelist(&info_hash) - .await; - assert!(!tracker.is_info_hash_whitelisted(&info_hash).await); + assert!(!whitelist_manager.is_info_hash_whitelisted(&info_hash).await); - tracker.load_whitelist_from_database().await.unwrap(); + whitelist_manager.load_whitelist_from_database().await.unwrap(); - assert!(tracker.is_info_hash_whitelisted(&info_hash).await); + assert!(whitelist_manager.is_info_hash_whitelisted(&info_hash).await); } } } @@ -1807,7 +1770,7 @@ mod tests { #[tokio::test] async fn it_should_return_the_zeroed_swarm_metadata_for_the_requested_file_if_it_is_not_whitelisted() { - let tracker = whitelisted_tracker(); + let (tracker, _whitelist_manager) = whitelisted_tracker(); let info_hash = "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0".parse::().unwrap(); diff --git a/tests/servers/api/environment.rs b/tests/servers/api/environment.rs index 70f2d4c65..37d031e1c 100644 --- a/tests/servers/api/environment.rs +++ b/tests/servers/api/environment.rs @@ -8,6 +8,7 @@ use torrust_tracker_api_client::connection_info::{ConnectionInfo, Origin}; use torrust_tracker_configuration::{Configuration, HttpApi}; use torrust_tracker_lib::bootstrap::app::initialize_with_configuration; use torrust_tracker_lib::bootstrap::jobs::make_rust_tls; +use torrust_tracker_lib::core::whitelist::WhiteListManager; use torrust_tracker_lib::core::Tracker; use torrust_tracker_lib::servers::apis::server::{ApiServer, Launcher, Running, Stopped}; use torrust_tracker_lib::servers::registar::Registar; @@ -21,6 +22,7 @@ where { pub config: Arc, pub tracker: Arc, + pub whitelist_manager: Arc, pub ban_service: Arc>, pub registar: Registar, pub server: ApiServer, @@ -40,6 +42,9 @@ impl Environment { pub fn new(configuration: &Arc) -> Self { let tracker = initialize_with_configuration(configuration); + // todo: get from `initialize_with_configuration` + let whitelist_manager = tracker.whitelist_manager.clone(); + let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); let config = Arc::new(configuration.http_api.clone().expect("missing API configuration")); @@ -53,6 +58,7 @@ impl Environment { Self { config, tracker, + whitelist_manager, ban_service, registar: Registar::default(), server, @@ -65,6 +71,7 @@ impl Environment { Environment { config: self.config, tracker: self.tracker.clone(), + whitelist_manager: self.whitelist_manager.clone(), ban_service: self.ban_service.clone(), registar: self.registar.clone(), server: self @@ -85,6 +92,7 @@ impl Environment { Environment { config: self.config, tracker: self.tracker, + whitelist_manager: self.whitelist_manager, ban_service: self.ban_service, registar: Registar::default(), server: self.server.stop().await.unwrap(), diff --git a/tests/servers/api/v1/contract/context/whitelist.rs b/tests/servers/api/v1/contract/context/whitelist.rs index 6dde663a5..aef1db4f1 100644 --- a/tests/servers/api/v1/contract/context/whitelist.rs +++ b/tests/servers/api/v1/contract/context/whitelist.rs @@ -31,7 +31,7 @@ async fn should_allow_whitelisting_a_torrent() { assert_ok(response).await; assert!( - env.tracker + env.whitelist_manager .is_info_hash_whitelisted(&InfoHash::from_str(&info_hash).unwrap()) .await ); @@ -167,7 +167,7 @@ async fn should_allow_removing_a_torrent_from_the_whitelist() { let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); - env.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); let request_id = Uuid::new_v4(); @@ -176,7 +176,7 @@ async fn should_allow_removing_a_torrent_from_the_whitelist() { .await; assert_ok(response).await; - assert!(!env.tracker.is_info_hash_whitelisted(&info_hash).await); + assert!(!env.whitelist_manager.is_info_hash_whitelisted(&info_hash).await); env.stop().await; } @@ -237,7 +237,7 @@ async fn should_fail_when_the_torrent_cannot_be_removed_from_the_whitelist() { let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); - env.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); force_database_error(&env.tracker); @@ -266,7 +266,7 @@ async fn should_not_allow_removing_a_torrent_from_the_whitelist_for_unauthentica let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); - env.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); let request_id = Uuid::new_v4(); @@ -281,7 +281,7 @@ async fn should_not_allow_removing_a_torrent_from_the_whitelist_for_unauthentica "Expected logs to contain: ERROR ... API ... request_id={request_id}" ); - env.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); let request_id = Uuid::new_v4(); @@ -307,7 +307,7 @@ async fn should_allow_reload_the_whitelist_from_the_database() { let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); - env.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); let request_id = Uuid::new_v4(); @@ -338,7 +338,7 @@ async fn should_fail_when_the_whitelist_cannot_be_reloaded_from_the_database() { let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); - env.tracker.add_torrent_to_whitelist(&info_hash).await.unwrap(); + env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); force_database_error(&env.tracker); diff --git a/tests/servers/http/environment.rs b/tests/servers/http/environment.rs index d615d7eaf..6d4001e6c 100644 --- a/tests/servers/http/environment.rs +++ b/tests/servers/http/environment.rs @@ -5,6 +5,7 @@ use futures::executor::block_on; use torrust_tracker_configuration::{Configuration, HttpTracker}; use torrust_tracker_lib::bootstrap::app::initialize_with_configuration; use torrust_tracker_lib::bootstrap::jobs::make_rust_tls; +use torrust_tracker_lib::core::whitelist::WhiteListManager; use torrust_tracker_lib::core::Tracker; use torrust_tracker_lib::servers::http::server::{HttpServer, Launcher, Running, Stopped}; use torrust_tracker_lib::servers::registar::Registar; @@ -13,6 +14,7 @@ use torrust_tracker_primitives::peer; pub struct Environment { pub config: Arc, pub tracker: Arc, + pub whitelist_manager: Arc, pub registar: Registar, pub server: HttpServer, } @@ -29,6 +31,8 @@ impl Environment { pub fn new(configuration: &Arc) -> Self { let tracker = initialize_with_configuration(configuration); + let whitelist_manager = tracker.whitelist_manager.clone(); + let http_tracker = configuration .http_trackers .clone() @@ -45,6 +49,7 @@ impl Environment { Self { config, tracker, + whitelist_manager, registar: Registar::default(), server, } @@ -55,6 +60,7 @@ impl Environment { Environment { config: self.config, tracker: self.tracker.clone(), + whitelist_manager: self.whitelist_manager.clone(), registar: self.registar.clone(), server: self.server.start(self.tracker, self.registar.give_form()).await.unwrap(), } @@ -70,6 +76,7 @@ impl Environment { Environment { config: self.config, tracker: self.tracker, + whitelist_manager: self.whitelist_manager, registar: Registar::default(), server: self.server.stop().await.unwrap(), diff --git a/tests/servers/http/v1/contract.rs b/tests/servers/http/v1/contract.rs index db03f526e..37d0288f4 100644 --- a/tests/servers/http/v1/contract.rs +++ b/tests/servers/http/v1/contract.rs @@ -1261,7 +1261,7 @@ mod configured_as_whitelisted { let info_hash = InfoHash::from_str("9c38422213e30bff212b30c360d26f9a02136422").unwrap(); - env.tracker + env.whitelist_manager .add_torrent_to_whitelist(&info_hash) .await .expect("should add the torrent to the whitelist"); @@ -1343,7 +1343,7 @@ mod configured_as_whitelisted { .build(), ); - env.tracker + env.whitelist_manager .add_torrent_to_whitelist(&info_hash) .await .expect("should add the torrent to the whitelist");