mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-08 22:03:13 +00:00
add never_expires to remove expiration dates of admin tokens and access keys
This commit is contained in:
@@ -4006,6 +4006,10 @@
|
||||
],
|
||||
"description": "Name of the admin API token"
|
||||
},
|
||||
"neverExpires": {
|
||||
"type": "boolean",
|
||||
"description": "Set the admin token to never expire"
|
||||
},
|
||||
"scope": {
|
||||
"type": [
|
||||
"array",
|
||||
@@ -4137,6 +4141,10 @@
|
||||
"null"
|
||||
],
|
||||
"description": "Name of the API key"
|
||||
},
|
||||
"neverExpires": {
|
||||
"type": "boolean",
|
||||
"description": "Set the access key to never expire"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -124,7 +124,7 @@ impl RequestHandler for CreateAdminTokenRequest {
|
||||
AdminApiToken::new(&format!("token_{}", Utc::now().format("%Y%m%d_%H%M")))
|
||||
};
|
||||
|
||||
apply_token_updates(&mut token, self.0);
|
||||
apply_token_updates(&mut token, self.0)?;
|
||||
|
||||
garage.admin_token_table.insert(&token).await?;
|
||||
|
||||
@@ -145,7 +145,7 @@ impl RequestHandler for UpdateAdminTokenRequest {
|
||||
) -> Result<UpdateAdminTokenResponse, Error> {
|
||||
let mut token = get_existing_admin_token(&garage, &self.id).await?;
|
||||
|
||||
apply_token_updates(&mut token, self.body);
|
||||
apply_token_updates(&mut token, self.body)?;
|
||||
|
||||
garage.admin_token_table.insert(&token).await?;
|
||||
|
||||
@@ -204,7 +204,16 @@ async fn get_existing_admin_token(garage: &Garage, id: &String) -> Result<AdminA
|
||||
.ok_or_else(|| Error::NoSuchAdminToken(id.to_string()))
|
||||
}
|
||||
|
||||
fn apply_token_updates(token: &mut AdminApiToken, updates: UpdateAdminTokenRequestBody) {
|
||||
fn apply_token_updates(
|
||||
token: &mut AdminApiToken,
|
||||
updates: UpdateAdminTokenRequestBody,
|
||||
) -> Result<(), Error> {
|
||||
if updates.never_expires && updates.expiration.is_some() {
|
||||
return Err(Error::bad_request(
|
||||
"cannot specify `expiration` and `never_expires`",
|
||||
));
|
||||
}
|
||||
|
||||
let params = token.params_mut().unwrap();
|
||||
|
||||
if let Some(name) = updates.name {
|
||||
@@ -215,7 +224,12 @@ fn apply_token_updates(token: &mut AdminApiToken, updates: UpdateAdminTokenReque
|
||||
.expiration
|
||||
.update(Some(expiration.timestamp_millis() as u64));
|
||||
}
|
||||
if updates.never_expires {
|
||||
params.expiration.update(None);
|
||||
}
|
||||
if let Some(scope) = updates.scope {
|
||||
params.scope.update(AdminApiTokenScope(scope));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -366,6 +366,9 @@ pub struct UpdateAdminTokenRequestBody {
|
||||
pub name: Option<String>,
|
||||
/// Expiration time and date, formatted according to RFC 3339
|
||||
pub expiration: Option<DateTime<Utc>>,
|
||||
/// Set the admin token to never expire
|
||||
#[serde(default)]
|
||||
pub never_expires: bool,
|
||||
/// Scope of the admin API token, a list of admin endpoint names (such as
|
||||
/// `GetClusterStatus`, etc), or the special value `*` to allow all
|
||||
/// admin endpoints. **WARNING:** Granting a scope of `CreateAdminToken` or
|
||||
@@ -737,6 +740,9 @@ pub struct UpdateKeyRequestBody {
|
||||
pub name: Option<String>,
|
||||
/// Expiration time and date, formatted according to RFC 3339
|
||||
pub expiration: Option<DateTime<Utc>>,
|
||||
/// Set the access key to never expire
|
||||
#[serde(default)]
|
||||
pub never_expires: bool,
|
||||
/// Permissions to allow for the key
|
||||
pub allow: Option<KeyPerm>,
|
||||
/// Permissions to deny for the key
|
||||
|
||||
+14
-3
@@ -105,7 +105,7 @@ impl RequestHandler for CreateKeyRequest {
|
||||
) -> Result<CreateKeyResponse, Error> {
|
||||
let mut key = Key::new("Unnamed key");
|
||||
|
||||
apply_key_updates(&mut key, self.0);
|
||||
apply_key_updates(&mut key, self.0)?;
|
||||
|
||||
garage.key_table.insert(&key).await?;
|
||||
|
||||
@@ -152,7 +152,7 @@ impl RequestHandler for UpdateKeyRequest {
|
||||
) -> Result<UpdateKeyResponse, Error> {
|
||||
let mut key = garage.key_helper().get_existing_key(&self.id).await?;
|
||||
|
||||
apply_key_updates(&mut key, self.body);
|
||||
apply_key_updates(&mut key, self.body)?;
|
||||
|
||||
garage.key_table.insert(&key).await?;
|
||||
|
||||
@@ -265,7 +265,13 @@ async fn key_info_results(
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn apply_key_updates(key: &mut Key, updates: UpdateKeyRequestBody) {
|
||||
fn apply_key_updates(key: &mut Key, updates: UpdateKeyRequestBody) -> Result<(), Error> {
|
||||
if updates.never_expires && updates.expiration.is_some() {
|
||||
return Err(Error::bad_request(
|
||||
"cannot specify `expiration` and `never_expires`",
|
||||
));
|
||||
}
|
||||
|
||||
let key_state = key.state.as_option_mut().unwrap();
|
||||
|
||||
if let Some(new_name) = updates.name {
|
||||
@@ -276,6 +282,9 @@ fn apply_key_updates(key: &mut Key, updates: UpdateKeyRequestBody) {
|
||||
.expiration
|
||||
.update(Some(expiration.timestamp_millis() as u64));
|
||||
}
|
||||
if updates.never_expires {
|
||||
key_state.expiration.update(None);
|
||||
}
|
||||
if let Some(allow) = updates.allow {
|
||||
if allow.create_bucket {
|
||||
key_state.allow_create_bucket.update(true);
|
||||
@@ -286,4 +295,6 @@ fn apply_key_updates(key: &mut Key, updates: UpdateKeyRequestBody) {
|
||||
key_state.allow_create_bucket.update(false);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ impl Cli {
|
||||
.transpose()
|
||||
.ok_or_message("Invalid duration passed for --expires-in parameter")?
|
||||
.map(|dur| Utc::now() + dur),
|
||||
never_expires: false,
|
||||
scope: opt.scope.map(|s| {
|
||||
s.split(",")
|
||||
.map(|x| x.trim().to_string())
|
||||
@@ -121,6 +122,7 @@ impl Cli {
|
||||
body: UpdateAdminTokenRequestBody {
|
||||
name: Some(new),
|
||||
expiration: None,
|
||||
never_expires: false,
|
||||
scope: None,
|
||||
},
|
||||
})
|
||||
@@ -150,6 +152,7 @@ impl Cli {
|
||||
.transpose()
|
||||
.ok_or_message("Invalid duration passed for --expires-in parameter")?
|
||||
.map(|dur| Utc::now() + dur),
|
||||
never_expires: opt.never_expires,
|
||||
scope: opt.scope.map({
|
||||
let mut new_scope = token.scope;
|
||||
|scope_str| {
|
||||
|
||||
@@ -77,6 +77,7 @@ impl Cli {
|
||||
.transpose()
|
||||
.ok_or_message("Invalid duration passed for --expires-in parameter")?
|
||||
.map(|dur| Utc::now() + dur),
|
||||
never_expires: false,
|
||||
allow: None,
|
||||
deny: None,
|
||||
}))
|
||||
@@ -102,6 +103,7 @@ impl Cli {
|
||||
body: UpdateKeyRequestBody {
|
||||
name: Some(opt.new_name),
|
||||
expiration: None,
|
||||
never_expires: false,
|
||||
allow: None,
|
||||
deny: None,
|
||||
},
|
||||
@@ -133,6 +135,7 @@ impl Cli {
|
||||
.transpose()
|
||||
.ok_or_message("Invalid duration passed for --expires-in parameter")?
|
||||
.map(|dur| Utc::now() + dur),
|
||||
never_expires: opt.never_expires,
|
||||
allow: None,
|
||||
deny: None,
|
||||
},
|
||||
@@ -185,6 +188,7 @@ impl Cli {
|
||||
body: UpdateKeyRequestBody {
|
||||
name: None,
|
||||
expiration: None,
|
||||
never_expires: false,
|
||||
allow: Some(KeyPerm {
|
||||
create_bucket: opt.create_bucket,
|
||||
}),
|
||||
@@ -213,6 +217,7 @@ impl Cli {
|
||||
body: UpdateKeyRequestBody {
|
||||
name: None,
|
||||
expiration: None,
|
||||
never_expires: false,
|
||||
allow: None,
|
||||
deny: Some(KeyPerm {
|
||||
create_bucket: opt.create_bucket,
|
||||
|
||||
@@ -461,6 +461,9 @@ pub struct KeySetOpt {
|
||||
/// (see docs.rs/parse_duration for date format)
|
||||
#[structopt(long = "expires-in")]
|
||||
pub expires_in: Option<String>,
|
||||
/// Set the access key to never expire
|
||||
#[structopt(long = "never-expires")]
|
||||
pub never_expires: bool,
|
||||
}
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
@@ -587,10 +590,15 @@ pub struct AdminTokenCreateOp {
|
||||
pub struct AdminTokenSetOp {
|
||||
/// Name or prefix of the ID of the token to modify
|
||||
pub api_token: String,
|
||||
|
||||
/// Set an expiration time for the token (see docs.rs/parse_duration for date
|
||||
/// format)
|
||||
#[structopt(long = "expires-in")]
|
||||
pub expires_in: Option<String>,
|
||||
/// Set the token to never expire
|
||||
#[structopt(long = "never-expires")]
|
||||
pub never_expires: bool,
|
||||
|
||||
/// Set a limited scope for the token, as a comma-separated list of
|
||||
/// admin API functions (e.g. GetClusterStatus, etc.), or `*` to allow
|
||||
/// all admin API functions.
|
||||
|
||||
Reference in New Issue
Block a user