Skip to content

Commit 47f798f

Browse files
authored
fix: tenant id validation (#1740)
* fix: tenant id validation Restrict DEFAULT_TENANT, and non-alphanumeric characters as tenant id * coderabbit suggestions
1 parent 26de34e commit 47f798f

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

‎src/parseable/mod.rs‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::{
2222
num::NonZeroU32,
2323
path::PathBuf,
2424
str::FromStr,
25-
sync::{Arc, RwLock},
25+
sync::{Arc, LazyLock, RwLock},
2626
};
2727

2828
use actix_web::http::{
@@ -34,6 +34,7 @@ use bytes::Bytes;
3434
use chrono::Utc;
3535
use clap::{Parser, error::ErrorKind};
3636
use once_cell::sync::{Lazy, OnceCell};
37+
use regex::Regex;
3738
use relative_path::RelativePathBuf;
3839
pub use staging::StagingError;
3940
use streams::StreamRef;
@@ -102,6 +103,23 @@ pub const STREAM_EXISTS: &str = "Stream exists";
102103
/// OnceCell to return metastore
103104
pub static METASTORE: OnceCell<Arc<dyn Metastore>> = OnceCell::new();
104105

106+
/// LazyLock for tenant id regex
107+
pub static TENANT_ID_REGEX: LazyLock<Regex> = LazyLock::new(|| {
108+
regex::RegexBuilder::new(r"^[a-zA-Z0-9][a-zA-Z0-9_-]{0,35}$")
109+
.build()
110+
.expect("Unable to create tenant id validation regex")
111+
});
112+
113+
pub fn validate_tenant_id(tenant_id: &str) -> Result<(), String> {
114+
if !TENANT_ID_REGEX.is_match(tenant_id) {
115+
return Err("tenant ID should follow regex- ^[a-zA-Z0-9][a-zA-Z0-9_-]{0,35}$".into());
116+
}
117+
if tenant_id.eq(DEFAULT_TENANT) {
118+
return Err(format!("tenant ID can't be {DEFAULT_TENANT}"));
119+
}
120+
Ok(())
121+
}
122+
105123
/// For OTel log sources the telemetry_type is fully determined by the log_source.
106124
/// When the user explicitly sets x-p-telemetry-type and it disagrees with the
107125
/// implied type for an otel-* source, reject the request. When they don't set it,
@@ -1165,7 +1183,7 @@ impl Parseable {
11651183
if !self.options.is_multi_tenant() {
11661184
return Err(anyhow::Error::msg("P_MULTI_TENANCY is set to false"));
11671185
}
1168-
1186+
validate_tenant_id(&tenant_id).map_err(|e| anyhow::anyhow!(e))?;
11691187
let mut tenants = self.tenants.write().unwrap();
11701188
if tenants.contains(&tenant_id) {
11711189
return Err(anyhow::Error::msg(format!(
@@ -1266,6 +1284,8 @@ impl Parseable {
12661284
.await?
12671285
&& is_multi_tenant
12681286
{
1287+
// check if tenantID is valid
1288+
validate_tenant_id(&tenant_id).map_err(|e| anyhow::anyhow!(e))?;
12691289
let metadata: StorageMetadata = serde_json::from_slice(&meta)?;
12701290

12711291
TENANT_METADATA.insert_tenant(tenant_id.clone(), metadata.clone());

0 commit comments

Comments
 (0)