Skip to content

Overhaul core Tracker: extract authentication #1192

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
6 changes: 4 additions & 2 deletions src/app_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -99,6 +105,7 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
stats_event_sender,
stats_repository,
whitelist_manager,
authentication,
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/bootstrap/jobs/http_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;

Expand Down
5 changes: 3 additions & 2 deletions src/bootstrap/jobs/tracker_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down
3 changes: 2 additions & 1 deletion src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Up @@ -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;
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand All @@ -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(),
Expand All @@ -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]
Expand All @@ -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
Loading