mirror of
https://git.deuxfleurs.fr/Deuxfleurs/garage.git
synced 2026-05-05 10:56:15 +02:00
possibility to update access key expiration date
This commit is contained in:
parent
c56b7e20c3
commit
590c9bb4db
@ -2162,15 +2162,7 @@
|
||||
"$ref": "#/components/schemas/GetBucketInfoResponse"
|
||||
},
|
||||
"CreateKeyRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
"$ref": "#/components/schemas/UpdateKeyRequestBody"
|
||||
},
|
||||
"CreateKeyResponse": {
|
||||
"$ref": "#/components/schemas/GetKeyInfoResponse"
|
||||
@ -4115,7 +4107,8 @@
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/KeyPerm"
|
||||
"$ref": "#/components/schemas/KeyPerm",
|
||||
"description": "Permissions to allow for the key"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -4125,15 +4118,25 @@
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/KeyPerm"
|
||||
"$ref": "#/components/schemas/KeyPerm",
|
||||
"description": "Permissions to deny for the key"
|
||||
}
|
||||
]
|
||||
},
|
||||
"expiration": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "date-time",
|
||||
"description": "Expiration time and date, formatted according to RFC 3339"
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
],
|
||||
"description": "Name of the API key"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -701,9 +701,7 @@ pub struct ApiBucketKeyPerm {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateKeyRequest {
|
||||
pub name: Option<String>,
|
||||
}
|
||||
pub struct CreateKeyRequest(pub UpdateKeyRequestBody);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
pub struct CreateKeyResponse(pub GetKeyInfoResponse);
|
||||
@ -735,8 +733,13 @@ pub struct UpdateKeyResponse(pub GetKeyInfoResponse);
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateKeyRequestBody {
|
||||
/// Name of the API key
|
||||
pub name: Option<String>,
|
||||
/// Expiration time and date, formatted according to RFC 3339
|
||||
pub expiration: Option<DateTime<Utc>>,
|
||||
/// Permissions to allow for the key
|
||||
pub allow: Option<KeyPerm>,
|
||||
/// Permissions to deny for the key
|
||||
pub deny: Option<KeyPerm>,
|
||||
}
|
||||
|
||||
|
||||
@ -103,7 +103,10 @@ impl RequestHandler for CreateKeyRequest {
|
||||
garage: &Arc<Garage>,
|
||||
_admin: &Admin,
|
||||
) -> Result<CreateKeyResponse, Error> {
|
||||
let key = Key::new(self.name.as_deref().unwrap_or("Unnamed key"));
|
||||
let mut key = Key::new("Unnamed key");
|
||||
|
||||
apply_key_updates(&mut key, self.0);
|
||||
|
||||
garage.key_table.insert(&key).await?;
|
||||
|
||||
Ok(CreateKeyResponse(
|
||||
@ -149,21 +152,7 @@ impl RequestHandler for UpdateKeyRequest {
|
||||
) -> Result<UpdateKeyResponse, Error> {
|
||||
let mut key = garage.key_helper().get_existing_key(&self.id).await?;
|
||||
|
||||
let key_state = key.state.as_option_mut().unwrap();
|
||||
|
||||
if let Some(new_name) = self.body.name {
|
||||
key_state.name.update(new_name);
|
||||
}
|
||||
if let Some(allow) = self.body.allow {
|
||||
if allow.create_bucket {
|
||||
key_state.allow_create_bucket.update(true);
|
||||
}
|
||||
}
|
||||
if let Some(deny) = self.body.deny {
|
||||
if deny.create_bucket {
|
||||
key_state.allow_create_bucket.update(false);
|
||||
}
|
||||
}
|
||||
apply_key_updates(&mut key, self.body);
|
||||
|
||||
garage.key_table.insert(&key).await?;
|
||||
|
||||
@ -275,3 +264,26 @@ async fn key_info_results(
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn apply_key_updates(key: &mut Key, updates: UpdateKeyRequestBody) {
|
||||
let key_state = key.state.as_option_mut().unwrap();
|
||||
|
||||
if let Some(new_name) = updates.name {
|
||||
key_state.name.update(new_name);
|
||||
}
|
||||
if let Some(expiration) = updates.expiration {
|
||||
key_state
|
||||
.expiration
|
||||
.update(Some(expiration.timestamp_millis() as u64));
|
||||
}
|
||||
if let Some(allow) = updates.allow {
|
||||
if allow.create_bucket {
|
||||
key_state.allow_create_bucket.update(true);
|
||||
}
|
||||
}
|
||||
if let Some(deny) = updates.deny {
|
||||
if deny.create_bucket {
|
||||
key_state.allow_create_bucket.update(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use format_table::format_table;
|
||||
|
||||
use chrono::Local;
|
||||
use chrono::{Local, Utc};
|
||||
|
||||
use garage_util::error::*;
|
||||
|
||||
@ -16,6 +16,7 @@ impl Cli {
|
||||
KeyOperation::Info(query) => self.cmd_key_info(query).await,
|
||||
KeyOperation::Create(query) => self.cmd_create_key(query).await,
|
||||
KeyOperation::Rename(query) => self.cmd_rename_key(query).await,
|
||||
KeyOperation::Set(opt) => self.cmd_update_key(opt).await,
|
||||
KeyOperation::Delete(query) => self.cmd_delete_key(query).await,
|
||||
KeyOperation::Allow(query) => self.cmd_allow_key(query).await,
|
||||
KeyOperation::Deny(query) => self.cmd_deny_key(query).await,
|
||||
@ -68,9 +69,17 @@ impl Cli {
|
||||
|
||||
pub async fn cmd_create_key(&self, opt: KeyNewOpt) -> Result<(), Error> {
|
||||
let key = self
|
||||
.api_request(CreateKeyRequest {
|
||||
.api_request(CreateKeyRequest(UpdateKeyRequestBody {
|
||||
name: Some(opt.name),
|
||||
})
|
||||
expiration: opt
|
||||
.expires_in
|
||||
.map(|x| parse_duration::parse::parse(&x))
|
||||
.transpose()
|
||||
.ok_or_message("Invalid duration passed for --expires-in parameter")?
|
||||
.map(|dur| Utc::now() + dur),
|
||||
allow: None,
|
||||
deny: None,
|
||||
}))
|
||||
.await?;
|
||||
|
||||
print_key_info(&key.0);
|
||||
@ -92,6 +101,38 @@ impl Cli {
|
||||
id: key.access_key_id,
|
||||
body: UpdateKeyRequestBody {
|
||||
name: Some(opt.new_name),
|
||||
expiration: None,
|
||||
allow: None,
|
||||
deny: None,
|
||||
},
|
||||
})
|
||||
.await?;
|
||||
|
||||
print_key_info(&new_key.0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cmd_update_key(&self, opt: KeySetOpt) -> Result<(), Error> {
|
||||
let key = self
|
||||
.api_request(GetKeyInfoRequest {
|
||||
id: None,
|
||||
search: Some(opt.key_pattern),
|
||||
show_secret_key: false,
|
||||
})
|
||||
.await?;
|
||||
|
||||
let new_key = self
|
||||
.api_request(UpdateKeyRequest {
|
||||
id: key.access_key_id,
|
||||
body: UpdateKeyRequestBody {
|
||||
name: None,
|
||||
expiration: opt
|
||||
.expires_in
|
||||
.map(|x| parse_duration::parse::parse(&x))
|
||||
.transpose()
|
||||
.ok_or_message("Invalid duration passed for --expires-in parameter")?
|
||||
.map(|dur| Utc::now() + dur),
|
||||
allow: None,
|
||||
deny: None,
|
||||
},
|
||||
@ -143,6 +184,7 @@ impl Cli {
|
||||
id: key.access_key_id,
|
||||
body: UpdateKeyRequestBody {
|
||||
name: None,
|
||||
expiration: None,
|
||||
allow: Some(KeyPerm {
|
||||
create_bucket: opt.create_bucket,
|
||||
}),
|
||||
@ -170,6 +212,7 @@ impl Cli {
|
||||
id: key.access_key_id,
|
||||
body: UpdateKeyRequestBody {
|
||||
name: None,
|
||||
expiration: None,
|
||||
allow: None,
|
||||
deny: Some(KeyPerm {
|
||||
create_bucket: opt.create_bucket,
|
||||
|
||||
@ -426,6 +426,10 @@ pub enum KeyOperation {
|
||||
/// Import key
|
||||
#[structopt(name = "import", version = garage_version())]
|
||||
Import(KeyImportOpt),
|
||||
|
||||
/// Set parameters for an access key
|
||||
#[structopt(name = "set", version = garage_version())]
|
||||
Set(KeySetOpt),
|
||||
}
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
@ -442,6 +446,21 @@ pub struct KeyNewOpt {
|
||||
/// Name of the key
|
||||
#[structopt(default_value = "Unnamed key")]
|
||||
pub name: String,
|
||||
/// Set an expiration time for the access key
|
||||
/// (see docs.rs/parse_duration for date format)
|
||||
#[structopt(long = "expires-in")]
|
||||
pub expires_in: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
pub struct KeySetOpt {
|
||||
/// ID or name of the key
|
||||
pub key_pattern: String,
|
||||
|
||||
/// Set an expiration time for the access key
|
||||
/// (see docs.rs/parse_duration for date format)
|
||||
#[structopt(long = "expires-in")]
|
||||
pub expires_in: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user