covert_system/expiration_manager/
lease.rs

1use chrono::{DateTime, Duration, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5use crate::error::{Error, ErrorType};
6
7#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
8pub struct LeaseEntry {
9    pub id: String,
10    pub issued_mount_path: String,
11    pub revoke_path: Option<String>,
12    pub revoke_data: String,
13    pub renew_path: Option<String>,
14    pub renew_data: String,
15    pub issued_at: DateTime<Utc>,
16    pub expires_at: DateTime<Utc>,
17    pub last_renewal_time: DateTime<Utc>,
18    pub failed_revocation_attempts: u32,
19    pub namespace_id: String,
20}
21
22impl LeaseEntry {
23    #[allow(clippy::too_many_arguments)]
24    pub fn new<T: Serialize>(
25        issued_mount_path: String,
26        revoke_path: Option<String>,
27        revoke_data: &T,
28        renew_path: Option<String>,
29        renew_data: &T,
30        now: DateTime<Utc>,
31        ttl: Duration,
32        namespace_id: String,
33    ) -> Result<Self, Error> {
34        let expires_at = now + ttl;
35        let issued_at = now;
36        let last_renewal_time = now;
37
38        let lease_id = Uuid::new_v4().to_string();
39        let revoke_data = serde_json::to_string(revoke_data)
40            .map_err(|_| ErrorType::BadData("Unable to serialize revoke data".into()))?;
41        let renew_data = serde_json::to_string(renew_data)
42            .map_err(|_| ErrorType::BadData("Unable to serialize renew data".into()))?;
43
44        Ok(LeaseEntry {
45            id: lease_id,
46            issued_mount_path,
47            revoke_path,
48            revoke_data,
49            renew_path,
50            renew_data,
51            issued_at,
52            expires_at,
53            last_renewal_time,
54            failed_revocation_attempts: 0,
55            namespace_id,
56        })
57    }
58
59    #[must_use]
60    pub fn id(&self) -> &str {
61        &self.id
62    }
63}
64
65impl PartialOrd for LeaseEntry {
66    fn partial_cmp(&self, other: &LeaseEntry) -> Option<std::cmp::Ordering> {
67        self.expires_at.partial_cmp(&other.expires_at)
68    }
69}
70
71impl PartialEq for LeaseEntry {
72    fn eq(&self, other: &LeaseEntry) -> bool {
73        self.id == other.id
74    }
75}
76
77impl Eq for LeaseEntry {}
78
79impl Ord for LeaseEntry {
80    fn cmp(&self, other: &LeaseEntry) -> std::cmp::Ordering {
81        self.expires_at.cmp(&other.expires_at)
82    }
83}