Skip to content

Commit 32e4064

Browse files
committed
feat: Improve package name handling in OpaConfig (#447)
## Description Leading forward slashes are removed. Dots are converted to forward slashes. This is done in the `document_url` function, therefore the sanitization is done on each call. Introducing a constructor and getters to perform the sanitization at most once would be a breaking change, therefore not considered.
1 parent e39f622 commit 32e4064

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

src/commons/opa.rs

+55-1
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,16 @@ use crate::error;
4848
use crate::error::OperatorResult;
4949
use k8s_openapi::api::core::v1::ConfigMap;
5050
use kube::ResourceExt;
51+
use lazy_static::lazy_static;
52+
use regex::Regex;
5153
use schemars::{self, JsonSchema};
5254
use serde::{Deserialize, Serialize};
5355

56+
lazy_static! {
57+
static ref DOT_REGEX: Regex = Regex::new("\\.").unwrap();
58+
/// To remove leading slashes from OPA package name (if present)
59+
static ref LEADING_SLASH_REGEX: Regex = Regex::new("(/*)(.*)").unwrap();
60+
}
5461
/// Indicates the OPA API version. This is required to choose the correct
5562
/// path when constructing the OPA urls to query.
5663
pub enum OpaApiVersion {
@@ -101,7 +108,7 @@ impl OpaConfig {
101108
T: ResourceExt,
102109
{
103110
let package_name = match &self.package {
104-
Some(p) => p.to_string(),
111+
Some(p) => Self::sanitize_opa_package_name(p),
105112
None => resource.name_any(),
106113
};
107114

@@ -212,6 +219,17 @@ impl OpaConfig {
212219
configmap_name: self.config_map_name.clone(),
213220
})
214221
}
222+
223+
/// Removes leading slashes from OPA package name. Dots are converted to forward slashes.
224+
///
225+
/// # Arguments
226+
/// * `package_name` - Package name to sanitize
227+
fn sanitize_opa_package_name(package_name: &str) -> String {
228+
// Package names starting with one or more slashes cause the resulting URL to be invalid, hence removed.
229+
let no_leading_slashes = LEADING_SLASH_REGEX.replace_all(package_name, "$2");
230+
// All dots must be replaced with forward slashes in order for the URL to be a valid resource
231+
DOT_REGEX.replace_all(&no_leading_slashes, "/").to_string()
232+
}
215233
}
216234

217235
#[cfg(test)]
@@ -316,4 +334,40 @@ mod tests {
316334
package: package.map(|p| p.to_string()),
317335
}
318336
}
337+
338+
#[test]
339+
fn test_opa_package_name_sanitizer() {
340+
// No sanitization needed
341+
assert_eq!(
342+
OpaConfig::sanitize_opa_package_name("kafka/authz"),
343+
"kafka/authz"
344+
);
345+
346+
// Remove single leading slash and convert dot to slash
347+
assert_eq!(
348+
OpaConfig::sanitize_opa_package_name("/kafka.authz"),
349+
"kafka/authz"
350+
);
351+
352+
// Remove multiple leading slashes and convert dot
353+
assert_eq!(
354+
OpaConfig::sanitize_opa_package_name("////kafka.authz"),
355+
"kafka/authz"
356+
);
357+
}
358+
359+
#[test]
360+
fn test_opa_document_url_sanitization() {
361+
let opa_config = OpaConfig {
362+
config_map_name: "simple-opa".to_owned(),
363+
package: Some("///kafka.authz".to_owned()),
364+
};
365+
366+
let document_url = opa_config.document_url(
367+
&k8s_openapi::api::core::v1::Pod::default(),
368+
None,
369+
OpaApiVersion::V1,
370+
);
371+
assert_eq!(document_url, "v1/data/kafka/authz")
372+
}
319373
}

0 commit comments

Comments
 (0)