@@ -445,6 +445,7 @@ pub mod error;
445
445
pub mod services;
446
446
pub mod statistics;
447
447
pub mod torrent;
448
+ pub mod whitelist;
448
449
449
450
pub mod peer_tests;
450
451
@@ -456,11 +457,9 @@ use std::time::Duration;
456
457
457
458
use auth:: PeerKey ;
458
459
use bittorrent_primitives:: info_hash:: InfoHash ;
459
- use databases:: driver:: Driver ;
460
460
use error:: PeerKeyError ;
461
461
use tokio:: sync:: mpsc:: error:: SendError ;
462
462
use torrust_tracker_clock:: clock:: Time ;
463
- use torrust_tracker_configuration:: v2_0_0:: database;
464
463
use torrust_tracker_configuration:: { AnnouncePolicy , Core , TORRENT_PEERS_LIMIT } ;
465
464
use torrust_tracker_located_error:: Located ;
466
465
use torrust_tracker_primitives:: core:: { AnnounceData , ScrapeData } ;
@@ -470,6 +469,7 @@ use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
470
469
use torrust_tracker_torrent_repository:: entry:: EntrySync ;
471
470
use torrust_tracker_torrent_repository:: repository:: Repository ;
472
471
use tracing:: instrument;
472
+ use whitelist:: WhiteListManager ;
473
473
474
474
use self :: auth:: Key ;
475
475
use self :: error:: Error ;
@@ -498,7 +498,7 @@ pub struct Tracker {
498
498
keys : tokio:: sync:: RwLock < std:: collections:: HashMap < Key , auth:: PeerKey > > ,
499
499
500
500
/// The list of allowed torrents. Only for listed trackers.
501
- whitelist : tokio :: sync :: RwLock < std :: collections :: HashSet < InfoHash > > ,
501
+ pub whitelist_manager : Arc < WhiteListManager > ,
502
502
503
503
/// The in-memory torrents repository.
504
504
torrents : Arc < Torrents > ,
@@ -574,24 +574,19 @@ impl Tracker {
574
574
/// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
575
575
pub fn new (
576
576
config : & Core ,
577
+ database : & Arc < Box < dyn Database > > ,
578
+ whitelist_manager : & Arc < WhiteListManager > ,
577
579
stats_event_sender : Option < Box < dyn statistics:: event:: sender:: Sender > > ,
578
580
stats_repository : statistics:: repository:: Repository ,
579
581
) -> Result < Tracker , databases:: error:: Error > {
580
- let driver = match config. database . driver {
581
- database:: Driver :: Sqlite3 => Driver :: Sqlite3 ,
582
- database:: Driver :: MySQL => Driver :: MySQL ,
583
- } ;
584
-
585
- let database = Arc :: new ( databases:: driver:: build ( & driver, & config. database . path ) ?) ;
586
-
587
582
Ok ( Tracker {
588
583
config : config. clone ( ) ,
584
+ database : database. clone ( ) ,
589
585
keys : tokio:: sync:: RwLock :: new ( std:: collections:: HashMap :: new ( ) ) ,
590
- whitelist : tokio :: sync :: RwLock :: new ( std :: collections :: HashSet :: new ( ) ) ,
586
+ whitelist_manager : whitelist_manager . clone ( ) ,
591
587
torrents : Arc :: default ( ) ,
592
588
stats_event_sender,
593
589
stats_repository,
594
- database,
595
590
} )
596
591
}
597
592
@@ -1049,7 +1044,7 @@ impl Tracker {
1049
1044
return Ok ( ( ) ) ;
1050
1045
}
1051
1046
1052
- if self . is_info_hash_whitelisted ( info_hash) . await {
1047
+ if self . whitelist_manager . is_info_hash_whitelisted ( info_hash) . await {
1053
1048
return Ok ( ( ) ) ;
1054
1049
}
1055
1050
@@ -1059,104 +1054,6 @@ impl Tracker {
1059
1054
} )
1060
1055
}
1061
1056
1062
- /// It adds a torrent to the whitelist.
1063
- /// Adding torrents is not relevant to public trackers.
1064
- ///
1065
- /// # Context: Whitelist
1066
- ///
1067
- /// # Errors
1068
- ///
1069
- /// Will return a `database::Error` if unable to add the `info_hash` into the whitelist database.
1070
- pub async fn add_torrent_to_whitelist ( & self , info_hash : & InfoHash ) -> Result < ( ) , databases:: error:: Error > {
1071
- self . add_torrent_to_database_whitelist ( info_hash) ?;
1072
- self . add_torrent_to_memory_whitelist ( info_hash) . await ;
1073
- Ok ( ( ) )
1074
- }
1075
-
1076
- /// It adds a torrent to the whitelist if it has not been whitelisted previously
1077
- fn add_torrent_to_database_whitelist ( & self , info_hash : & InfoHash ) -> Result < ( ) , databases:: error:: Error > {
1078
- let is_whitelisted = self . database . is_info_hash_whitelisted ( * info_hash) ?;
1079
-
1080
- if is_whitelisted {
1081
- return Ok ( ( ) ) ;
1082
- }
1083
-
1084
- self . database . add_info_hash_to_whitelist ( * info_hash) ?;
1085
-
1086
- Ok ( ( ) )
1087
- }
1088
-
1089
- pub async fn add_torrent_to_memory_whitelist ( & self , info_hash : & InfoHash ) -> bool {
1090
- self . whitelist . write ( ) . await . insert ( * info_hash)
1091
- }
1092
-
1093
- /// It removes a torrent from the whitelist.
1094
- /// Removing torrents is not relevant to public trackers.
1095
- ///
1096
- /// # Context: Whitelist
1097
- ///
1098
- /// # Errors
1099
- ///
1100
- /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database.
1101
- pub async fn remove_torrent_from_whitelist ( & self , info_hash : & InfoHash ) -> Result < ( ) , databases:: error:: Error > {
1102
- self . remove_torrent_from_database_whitelist ( info_hash) ?;
1103
- self . remove_torrent_from_memory_whitelist ( info_hash) . await ;
1104
- Ok ( ( ) )
1105
- }
1106
-
1107
- /// It removes a torrent from the whitelist in the database.
1108
- ///
1109
- /// # Context: Whitelist
1110
- ///
1111
- /// # Errors
1112
- ///
1113
- /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database.
1114
- pub fn remove_torrent_from_database_whitelist ( & self , info_hash : & InfoHash ) -> Result < ( ) , databases:: error:: Error > {
1115
- let is_whitelisted = self . database . is_info_hash_whitelisted ( * info_hash) ?;
1116
-
1117
- if !is_whitelisted {
1118
- return Ok ( ( ) ) ;
1119
- }
1120
-
1121
- self . database . remove_info_hash_from_whitelist ( * info_hash) ?;
1122
-
1123
- Ok ( ( ) )
1124
- }
1125
-
1126
- /// It removes a torrent from the whitelist in memory.
1127
- ///
1128
- /// # Context: Whitelist
1129
- pub async fn remove_torrent_from_memory_whitelist ( & self , info_hash : & InfoHash ) -> bool {
1130
- self . whitelist . write ( ) . await . remove ( info_hash)
1131
- }
1132
-
1133
- /// It checks if a torrent is whitelisted.
1134
- ///
1135
- /// # Context: Whitelist
1136
- pub async fn is_info_hash_whitelisted ( & self , info_hash : & InfoHash ) -> bool {
1137
- self . whitelist . read ( ) . await . contains ( info_hash)
1138
- }
1139
-
1140
- /// It loads the whitelist from the database.
1141
- ///
1142
- /// # Context: Whitelist
1143
- ///
1144
- /// # Errors
1145
- ///
1146
- /// Will return a `database::Error` if unable to load the list whitelisted `info_hash`s from the database.
1147
- pub async fn load_whitelist_from_database ( & self ) -> Result < ( ) , databases:: error:: Error > {
1148
- let whitelisted_torrents_from_database = self . database . load_whitelist ( ) ?;
1149
- let mut whitelist = self . whitelist . write ( ) . await ;
1150
-
1151
- whitelist. clear ( ) ;
1152
-
1153
- for info_hash in whitelisted_torrents_from_database {
1154
- let _: bool = whitelist. insert ( info_hash) ;
1155
- }
1156
-
1157
- Ok ( ( ) )
1158
- }
1159
-
1160
1057
/// It return the `Tracker` [`statistics::metrics::Metrics`].
1161
1058
///
1162
1059
/// # Context: Statistics
@@ -1214,26 +1111,37 @@ mod tests {
1214
1111
use torrust_tracker_primitives:: DurationSinceUnixEpoch ;
1215
1112
use torrust_tracker_test_helpers:: configuration;
1216
1113
1114
+ use crate :: bootstrap:: app:: initialize_tracker_dependencies;
1217
1115
use crate :: core:: peer:: Peer ;
1218
1116
use crate :: core:: services:: tracker_factory;
1117
+ use crate :: core:: whitelist:: WhiteListManager ;
1219
1118
use crate :: core:: { TorrentsMetrics , Tracker } ;
1220
1119
1221
1120
fn public_tracker ( ) -> Tracker {
1222
- tracker_factory ( & configuration:: ephemeral_public ( ) )
1121
+ let config = configuration:: ephemeral_public ( ) ;
1122
+ let ( database, whitelist_manager) = initialize_tracker_dependencies ( & config) ;
1123
+ tracker_factory ( & config, & database, & whitelist_manager)
1223
1124
}
1224
1125
1225
1126
fn private_tracker ( ) -> Tracker {
1226
- tracker_factory ( & configuration:: ephemeral_private ( ) )
1127
+ let config = configuration:: ephemeral_private ( ) ;
1128
+ let ( database, whitelist_manager) = initialize_tracker_dependencies ( & config) ;
1129
+ tracker_factory ( & config, & database, & whitelist_manager)
1227
1130
}
1228
1131
1229
- fn whitelisted_tracker ( ) -> Tracker {
1230
- tracker_factory ( & configuration:: ephemeral_listed ( ) )
1132
+ fn whitelisted_tracker ( ) -> ( Tracker , Arc < WhiteListManager > ) {
1133
+ let config = configuration:: ephemeral_listed ( ) ;
1134
+ let ( database, whitelist_manager) = initialize_tracker_dependencies ( & config) ;
1135
+ let tracker = tracker_factory ( & config, & database, & whitelist_manager) ;
1136
+
1137
+ ( tracker, whitelist_manager)
1231
1138
}
1232
1139
1233
1140
pub fn tracker_persisting_torrents_in_database ( ) -> Tracker {
1234
- let mut configuration = configuration:: ephemeral ( ) ;
1235
- configuration. core . tracker_policy . persistent_torrent_completed_stat = true ;
1236
- tracker_factory ( & configuration)
1141
+ let mut config = configuration:: ephemeral_listed ( ) ;
1142
+ config. core . tracker_policy . persistent_torrent_completed_stat = true ;
1143
+ let ( database, whitelist_manager) = initialize_tracker_dependencies ( & config) ;
1144
+ tracker_factory ( & config, & database, & whitelist_manager)
1237
1145
}
1238
1146
1239
1147
fn sample_info_hash ( ) -> InfoHash {
@@ -1760,11 +1668,11 @@ mod tests {
1760
1668
1761
1669
#[ tokio:: test]
1762
1670
async fn it_should_authorize_the_announce_and_scrape_actions_on_whitelisted_torrents ( ) {
1763
- let tracker = whitelisted_tracker ( ) ;
1671
+ let ( tracker, whitelist_manager ) = whitelisted_tracker ( ) ;
1764
1672
1765
1673
let info_hash = sample_info_hash ( ) ;
1766
1674
1767
- let result = tracker . add_torrent_to_whitelist ( & info_hash) . await ;
1675
+ let result = whitelist_manager . add_torrent_to_whitelist ( & info_hash) . await ;
1768
1676
assert ! ( result. is_ok( ) ) ;
1769
1677
1770
1678
let result = tracker. authorize ( & info_hash) . await ;
@@ -1773,7 +1681,7 @@ mod tests {
1773
1681
1774
1682
#[ tokio:: test]
1775
1683
async fn it_should_not_authorize_the_announce_and_scrape_actions_on_not_whitelisted_torrents ( ) {
1776
- let tracker = whitelisted_tracker ( ) ;
1684
+ let ( tracker, _whitelist_manager ) = whitelisted_tracker ( ) ;
1777
1685
1778
1686
let info_hash = sample_info_hash ( ) ;
1779
1687
@@ -1785,48 +1693,53 @@ mod tests {
1785
1693
mod handling_the_torrent_whitelist {
1786
1694
use crate :: core:: tests:: the_tracker:: { sample_info_hash, whitelisted_tracker} ;
1787
1695
1696
+ // todo: after extracting the WhitelistManager from the Tracker,
1697
+ // there is no need to use the tracker to test the whitelist.
1698
+ // Test not using the `tracker` (`_tracker` variable) should be
1699
+ // moved to the whitelist module.
1700
+
1788
1701
#[ tokio:: test]
1789
1702
async fn it_should_add_a_torrent_to_the_whitelist ( ) {
1790
- let tracker = whitelisted_tracker ( ) ;
1703
+ let ( _tracker , whitelist_manager ) = whitelisted_tracker ( ) ;
1791
1704
1792
1705
let info_hash = sample_info_hash ( ) ;
1793
1706
1794
- tracker . add_torrent_to_whitelist ( & info_hash) . await . unwrap ( ) ;
1707
+ whitelist_manager . add_torrent_to_whitelist ( & info_hash) . await . unwrap ( ) ;
1795
1708
1796
- assert ! ( tracker . is_info_hash_whitelisted( & info_hash) . await ) ;
1709
+ assert ! ( whitelist_manager . is_info_hash_whitelisted( & info_hash) . await ) ;
1797
1710
}
1798
1711
1799
1712
#[ tokio:: test]
1800
1713
async fn it_should_remove_a_torrent_from_the_whitelist ( ) {
1801
- let tracker = whitelisted_tracker ( ) ;
1714
+ let ( _tracker , whitelist_manager ) = whitelisted_tracker ( ) ;
1802
1715
1803
1716
let info_hash = sample_info_hash ( ) ;
1804
1717
1805
- tracker . add_torrent_to_whitelist ( & info_hash) . await . unwrap ( ) ;
1718
+ whitelist_manager . add_torrent_to_whitelist ( & info_hash) . await . unwrap ( ) ;
1806
1719
1807
- tracker . remove_torrent_from_whitelist ( & info_hash) . await . unwrap ( ) ;
1720
+ whitelist_manager . remove_torrent_from_whitelist ( & info_hash) . await . unwrap ( ) ;
1808
1721
1809
- assert ! ( !tracker . is_info_hash_whitelisted( & info_hash) . await ) ;
1722
+ assert ! ( !whitelist_manager . is_info_hash_whitelisted( & info_hash) . await ) ;
1810
1723
}
1811
1724
1812
1725
mod persistence {
1813
1726
use crate :: core:: tests:: the_tracker:: { sample_info_hash, whitelisted_tracker} ;
1814
1727
1815
1728
#[ tokio:: test]
1816
1729
async fn it_should_load_the_whitelist_from_the_database ( ) {
1817
- let tracker = whitelisted_tracker ( ) ;
1730
+ let ( _tracker , whitelist_manager ) = whitelisted_tracker ( ) ;
1818
1731
1819
1732
let info_hash = sample_info_hash ( ) ;
1820
1733
1821
- tracker. add_torrent_to_whitelist ( & info_hash) . await . unwrap ( ) ;
1734
+ whitelist_manager. add_torrent_to_whitelist ( & info_hash) . await . unwrap ( ) ;
1735
+
1736
+ whitelist_manager. remove_torrent_from_memory_whitelist ( & info_hash) . await ;
1822
1737
1823
- // Remove torrent from the in-memory whitelist
1824
- tracker. whitelist . write ( ) . await . remove ( & info_hash) ;
1825
- assert ! ( !tracker. is_info_hash_whitelisted( & info_hash) . await ) ;
1738
+ assert ! ( !whitelist_manager. is_info_hash_whitelisted( & info_hash) . await ) ;
1826
1739
1827
- tracker . load_whitelist_from_database ( ) . await . unwrap ( ) ;
1740
+ whitelist_manager . load_whitelist_from_database ( ) . await . unwrap ( ) ;
1828
1741
1829
- assert ! ( tracker . is_info_hash_whitelisted( & info_hash) . await ) ;
1742
+ assert ! ( whitelist_manager . is_info_hash_whitelisted( & info_hash) . await ) ;
1830
1743
}
1831
1744
}
1832
1745
}
@@ -1857,7 +1770,7 @@ mod tests {
1857
1770
1858
1771
#[ tokio:: test]
1859
1772
async fn it_should_return_the_zeroed_swarm_metadata_for_the_requested_file_if_it_is_not_whitelisted ( ) {
1860
- let tracker = whitelisted_tracker ( ) ;
1773
+ let ( tracker, _whitelist_manager ) = whitelisted_tracker ( ) ;
1861
1774
1862
1775
let info_hash = "3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0" . parse :: < InfoHash > ( ) . unwrap ( ) ;
1863
1776
0 commit comments