Skip to content

Commit

Permalink
refactor: [torrust#1195] extract authentication::Service
Browse files Browse the repository at this point in the history
  • Loading branch information
josecelano committed Jan 21, 2025
1 parent a93a79c commit cd542dc
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 44 deletions.
69 changes: 25 additions & 44 deletions src/core/authentication/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::panic::Location;
use std::sync::Arc;
use std::time::Duration;

Expand All @@ -14,6 +13,7 @@ use super::error::PeerKeyError;
use crate::CurrentClock;

pub mod key;
pub mod service;

pub type PeerKey = key::PeerKey;
pub type Key = key::Key;
Expand All @@ -34,23 +34,25 @@ pub struct AddKeyRequest {
}

pub struct Facade {
/// The tracker configuration.
config: Core,

/// The database repository for the authentication keys.
db_key_repository: DatabaseKeyRepository,

/// In-memory implementation of the authentication key repository.
in_memory_key_repository: InMemoryKeyRepository,
in_memory_key_repository: Arc<InMemoryKeyRepository>,

/// The authentication service.
authentication_service: service::Service,
}

impl Facade {
#[must_use]
pub fn new(config: &Core, database: &Arc<Box<dyn Database>>) -> Self {
let in_memory_key_repository = Arc::new(InMemoryKeyRepository::default());

Self {
config: config.clone(),
db_key_repository: DatabaseKeyRepository::new(database),
in_memory_key_repository: InMemoryKeyRepository::default(),
in_memory_key_repository: in_memory_key_repository.clone(),
authentication_service: service::Service::new(config, &in_memory_key_repository),
}
}

Expand All @@ -61,40 +63,7 @@ impl Facade {
///
/// Will return an error if the the authentication key cannot be verified.
pub async fn authenticate(&self, key: &Key) -> Result<(), Error> {
if self.is_private() {
self.verify_auth_key(key).await
} else {
Ok(())
}
}

/// Returns `true` is the tracker is in private mode.
pub fn is_private(&self) -> bool {
self.config.private
}

/// It verifies an authentication key.
///
/// # Errors
///
/// Will return a `key::Error` if unable to get any `auth_key`.
pub async fn verify_auth_key(&self, key: &Key) -> Result<(), Error> {
match self.in_memory_key_repository.get(key).await {
None => Err(Error::UnableToReadKey {
location: Location::caller(),
key: Box::new(key.clone()),
}),
Some(key) => match self.config.private_mode {
Some(private_mode) => {
if private_mode.check_keys_expiration {
return key::verify_key_expiration(&key);
}

Ok(())
}
None => key::verify_key_expiration(&key),
},
}
self.authentication_service.authenticate(key).await
}

/// Adds new peer keys to the tracker.
Expand Down Expand Up @@ -340,7 +309,11 @@ mod tests {

let unregistered_key = authentication::Key::from_str("YZSl4lMZupRuOpSRC3krIKR5BPB14nrJ").unwrap();

assert!(authentication.verify_auth_key(&unregistered_key).await.is_err());
assert!(authentication
.authentication_service
.verify_auth_key(&unregistered_key)
.await
.is_err());
}

#[tokio::test]
Expand All @@ -355,7 +328,11 @@ mod tests {
let result = authentication.remove_auth_key(&expiring_key.key()).await;

assert!(result.is_ok());
assert!(authentication.verify_auth_key(&expiring_key.key()).await.is_err());
assert!(authentication
.authentication_service
.verify_auth_key(&expiring_key.key())
.await
.is_err());
}

#[tokio::test]
Expand All @@ -373,7 +350,11 @@ mod tests {
let result = authentication.load_keys_from_database().await;

assert!(result.is_ok());
assert!(authentication.verify_auth_key(&expiring_key.key()).await.is_ok());
assert!(authentication
.authentication_service
.verify_auth_key(&expiring_key.key())
.await
.is_ok());
}

mod with_expiring_and {
Expand Down
70 changes: 70 additions & 0 deletions src/core/authentication/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::panic::Location;
use std::sync::Arc;

use torrust_tracker_configuration::Core;

use super::key::repository::in_memory::InMemoryKeyRepository;
use super::{key, Error, Key};

#[derive(Debug)]
pub struct Service {
/// The tracker configuration.
config: Core,

/// In-memory implementation of the authentication key repository.
in_memory_key_repository: Arc<InMemoryKeyRepository>,
}

impl Service {
#[must_use]
pub fn new(config: &Core, in_memory_key_repository: &Arc<InMemoryKeyRepository>) -> Self {
Self {
config: config.clone(),
in_memory_key_repository: in_memory_key_repository.clone(),
}
}

/// It authenticates the peer `key` against the `Tracker` authentication
/// key list.
///
/// # Errors
///
/// Will return an error if the the authentication key cannot be verified.
pub async fn authenticate(&self, key: &Key) -> Result<(), Error> {
if self.is_private() {
self.verify_auth_key(key).await
} else {
Ok(())
}
}

/// Returns `true` is the tracker is in private mode.
#[must_use]
pub fn is_private(&self) -> bool {
self.config.private
}

/// It verifies an authentication key.
///
/// # Errors
///
/// Will return a `key::Error` if unable to get any `auth_key`.
pub async fn verify_auth_key(&self, key: &Key) -> Result<(), Error> {
match self.in_memory_key_repository.get(key).await {
None => Err(Error::UnableToReadKey {
location: Location::caller(),
key: Box::new(key.clone()),
}),
Some(key) => match self.config.private_mode {
Some(private_mode) => {
if private_mode.check_keys_expiration {
return key::verify_key_expiration(&key);
}

Ok(())
}
None => key::verify_key_expiration(&key),
},
}
}
}

0 comments on commit cd542dc

Please sign in to comment.