Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul core Tracker: extract authentication #1192

1 change: 1 addition & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -53,6 +53,7 @@ pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec<
if app_container.tracker.is_private() {
app_container
.tracker
.authentication
.load_keys_from_database()
.await
.expect("Could not retrieve keys from database.");
6 changes: 4 additions & 2 deletions src/app_test.rs
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@ use torrust_tracker_configuration::Configuration;

use crate::core::databases::Database;
use crate::core::services::initialize_database;
use crate::core::whitelist;
use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
use crate::core::{authentication, whitelist};

/// Initialize the tracker dependencies.
#[allow(clippy::type_complexity)]
@@ -17,13 +17,15 @@ pub fn initialize_tracker_dependencies(
Arc<Box<dyn Database>>,
Arc<InMemoryWhitelist>,
Arc<whitelist::authorization::Authorization>,
Arc<authentication::Facade>,
) {
let database = initialize_database(config);
let in_memory_whitelist = Arc::new(InMemoryWhitelist::default());
let whitelist_authorization = Arc::new(whitelist::authorization::Authorization::new(
&config.core,
&in_memory_whitelist.clone(),
));
let authentication = Arc::new(authentication::Facade::new(&config.core, &database.clone()));

(database, in_memory_whitelist, whitelist_authorization)
(database, in_memory_whitelist, whitelist_authorization, authentication)
}
11 changes: 9 additions & 2 deletions src/bootstrap/app.rs
Original file line number Diff line number Diff line change
@@ -23,8 +23,8 @@ use super::config::initialize_configuration;
use crate::bootstrap;
use crate::container::AppContainer;
use crate::core::services::{initialize_database, initialize_tracker, initialize_whitelist_manager, statistics};
use crate::core::whitelist;
use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
use crate::core::{authentication, whitelist};
use crate::servers::udp::server::banning::BanService;
use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP;
use crate::shared::crypto::ephemeral_instance_keys;
@@ -89,8 +89,14 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
&in_memory_whitelist.clone(),
));
let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
let authentication = Arc::new(authentication::Facade::new(&configuration.core, &database.clone()));

let tracker = Arc::new(initialize_tracker(configuration, &database, &whitelist_authorization));
let tracker = Arc::new(initialize_tracker(
configuration,
&database,
&whitelist_authorization,
&authentication,
));

AppContainer {
tracker,
@@ -99,6 +105,7 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
stats_event_sender,
stats_repository,
whitelist_manager,
authentication,
}
}

6 changes: 4 additions & 2 deletions src/bootstrap/jobs/http_tracker.rs
Original file line number Diff line number Diff line change
@@ -101,8 +101,8 @@ mod tests {
use crate::bootstrap::app::initialize_global_services;
use crate::bootstrap::jobs::http_tracker::start_job;
use crate::core::services::{initialize_database, initialize_tracker, statistics};
use crate::core::whitelist;
use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
use crate::core::{authentication, whitelist};
use crate::servers::http::Version;
use crate::servers::registar::Registar;

@@ -123,7 +123,9 @@ mod tests {
&cfg.core,
&in_memory_whitelist.clone(),
));
let tracker = Arc::new(initialize_tracker(&cfg, &database, &whitelist_authorization));
let authentication = Arc::new(authentication::Facade::new(&cfg.core, &database.clone()));

let tracker = Arc::new(initialize_tracker(&cfg, &database, &whitelist_authorization, &authentication));

let version = Version::V1;

5 changes: 3 additions & 2 deletions src/bootstrap/jobs/tracker_apis.rs
Original file line number Diff line number Diff line change
@@ -150,8 +150,8 @@ mod tests {
use crate::bootstrap::app::initialize_global_services;
use crate::bootstrap::jobs::tracker_apis::start_job;
use crate::core::services::{initialize_database, initialize_tracker, initialize_whitelist_manager, statistics};
use crate::core::whitelist;
use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
use crate::core::{authentication, whitelist};
use crate::servers::apis::Version;
use crate::servers::registar::Registar;
use crate::servers::udp::server::banning::BanService;
@@ -176,8 +176,9 @@ mod tests {
&in_memory_whitelist.clone(),
));
let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
let authentication = Arc::new(authentication::Facade::new(&cfg.core, &database.clone()));

let tracker = Arc::new(initialize_tracker(&cfg, &database, &whitelist_authorization));
let tracker = Arc::new(initialize_tracker(&cfg, &database, &whitelist_authorization, &authentication));

let version = Version::V1;

3 changes: 2 additions & 1 deletion src/container.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ use tokio::sync::RwLock;
use crate::core::statistics::event::sender::Sender;
use crate::core::statistics::repository::Repository;
use crate::core::whitelist::manager::WhiteListManager;
use crate::core::{whitelist, Tracker};
use crate::core::{authentication, whitelist, Tracker};
use crate::servers::udp::server::banning::BanService;

pub struct AppContainer {
@@ -15,4 +15,5 @@ pub struct AppContainer {
pub stats_event_sender: Arc<Option<Box<dyn Sender>>>,
pub stats_repository: Arc<Repository>,
pub whitelist_manager: Arc<WhiteListManager>,
pub authentication: Arc<authentication::Facade>,
}
36 changes: 19 additions & 17 deletions src/core/auth.rs → src/core/authentication/key.rs
Original file line number Diff line number Diff line change
@@ -12,28 +12,30 @@
//! Keys are stored in this struct:
//!
//! ```rust,no_run
//! use torrust_tracker_lib::core::auth::Key;
//! use torrust_tracker_lib::core::authentication::Key;
//! use torrust_tracker_primitives::DurationSinceUnixEpoch;
//!
//! pub struct ExpiringKey {
//! pub struct PeerKey {
//! /// Random 32-char string. For example: `YZSl4lMZupRuOpSRC3krIKR5BPB14nrJ`
//! pub key: Key,
//! /// Timestamp, the key will be no longer valid after this timestamp
//!
//! /// Timestamp, the key will be no longer valid after this timestamp.
//! /// If `None` the keys will not expire (permanent key).
//! pub valid_until: Option<DurationSinceUnixEpoch>,
//! }
//! ```
//!
//! You can generate a new key valid for `9999` seconds and `0` nanoseconds from the current time with the following:
//!
//! ```rust,no_run
//! use torrust_tracker_lib::core::auth;
//! use torrust_tracker_lib::core::authentication;
//! use std::time::Duration;
//!
//! let expiring_key = auth::generate_key(Some(Duration::new(9999, 0)));
//! let expiring_key = authentication::key::generate_key(Some(Duration::new(9999, 0)));
//!
//! // And you can later verify it with:
//!
//! assert!(auth::verify_key_expiration(&expiring_key).is_ok());
//! assert!(authentication::key::verify_key_expiration(&expiring_key).is_ok());
//! ```

use std::panic::Location;
@@ -197,7 +199,7 @@ impl Key {
/// Error returned when a key cannot be parsed from a string.
///
/// ```text
/// use torrust_tracker_lib::core::auth::Key;
/// use torrust_tracker_lib::core::authentication::Key;
/// use std::str::FromStr;
///
/// let key_string = "YZSl4lMZupRuOpSRC3krIKR5BPB14nrJ";
@@ -227,7 +229,7 @@ impl FromStr for Key {
}

/// Verification error. Error returned when an [`PeerKey`] cannot be
/// verified with the (`crate::core::auth::verify_key`) function.
/// verified with the (`crate::core::authentication::verify_key`) function.
#[derive(Debug, Error)]
#[allow(dead_code)]
pub enum Error {
@@ -258,7 +260,7 @@ mod tests {
mod key {
use std::str::FromStr;

use crate::core::auth::Key;
use crate::core::authentication::Key;

#[test]
fn should_be_parsed_from_an_string() {
@@ -293,12 +295,12 @@ mod tests {
use torrust_tracker_clock::clock;
use torrust_tracker_clock::clock::stopped::Stopped as _;

use crate::core::auth;
use crate::core::authentication;

#[test]
fn should_be_parsed_from_an_string() {
let key_string = "YZSl4lMZupRuOpSRC3krIKR5BPB14nrJ";
let auth_key = auth::Key::from_str(key_string);
let auth_key = authentication::Key::from_str(key_string);

assert!(auth_key.is_ok());
assert_eq!(auth_key.unwrap().to_string(), key_string);
@@ -309,7 +311,7 @@ mod tests {
// Set the time to the current time.
clock::Stopped::local_set_to_unix_epoch();

let expiring_key = auth::generate_key(Some(Duration::from_secs(0)));
let expiring_key = authentication::key::generate_key(Some(Duration::from_secs(0)));

assert_eq!(
expiring_key.to_string(),
@@ -319,9 +321,9 @@ mod tests {

#[test]
fn should_be_generated_with_a_expiration_time() {
let expiring_key = auth::generate_key(Some(Duration::new(9999, 0)));
let expiring_key = authentication::key::generate_key(Some(Duration::new(9999, 0)));

assert!(auth::verify_key_expiration(&expiring_key).is_ok());
assert!(authentication::key::verify_key_expiration(&expiring_key).is_ok());
}

#[test]
@@ -330,17 +332,17 @@ mod tests {
clock::Stopped::local_set_to_system_time_now();

// Make key that is valid for 19 seconds.
let expiring_key = auth::generate_key(Some(Duration::from_secs(19)));
let expiring_key = authentication::key::generate_key(Some(Duration::from_secs(19)));

// Mock the time has passed 10 sec.
clock::Stopped::local_add(&Duration::from_secs(10)).unwrap();

assert!(auth::verify_key_expiration(&expiring_key).is_ok());
assert!(authentication::key::verify_key_expiration(&expiring_key).is_ok());

// Mock the time has passed another 10 sec.
clock::Stopped::local_add(&Duration::from_secs(10)).unwrap();

assert!(auth::verify_key_expiration(&expiring_key).is_err());
assert!(authentication::key::verify_key_expiration(&expiring_key).is_err());
}
}
}
Loading