allow punnycode in bucket name

This commit is contained in:
trinity-1686a
2025-05-19 18:07:04 +02:00
parent a2a9e3cec4
commit 539af12d21
6 changed files with 19 additions and 18 deletions
+2 -2
View File
@@ -277,7 +277,7 @@ pub async fn handle_create_bucket(
let helper = garage.locked_helper().await;
if let Some(ga) = &req.global_alias {
if !is_valid_bucket_name(ga) {
if !is_valid_bucket_name(ga, garage.config.allow_punnycode) {
return Err(Error::bad_request(format!(
"{}: {}",
ga, INVALID_BUCKET_NAME_MESSAGE
@@ -292,7 +292,7 @@ pub async fn handle_create_bucket(
}
if let Some(la) = &req.local_alias {
if !is_valid_bucket_name(&la.alias) {
if !is_valid_bucket_name(&la.alias, garage.config.allow_punnycode) {
return Err(Error::bad_request(format!(
"{}: {}",
la.alias, INVALID_BUCKET_NAME_MESSAGE
+1 -1
View File
@@ -172,7 +172,7 @@ pub async fn handle_create_bucket(
}
// Create the bucket!
if !is_valid_bucket_name(&bucket_name) {
if !is_valid_bucket_name(&bucket_name, garage.config.allow_punnycode) {
return Err(Error::bad_request(format!(
"{}: {}",
bucket_name, INVALID_BUCKET_NAME_MESSAGE
+1 -1
View File
@@ -126,7 +126,7 @@ impl AdminRpcHandler {
#[allow(clippy::ptr_arg)]
async fn handle_create_bucket(&self, name: &String) -> Result<AdminRpc, Error> {
if !is_valid_bucket_name(name) {
if !is_valid_bucket_name(name, self.garage.config.allow_punnycode) {
return Err(Error::BadRequest(format!(
"{}: {}",
name, INVALID_BUCKET_NAME_MESSAGE
+8 -10
View File
@@ -22,14 +22,10 @@ mod v08 {
pub use v08::*;
impl BucketAlias {
pub fn new(name: String, ts: u64, bucket_id: Option<Uuid>) -> Option<Self> {
if !is_valid_bucket_name(&name) {
None
} else {
Some(BucketAlias {
name,
state: crdt::Lww::raw(ts, bucket_id),
})
pub fn new(name: String, ts: u64, bucket_id: Option<Uuid>) -> Self {
BucketAlias {
name,
state: crdt::Lww::raw(ts, bucket_id),
}
}
@@ -80,7 +76,7 @@ impl TableSchema for BucketAliasTable {
/// In the case of Garage, bucket names must not be hex-encoded
/// 32 byte string, which is excluded thanks to the
/// maximum length of 63 bytes given in the spec.
pub fn is_valid_bucket_name(n: &str) -> bool {
pub fn is_valid_bucket_name(n: &str, punny: bool) -> bool {
// Bucket names must be between 3 and 63 characters
n.len() >= 3 && n.len() <= 63
// Bucket names must be composed of lowercase letters, numbers,
@@ -92,7 +88,9 @@ pub fn is_valid_bucket_name(n: &str) -> bool {
// Bucket names must not be formatted as an IP address
&& n.parse::<std::net::IpAddr>().is_err()
// Bucket names must not start with "xn--"
&& !n.starts_with("xn--")
&& (!n.starts_with("xn--") || punny)
// We are a bit stricter, to properly restrict punnycode in all labels
&& (!n.contains(".xn--") || punny)
// Bucket names must not end with "-s3alias"
&& !n.ends_with("-s3alias")
}
+3 -4
View File
@@ -57,7 +57,7 @@ impl<'a> LockedHelper<'a> {
bucket_id: Uuid,
alias_name: &String,
) -> Result<(), Error> {
if !is_valid_bucket_name(alias_name) {
if !is_valid_bucket_name(alias_name, self.0.config.allow_punnycode) {
return Err(Error::InvalidBucketName(alias_name.to_string()));
}
@@ -88,8 +88,7 @@ impl<'a> LockedHelper<'a> {
// writes are now done and all writes use timestamp alias_ts
let alias = match alias {
None => BucketAlias::new(alias_name.clone(), alias_ts, Some(bucket_id))
.ok_or_else(|| Error::InvalidBucketName(alias_name.clone()))?,
None => BucketAlias::new(alias_name.clone(), alias_ts, Some(bucket_id)),
Some(mut a) => {
a.state = Lww::raw(alias_ts, Some(bucket_id));
a
@@ -218,7 +217,7 @@ impl<'a> LockedHelper<'a> {
) -> Result<(), Error> {
let key_helper = KeyHelper(self.0);
if !is_valid_bucket_name(alias_name) {
if !is_valid_bucket_name(alias_name, self.0.config.allow_punnycode) {
return Err(Error::InvalidBucketName(alias_name.to_string()));
}
+4
View File
@@ -135,6 +135,10 @@ pub struct Config {
/// Configuration for the admin API endpoint
#[serde(default = "Default::default")]
pub admin: AdminConfig,
/// Allow punnycode in bucket names
#[serde(default)]
pub allow_punnycode: bool,
}
/// Value for data_dir: either a single directory or a list of dirs with attributes