@@ -5,9 +5,6 @@ use std::sync::Arc;
55
66use aquatic_udp_protocol:: { AnnounceEvent , NumberOfBytes } ;
77use reqwest:: Response ;
8- use torrust_tracker:: api:: resource:: auth_key:: AuthKey ;
9- use torrust_tracker:: api:: resource:: stats:: Stats ;
10- use torrust_tracker:: api:: resource:: torrent:: { self , Torrent } ;
118use torrust_tracker:: config:: Configuration ;
129use torrust_tracker:: jobs:: tracker_api;
1310use torrust_tracker:: protocol:: clock:: DurationSinceUnixEpoch ;
@@ -51,14 +48,21 @@ pub fn tracker_configuration() -> Arc<Configuration> {
5148#[ derive( Clone ) ]
5249pub struct ConnectionInfo {
5350 pub bind_address : String ,
54- pub api_token : String ,
51+ pub api_token : Option < String > ,
5552}
5653
5754impl ConnectionInfo {
58- pub fn new ( bind_address : & str , api_token : & str ) -> Self {
55+ pub fn authenticated ( bind_address : & str , api_token : & str ) -> Self {
5956 Self {
6057 bind_address : bind_address. to_string ( ) ,
61- api_token : api_token. to_string ( ) ,
58+ api_token : Some ( api_token. to_string ( ) ) ,
59+ }
60+ }
61+
62+ pub fn anonymous ( bind_address : & str ) -> Self {
63+ Self {
64+ bind_address : bind_address. to_string ( ) ,
65+ api_token : None ,
6266 }
6367 }
6468}
@@ -73,7 +77,7 @@ pub async fn start_custom_api_server(configuration: Arc<Configuration>) -> Serve
7377}
7478
7579async fn start ( configuration : Arc < Configuration > ) -> Server {
76- let connection_info = ConnectionInfo :: new (
80+ let connection_info = ConnectionInfo :: authenticated (
7781 & configuration. http_api . bind_address . clone ( ) ,
7882 & configuration. http_api . access_tokens . get_key_value ( "admin" ) . unwrap ( ) . 1 . clone ( ) ,
7983 ) ;
@@ -117,6 +121,10 @@ impl Server {
117121 self . connection_info . clone ( )
118122 }
119123
124+ pub fn get_bind_address ( & self ) -> String {
125+ self . connection_info . bind_address . clone ( )
126+ }
127+
120128 /// Add a torrent to the tracker
121129 pub async fn add_torrent ( & self , info_hash : & InfoHash , peer : & Peer ) {
122130 self . tracker . update_torrent_with_peer_and_get_stats ( info_hash, peer) . await ;
@@ -127,53 +135,149 @@ pub struct Client {
127135 connection_info : ConnectionInfo ,
128136}
129137
138+ type ReqwestQuery = Vec < ReqwestQueryParam > ;
139+ type ReqwestQueryParam = ( String , String ) ;
140+
141+ #[ derive( Default , Debug ) ]
142+ pub struct Query {
143+ params : Vec < QueryParam > ,
144+ }
145+
146+ impl Query {
147+ pub fn empty ( ) -> Self {
148+ Self { params : vec ! [ ] }
149+ }
150+
151+ pub fn params ( params : Vec < QueryParam > ) -> Self {
152+ Self { params }
153+ }
154+
155+ pub fn add_param ( & mut self , param : QueryParam ) {
156+ self . params . push ( param) ;
157+ }
158+
159+ fn with_token ( token : & str ) -> Self {
160+ Self {
161+ params : vec ! [ QueryParam :: new( "token" , token) ] ,
162+ }
163+ }
164+ }
165+
166+ impl From < Query > for ReqwestQuery {
167+ fn from ( url_search_params : Query ) -> Self {
168+ url_search_params
169+ . params
170+ . iter ( )
171+ . map ( |param| ReqwestQueryParam :: from ( ( * param) . clone ( ) ) )
172+ . collect ( )
173+ }
174+ }
175+
176+ #[ derive( Clone , Debug ) ]
177+ pub struct QueryParam {
178+ name : String ,
179+ value : String ,
180+ }
181+
182+ impl QueryParam {
183+ pub fn new ( name : & str , value : & str ) -> Self {
184+ Self {
185+ name : name. to_string ( ) ,
186+ value : value. to_string ( ) ,
187+ }
188+ }
189+ }
190+
191+ impl From < QueryParam > for ReqwestQueryParam {
192+ fn from ( param : QueryParam ) -> Self {
193+ ( param. name , param. value )
194+ }
195+ }
196+
130197impl Client {
131198 pub fn new ( connection_info : ConnectionInfo ) -> Self {
132199 Self { connection_info }
133200 }
134201
135- pub async fn generate_auth_key ( & self , seconds_valid : i32 ) -> AuthKey {
136- self . post ( & format ! ( "key/{}" , & seconds_valid) ) . await . json ( ) . await . unwrap ( )
202+ pub async fn generate_auth_key ( & self , seconds_valid : i32 ) -> Response {
203+ self . post ( & format ! ( "key/{}" , & seconds_valid) ) . await
204+ }
205+
206+ pub async fn delete_auth_key ( & self , key : & str ) -> Response {
207+ self . delete ( & format ! ( "key/{}" , & key) ) . await
208+ }
209+
210+ pub async fn reload_keys ( & self ) -> Response {
211+ self . get ( "keys/reload" , Query :: default ( ) ) . await
137212 }
138213
139214 pub async fn whitelist_a_torrent ( & self , info_hash : & str ) -> Response {
140215 self . post ( & format ! ( "whitelist/{}" , & info_hash) ) . await
141216 }
142217
143- pub async fn get_torrent ( & self , info_hash : & str ) -> Torrent {
144- self . get ( & format ! ( "torrent/{}" , & info_hash) )
145- . await
146- . json :: < Torrent > ( )
147- . await
148- . unwrap ( )
218+ pub async fn remove_torrent_from_whitelist ( & self , info_hash : & str ) -> Response {
219+ self . delete ( & format ! ( "whitelist/{}" , & info_hash) ) . await
149220 }
150221
151- pub async fn get_torrents ( & self ) -> Vec < torrent :: ListItem > {
152- self . get ( "torrents" ) . await . json :: < Vec < torrent :: ListItem > > ( ) . await . unwrap ( )
222+ pub async fn reload_whitelist ( & self ) -> Response {
223+ self . get ( "whitelist/reload" , Query :: default ( ) ) . await
153224 }
154225
155- pub async fn get_tracker_statistics ( & self ) -> Stats {
156- self . get ( "stats" ) . await . json :: < Stats > ( ) . await . unwrap ( )
226+ pub async fn get_torrent ( & self , info_hash : & str ) -> Response {
227+ self . get ( & format ! ( "torrent/{}" , & info_hash ) , Query :: default ( ) ) . await
157228 }
158229
159- async fn get ( & self , path : & str ) -> Response {
230+ pub async fn get_torrents ( & self , params : Query ) -> Response {
231+ self . get ( "torrents" , params) . await
232+ }
233+
234+ pub async fn get_tracker_statistics ( & self ) -> Response {
235+ self . get ( "stats" , Query :: default ( ) ) . await
236+ }
237+
238+ async fn get ( & self , path : & str , params : Query ) -> Response {
239+ let mut query: Query = params;
240+
241+ if let Some ( token) = & self . connection_info . api_token {
242+ query. add_param ( QueryParam :: new ( "token" , token) ) ;
243+ } ;
244+
160245 reqwest:: Client :: builder ( )
161246 . build ( )
162247 . unwrap ( )
163- . get ( self . url ( path) )
248+ . get ( self . base_url ( path) )
249+ . query ( & ReqwestQuery :: from ( query) )
164250 . send ( )
165251 . await
166252 . unwrap ( )
167253 }
168254
169255 async fn post ( & self , path : & str ) -> Response {
170- reqwest:: Client :: new ( ) . post ( self . url ( path) . clone ( ) ) . send ( ) . await . unwrap ( )
256+ reqwest:: Client :: new ( )
257+ . post ( self . base_url ( path) . clone ( ) )
258+ . query ( & ReqwestQuery :: from ( self . query_with_token ( ) ) )
259+ . send ( )
260+ . await
261+ . unwrap ( )
262+ }
263+
264+ async fn delete ( & self , path : & str ) -> Response {
265+ reqwest:: Client :: new ( )
266+ . delete ( self . base_url ( path) . clone ( ) )
267+ . query ( & ReqwestQuery :: from ( self . query_with_token ( ) ) )
268+ . send ( )
269+ . await
270+ . unwrap ( )
171271 }
172272
173- fn url ( & self , path : & str ) -> String {
174- format ! (
175- "http://{}/api/{path}?token={}" ,
176- & self . connection_info. bind_address, & self . connection_info. api_token
177- )
273+ fn base_url ( & self , path : & str ) -> String {
274+ format ! ( "http://{}/api/{path}" , & self . connection_info. bind_address)
275+ }
276+
277+ fn query_with_token ( & self ) -> Query {
278+ match & self . connection_info . api_token {
279+ Some ( token) => Query :: with_token ( token) ,
280+ None => Query :: default ( ) ,
281+ }
178282 }
179283}
0 commit comments