Compare commits

..

2 commits

Author SHA1 Message Date
18461d3567 admin api: verify tokens using the new admin api token table
All checks were successful
ci/woodpecker/pr/debug Pipeline was successful
ci/woodpecker/push/debug Pipeline was successful
2025-03-11 13:50:04 +01:00
5b1f5627c1 add model for admin key table 2025-03-11 13:50:04 +01:00
4 changed files with 32 additions and 32 deletions

View file

@ -274,7 +274,7 @@ async fn verify_authorization(
let token_hash_string = if let Some((prefix, _)) = token.split_once('.') {
garage
.admin_key_table
.admin_token_table
.get(&EmptyKey, &prefix.to_string())
.await?
.and_then(|k| k.state.into_option())

View file

@ -9,7 +9,7 @@ mod v2 {
use serde::{Deserialize, Serialize};
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct AdminApiKey {
pub struct AdminApiToken {
/// An admin API key is a bearer token of the following form:
/// `<prefix>.<suffix>`
/// Only the prefix is saved here, it is used as a key identifier.
@ -17,11 +17,11 @@ mod v2 {
pub prefix: String,
/// If the key is not deleted, its parameters
pub state: crdt::Deletable<AdminApiKeyParams>,
pub state: crdt::Deletable<AdminApiTokenParams>,
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct AdminApiKeyParams {
pub struct AdminApiTokenParams {
/// The entire API key hashed as a password
pub token_hash: String,
@ -32,20 +32,20 @@ mod v2 {
pub expiration: crdt::Lww<Option<u64>>,
/// The scope of the token, i.e. list of authorized admin API calls
pub scope: crdt::Lww<AdminApiKeyScope>,
pub scope: crdt::Lww<AdminApiTokenScope>,
}
#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct AdminApiKeyScope(pub Vec<String>);
pub struct AdminApiTokenScope(pub Vec<String>);
impl garage_util::migrate::InitialFormat for AdminApiKey {
const VERSION_MARKER: &'static [u8] = b"G2admkey";
impl garage_util::migrate::InitialFormat for AdminApiToken {
const VERSION_MARKER: &'static [u8] = b"G2admtok";
}
}
pub use v2::*;
impl Crdt for AdminApiKeyParams {
impl Crdt for AdminApiTokenParams {
fn merge(&mut self, o: &Self) {
self.name.merge(&o.name);
self.expiration.merge(&o.expiration);
@ -53,21 +53,21 @@ impl Crdt for AdminApiKeyParams {
}
}
impl Crdt for AdminApiKey {
impl Crdt for AdminApiToken {
fn merge(&mut self, other: &Self) {
self.state.merge(&other.state);
}
}
impl Crdt for AdminApiKeyScope {
impl Crdt for AdminApiTokenScope {
fn merge(&mut self, other: &Self) {
self.0.retain(|x| other.0.contains(x));
}
}
impl AdminApiKey {
/// Create a new admin API access key.
/// Returns the AdminApiKey object, which contains the hashed bearer token,
impl AdminApiToken {
/// Create a new admin API token.
/// Returns the AdminApiToken object, which contains the hashed bearer token,
/// as well as the plaintext bearer token.
pub fn new(name: &str) -> (Self, String) {
use argon2::{
@ -86,13 +86,13 @@ impl AdminApiKey {
.expect("could not hash admin API token")
.to_string();
let ret = AdminApiKey {
let ret = AdminApiToken {
prefix,
state: crdt::Deletable::present(AdminApiKeyParams {
state: crdt::Deletable::present(AdminApiTokenParams {
token_hash: hashed_token,
name: crdt::Lww::new(name.to_string()),
expiration: crdt::Lww::new(None),
scope: crdt::Lww::new(AdminApiKeyScope(vec!["*".to_string()])),
scope: crdt::Lww::new(AdminApiTokenScope(vec!["*".to_string()])),
}),
};
@ -112,12 +112,12 @@ impl AdminApiKey {
}
/// Returns an option representing the params (None if in deleted state)
pub fn params(&self) -> Option<&AdminApiKeyParams> {
pub fn params(&self) -> Option<&AdminApiTokenParams> {
self.state.as_option()
}
/// Mutable version of `.state()`
pub fn params_mut(&mut self) -> Option<&mut AdminApiKeyParams> {
pub fn params_mut(&mut self) -> Option<&mut AdminApiTokenParams> {
self.state.as_option_mut()
}
@ -130,7 +130,7 @@ impl AdminApiKey {
}
}
impl Entry<EmptyKey, String> for AdminApiKey {
impl Entry<EmptyKey, String> for AdminApiToken {
fn partition_key(&self) -> &EmptyKey {
&EmptyKey
}
@ -139,14 +139,14 @@ impl Entry<EmptyKey, String> for AdminApiKey {
}
}
pub struct AdminApiKeyTable;
pub struct AdminApiTokenTable;
impl TableSchema for AdminApiKeyTable {
const TABLE_NAME: &'static str = "admin_key";
impl TableSchema for AdminApiTokenTable {
const TABLE_NAME: &'static str = "admin_token";
type P = EmptyKey;
type S = String;
type E = AdminApiKey;
type E = AdminApiToken;
type Filter = KeyFilter;
fn matches_filter(entry: &Self::E, filter: &Self::Filter) -> bool {

View file

@ -24,7 +24,7 @@ use crate::s3::mpu_table::*;
use crate::s3::object_table::*;
use crate::s3::version_table::*;
use crate::admin_key_table::*;
use crate::admin_token_table::*;
use crate::bucket_alias_table::*;
use crate::bucket_table::*;
use crate::helper;
@ -52,7 +52,7 @@ pub struct Garage {
pub block_manager: Arc<BlockManager>,
/// Table containing admin API keys
pub admin_key_table: Arc<Table<AdminApiKeyTable, TableFullReplication>>,
pub admin_token_table: Arc<Table<AdminApiTokenTable, TableFullReplication>>,
/// Table containing buckets
pub bucket_table: Arc<Table<BucketTable, TableFullReplication>>,
/// Table containing bucket aliases
@ -177,9 +177,9 @@ impl Garage {
block_manager.register_bg_vars(&mut bg_vars);
// ---- admin tables ----
info!("Initialize admin_key_table...");
let admin_key_table = Table::new(
AdminApiKeyTable,
info!("Initialize admin_token_table...");
let admin_token_table = Table::new(
AdminApiTokenTable,
control_rep_param.clone(),
system.clone(),
&db,
@ -274,7 +274,7 @@ impl Garage {
db,
system,
block_manager,
admin_key_table,
admin_token_table,
bucket_table,
bucket_alias_table,
key_table,
@ -294,7 +294,7 @@ impl Garage {
pub fn spawn_workers(self: &Arc<Self>, bg: &BackgroundRunner) -> Result<(), Error> {
self.block_manager.spawn_workers(bg);
self.admin_key_table.spawn_workers(bg);
self.admin_token_table.spawn_workers(bg);
self.bucket_table.spawn_workers(bg);
self.bucket_alias_table.spawn_workers(bg);
self.key_table.spawn_workers(bg);

View file

@ -5,7 +5,7 @@ pub mod permission;
pub mod index_counter;
pub mod admin_key_table;
pub mod admin_token_table;
pub mod bucket_alias_table;
pub mod bucket_table;
pub mod key_table;