Skip to content

Commit 613efb2

Browse files
committedFeb 10, 2025
fix: [torrust#1257] bug 3. Expiring auth keys ignore fractions of seconds
The `Duration` of a peer Key can have gractions of seconds. However we only store seconds (integer) in the database. When comparing peer keys we should ignore the fractions.
1 parent b94179d commit 613efb2

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed
 

‎packages/tracker-core/src/authentication/key/peer_key.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::str::FromStr;
2+
use std::time::Duration;
23

34
use derive_more::Display;
45
use rand::distr::Alphanumeric;
@@ -12,7 +13,7 @@ use super::AUTH_KEY_LENGTH;
1213

1314
/// An authentication key which can potentially have an expiration time.
1415
/// After that time is will automatically become invalid.
15-
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
16+
#[derive(Serialize, Deserialize, Debug, Clone)]
1617
pub struct PeerKey {
1718
/// Random 32-char string. For example: `YZSl4lMZupRuOpSRC3krIKR5BPB14nrJ`
1819
pub key: Key,
@@ -22,6 +23,21 @@ pub struct PeerKey {
2223
pub valid_until: Option<DurationSinceUnixEpoch>,
2324
}
2425

26+
impl PartialEq for PeerKey {
27+
fn eq(&self, other: &Self) -> bool {
28+
// We ignore the fractions of seconds when comparing the timestamps
29+
// because we only store the seconds in the database.
30+
self.key == other.key
31+
&& match (&self.valid_until, &other.valid_until) {
32+
(Some(a), Some(b)) => a.as_secs() == b.as_secs(),
33+
(None, None) => true,
34+
_ => false,
35+
}
36+
}
37+
}
38+
39+
impl Eq for PeerKey {}
40+
2541
impl std::fmt::Display for PeerKey {
2642
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2743
match self.expiry_time() {
@@ -47,7 +63,10 @@ impl PeerKey {
4763
/// (this will naturally happen in 292.5 billion years)
4864
#[must_use]
4965
pub fn expiry_time(&self) -> Option<chrono::DateTime<chrono::Utc>> {
50-
self.valid_until.map(convert_from_timestamp_to_datetime_utc)
66+
// We remove the fractions of seconds because we only store the seconds
67+
// in the database.
68+
self.valid_until
69+
.map(|valid_until| convert_from_timestamp_to_datetime_utc(Duration::from_secs(valid_until.as_secs())))
5170
}
5271
}
5372

‎packages/tracker-core/src/databases/driver/mod.rs

+2-15
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,8 @@ mod tests {
180180
// Get the key back
181181
let stored_peer_key = driver.get_key_from_keys(&peer_key.key()).unwrap().unwrap();
182182

183-
/* todo:
184-
185-
The expiration time recovered from the database is not the same
186-
as the one we set. It includes a small offset (nanoseconds).
187-
188-
left: PeerKey { key: Key("7HP1NslpuQn6kLVAgAF4nFpnZNSQ4hrx"), valid_until: Some(1739182308s) }
189-
right: PeerKey { key: Key("7HP1NslpuQn6kLVAgAF4nFpnZNSQ4hrx"), valid_until: Some(1739182308.603691299s)
190-
191-
*/
192-
193-
assert_eq!(stored_peer_key.key(), peer_key.key());
194-
assert_eq!(
195-
stored_peer_key.valid_until.unwrap().as_secs(),
196-
peer_key.valid_until.unwrap().as_secs()
197-
);
183+
assert_eq!(stored_peer_key, peer_key);
184+
assert_eq!(stored_peer_key.expiry_time(), peer_key.expiry_time());
198185
}
199186

200187
pub fn it_should_remove_a_permanent_authentication_key(driver: &Arc<Box<dyn Database>>) {

0 commit comments

Comments
 (0)
Please sign in to comment.