covert_system/system/
lease.rs1use covert_framework::extract::{Extension, Json, Path};
2use covert_types::{
3 methods::system::{
4 LeaseEntry as LeaseEntryDTO, ListLeasesResponse, LookupLeaseResponse, RenewLeaseParams,
5 RenewLeaseResponse, RevokedLeaseResponse, RevokedLeasesResponse,
6 },
7 response::Response,
8};
9
10use crate::{
11 context::Context,
12 error::{Error, ErrorType},
13 expiration_manager::LeaseEntry,
14 repos::namespace::Namespace,
15};
16
17impl From<&LeaseEntry> for LeaseEntryDTO {
18 fn from(le: &LeaseEntry) -> Self {
19 Self {
20 id: le.id.clone(),
21 issued_mount_path: le.issued_mount_path.clone(),
22 issue_time: le.issued_at.to_rfc3339(),
23 expire_time: le.expires_at.to_rfc3339(),
24 last_renewal_time: le.expires_at.to_rfc3339(),
25 }
26 }
27}
28
29pub async fn handle_lease_revocation_by_mount(
30 Extension(ctx): Extension<Context>,
31 Extension(ns): Extension<Namespace>,
32 Path(prefix): Path<String>,
33) -> Result<Response, Error> {
34 let revoked_leases = ctx
35 .expiration_manager
36 .revoke_leases_by_mount_prefix(&prefix, &ns.id)
37 .await?;
38 let resp = RevokedLeasesResponse {
39 leases: revoked_leases.iter().map(LeaseEntryDTO::from).collect(),
40 };
41 Response::raw(resp).map_err(|err| ErrorType::BadResponseData(err).into())
42}
43
44pub async fn handle_lease_revocation(
45 Extension(ctx): Extension<Context>,
46 Extension(ns): Extension<Namespace>,
47 Path(lease_id): Path<String>,
48) -> Result<Response, Error> {
49 let revoked_lease = ctx
50 .expiration_manager
51 .revoke_lease_entry_by_id(&lease_id, &ns.id)
52 .await?;
53 let resp = RevokedLeaseResponse {
54 lease: LeaseEntryDTO::from(&revoked_lease),
55 };
56 Response::raw(resp).map_err(|err| ErrorType::BadResponseData(err).into())
57}
58
59pub async fn handle_list_leases(
60 Extension(ctx): Extension<Context>,
61 Extension(ns): Extension<Namespace>,
62 Path(prefix): Path<String>,
63) -> Result<Response, Error> {
64 let leases = ctx
65 .expiration_manager
66 .list_by_mount_prefix(&prefix, &ns.id)
67 .await?;
68 let resp = ListLeasesResponse {
69 leases: leases.iter().map(LeaseEntryDTO::from).collect(),
70 };
71 Response::raw(resp).map_err(|err| ErrorType::BadResponseData(err).into())
72}
73
74pub async fn handle_lease_lookup(
75 Extension(ctx): Extension<Context>,
76 Extension(ns): Extension<Namespace>,
77 Path(lease_id): Path<String>,
78) -> Result<Response, Error> {
79 let lease = ctx
80 .expiration_manager
81 .lookup(&lease_id, &ns.id)
82 .await?
83 .ok_or_else(|| ErrorType::NotFound(format!("Lease `{lease_id}` not found")))?;
84 let resp = LookupLeaseResponse {
85 lease: LeaseEntryDTO::from(&lease),
86 };
87 Response::raw(resp).map_err(|err| ErrorType::BadResponseData(err).into())
88}
89
90pub async fn handle_lease_renew(
91 Extension(ctx): Extension<Context>,
92 Extension(ns): Extension<Namespace>,
93 Json(body): Json<RenewLeaseParams>,
94 Path(lease_id): Path<String>,
95) -> Result<Response, Error> {
96 let lease = ctx
97 .expiration_manager
98 .renew_lease_entry(&lease_id, &ns.id, body.ttl)
99 .await?;
100 let resp = RenewLeaseResponse {
101 lease: LeaseEntryDTO::from(&lease),
102 };
103 Response::raw(resp).map_err(|err| ErrorType::BadResponseData(err).into())
104}