Skip to content

Commit 12a62ce

Browse files
committed
refactor: [#1195] extract InMemoryKeyRepository
1 parent f4c7b97 commit 12a62ce

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::core::authentication::key::{Key, PeerKey};
2+
3+
/// In-memory implementation of the authentication key repository.
4+
#[derive(Debug, Default)]
5+
pub struct InMemoryKeyRepository {
6+
/// Tracker users' keys. Only for private trackers.
7+
keys: tokio::sync::RwLock<std::collections::HashMap<Key, PeerKey>>,
8+
}
9+
10+
impl InMemoryKeyRepository {
11+
/// It adds a new authentication key.
12+
pub async fn insert(&self, auth_key: &PeerKey) {
13+
self.keys.write().await.insert(auth_key.key.clone(), auth_key.clone());
14+
}
15+
16+
/// It removes an authentication key.
17+
pub async fn remove(&self, key: &Key) {
18+
self.keys.write().await.remove(key);
19+
}
20+
21+
pub async fn get(&self, key: &Key) -> Option<PeerKey> {
22+
self.keys.read().await.get(key).cloned()
23+
}
24+
25+
/// It clears all the authentication keys.
26+
pub async fn clear(&self) {
27+
let mut keys = self.keys.write().await;
28+
keys.clear();
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
pub mod in_memory;
12
pub mod persisted;

src/core/authentication/mod.rs

+21-20
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::panic::Location;
22
use std::sync::Arc;
33
use std::time::Duration;
44

5+
use key::repository::in_memory::InMemoryKeyRepository;
56
use key::repository::persisted::DatabaseKeyRepository;
67
use torrust_tracker_clock::clock::Time;
78
use torrust_tracker_configuration::Core;
@@ -36,20 +37,20 @@ pub struct Facade {
3637
/// The tracker configuration.
3738
config: Core,
3839

39-
/// Tracker users' keys. Only for private trackers.
40-
keys: tokio::sync::RwLock<std::collections::HashMap<Key, PeerKey>>,
41-
4240
/// The database repository for the authentication keys.
4341
db_key_repository: DatabaseKeyRepository,
42+
43+
/// In-memory implementation of the authentication key repository.
44+
in_memory_key_repository: InMemoryKeyRepository,
4445
}
4546

4647
impl Facade {
4748
#[must_use]
4849
pub fn new(config: &Core, database: &Arc<Box<dyn Database>>) -> Self {
4950
Self {
5051
config: config.clone(),
51-
keys: tokio::sync::RwLock::new(std::collections::HashMap::new()),
5252
db_key_repository: DatabaseKeyRepository::new(database),
53+
in_memory_key_repository: InMemoryKeyRepository::default(),
5354
}
5455
}
5556

@@ -82,20 +83,20 @@ impl Facade {
8283
///
8384
/// Will return a `key::Error` if unable to get any `auth_key`.
8485
pub async fn verify_auth_key(&self, key: &Key) -> Result<(), Error> {
85-
match self.keys.read().await.get(key) {
86+
match self.in_memory_key_repository.get(key).await {
8687
None => Err(Error::UnableToReadKey {
8788
location: Location::caller(),
8889
key: Box::new(key.clone()),
8990
}),
9091
Some(key) => match self.config.private_mode {
9192
Some(private_mode) => {
9293
if private_mode.check_keys_expiration {
93-
return key::verify_key_expiration(key);
94+
return key::verify_key_expiration(&key);
9495
}
9596

9697
Ok(())
9798
}
98-
None => key::verify_key_expiration(key),
99+
None => key::verify_key_expiration(&key),
99100
},
100101
}
101102
}
@@ -203,12 +204,13 @@ impl Facade {
203204
/// * `lifetime` - The duration in seconds for the new key. The key will be
204205
/// no longer valid after `lifetime` seconds.
205206
pub async fn generate_auth_key(&self, lifetime: Option<Duration>) -> Result<PeerKey, databases::error::Error> {
206-
let auth_key = key::generate_key(lifetime);
207+
let peer_key = key::generate_key(lifetime);
208+
209+
self.db_key_repository.add(&peer_key)?;
207210

208-
self.db_key_repository.add(&auth_key)?;
211+
self.in_memory_key_repository.insert(&peer_key).await;
209212

210-
self.keys.write().await.insert(auth_key.key.clone(), auth_key.clone());
211-
Ok(auth_key)
213+
Ok(peer_key)
212214
}
213215

214216
/// It adds a pre-generated permanent authentication key.
@@ -250,15 +252,16 @@ impl Facade {
250252
key: Key,
251253
valid_until: Option<DurationSinceUnixEpoch>,
252254
) -> Result<PeerKey, databases::error::Error> {
253-
let auth_key = PeerKey { key, valid_until };
255+
let peer_key = PeerKey { key, valid_until };
254256

255257
// code-review: should we return a friendly error instead of the DB
256258
// constrain error when the key already exist? For now, it's returning
257259
// the specif error for each DB driver when a UNIQUE constrain fails.
258-
self.db_key_repository.add(&auth_key)?;
260+
self.db_key_repository.add(&peer_key)?;
259261

260-
self.keys.write().await.insert(auth_key.key.clone(), auth_key.clone());
261-
Ok(auth_key)
262+
self.in_memory_key_repository.insert(&peer_key).await;
263+
264+
Ok(peer_key)
262265
}
263266

264267
/// It removes an authentication key.
@@ -280,7 +283,7 @@ impl Facade {
280283
///
281284
/// # Context: Authentication
282285
pub async fn remove_in_memory_auth_key(&self, key: &Key) {
283-
self.keys.write().await.remove(key);
286+
self.in_memory_key_repository.remove(key).await;
284287
}
285288

286289
/// The `Tracker` stores the authentication keys in memory and in the database.
@@ -296,12 +299,10 @@ impl Facade {
296299
pub async fn load_keys_from_database(&self) -> Result<(), databases::error::Error> {
297300
let keys_from_database = self.db_key_repository.load_keys()?;
298301

299-
let mut keys = self.keys.write().await;
300-
301-
keys.clear();
302+
self.in_memory_key_repository.clear().await;
302303

303304
for key in keys_from_database {
304-
keys.insert(key.key.clone(), key);
305+
self.in_memory_key_repository.insert(&key).await;
305306
}
306307

307308
Ok(())

0 commit comments

Comments
 (0)