add creation date and expiration date to access keys

This commit is contained in:
Alex Auvolat
2025-04-17 11:09:21 +02:00
parent 2f21181ccb
commit c56b7e20c3
10 changed files with 225 additions and 33 deletions
+1 -5
View File
@@ -190,11 +190,7 @@ fn admin_token_info_results(token: &AdminApiToken, now: u64) -> GetAdminTokenInf
expiration: params.expiration.get().map(|x| {
DateTime::from_timestamp_millis(x as i64).expect("invalid timestamp stored in db")
}),
expired: params
.expiration
.get()
.map(|exp| now > exp)
.unwrap_or(false),
expired: params.is_expired(now),
scope: params.scope.get().0.clone(),
}
}
+7 -1
View File
@@ -637,6 +637,9 @@ pub struct ListKeysResponse(pub Vec<ListKeysResponseItem>);
pub struct ListKeysResponseItem {
pub id: String,
pub name: String,
pub created: Option<DateTime<Utc>>,
pub expiration: Option<DateTime<Utc>>,
pub expired: bool,
}
// ---- GetKeyInfo ----
@@ -656,8 +659,11 @@ pub struct GetKeyInfoRequest {
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct GetKeyInfoResponse {
pub name: String,
pub access_key_id: String,
pub created: Option<DateTime<Utc>>,
pub name: String,
pub expiration: Option<DateTime<Utc>>,
pub expired: bool,
#[serde(default, skip_serializing_if = "is_default")]
pub secret_access_key: Option<String>,
pub permissions: KeyPerm,
+2 -13
View File
@@ -272,19 +272,8 @@ fn verify_authorization(
.admin_token_table
.get_local(&EmptyKey, &prefix.to_string())?
.and_then(|k| k.state.into_option())
.filter(|p| {
p.expiration
.get()
.map(|exp| now_msec() < exp)
.unwrap_or(true)
})
.filter(|p| {
p.scope
.get()
.0
.iter()
.any(|x| x == "*" || x == endpoint_name)
})
.filter(|p| !p.is_expired(now_msec()))
.filter(|p| p.has_scope(endpoint_name))
.ok_or_else(|| Error::forbidden(invalid_msg))?
.token_hash
} else {
+28 -3
View File
@@ -1,7 +1,10 @@
use std::collections::HashMap;
use std::sync::Arc;
use chrono::DateTime;
use garage_table::*;
use garage_util::time::now_msec;
use garage_model::garage::Garage;
use garage_model::key_table::*;
@@ -14,6 +17,8 @@ impl RequestHandler for ListKeysRequest {
type Response = ListKeysResponse;
async fn handle(self, garage: &Arc<Garage>, _admin: &Admin) -> Result<ListKeysResponse, Error> {
let now = now_msec();
let res = garage
.key_table
.get_range(
@@ -25,9 +30,22 @@ impl RequestHandler for ListKeysRequest {
)
.await?
.iter()
.map(|k| ListKeysResponseItem {
id: k.key_id.to_string(),
name: k.params().unwrap().name.get().clone(),
.map(|k| {
let p = k.params().unwrap();
ListKeysResponseItem {
id: k.key_id.to_string(),
name: p.name.get().clone(),
created: p.created.map(|x| {
DateTime::from_timestamp_millis(x as i64)
.expect("invalid timestamp stored in db")
}),
expiration: p.expiration.get().map(|x| {
DateTime::from_timestamp_millis(x as i64)
.expect("invalid timestamp stored in db")
}),
expired: p.is_expired(now),
}
})
.collect::<Vec<_>>();
@@ -205,6 +223,13 @@ async fn key_info_results(
let res = GetKeyInfoResponse {
name: key_state.name.get().clone(),
created: key_state.created.map(|x| {
DateTime::from_timestamp_millis(x as i64).expect("invalid timestamp stored in db")
}),
expiration: key_state.expiration.get().map(|x| {
DateTime::from_timestamp_millis(x as i64).expect("invalid timestamp stored in db")
}),
expired: key_state.is_expired(now_msec()),
access_key_id: key.key_id.clone(),
secret_access_key: if show_secret {
Some(key_state.secret_key.clone())
+8
View File
@@ -9,6 +9,7 @@ use sha2::{Digest, Sha256};
use garage_table::*;
use garage_util::data::Hash;
use garage_util::time::now_msec;
use garage_model::garage::Garage;
use garage_model::key_table::*;
@@ -396,6 +397,13 @@ pub fn verify_v4(
.ok_or_else(|| Error::forbidden(format!("No such key: {}", &auth.key_id)))?;
let key_p = key.params().unwrap();
if key_p.is_expired(now_msec()) {
return Err(Error::forbidden(format!(
"Access key {} has expired",
key.key_id
)));
}
let mut hmac = signing_hmac(
&auth.date,
&key_p.secret_key,