Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a way to obtain package names of loaded policies #239

Merged
merged 1 commit into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/regorus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn read_value_from_json_file(path: &String) -> Result<regorus::Value> {
regorus::Value::from_json_str(&read_file(path)?)
}

fn add_policy_from_file(engine: &mut regorus::Engine, path: String) -> Result<()> {
fn add_policy_from_file(engine: &mut regorus::Engine, path: String) -> Result<String> {
#[cfg(feature = "std")]
return engine.add_policy_from_file(path);

Expand Down Expand Up @@ -65,15 +65,15 @@ fn rego_eval(
_ => continue,
}

add_policy_from_file(&mut engine, entry.path().display().to_string())?;
let _package = add_policy_from_file(&mut engine, entry.path().display().to_string())?;
}
}

// Load given files.
for file in files.iter() {
if file.ends_with(".rego") {
// Read policy file.
add_policy_from_file(&mut engine, file.clone())?;
let _package = add_policy_from_file(&mut engine, file.clone())?;
} else {
// Read data file.
let data = if file.ends_with(".json") {
Expand Down
48 changes: 40 additions & 8 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl Engine {
///
/// The policy file will be parsed and converted to AST representation.
/// Multiple policy files may be added to the engine.
/// Returns the Rego package name declared in the policy.
///
/// * `path`: A filename to be associated with the policy.
/// * `rego`: The rego policy code.
Expand All @@ -52,29 +53,33 @@ impl Engine {
/// # fn main() -> anyhow::Result<()> {
/// let mut engine = Engine::new();
///
/// engine.add_policy(
/// let package = engine.add_policy(
/// "test.rego".to_string(),
/// r#"
/// package test
/// allow = input.user == "root"
/// "#.to_string())?;
///
/// assert_eq!(package, "data.test");
/// # Ok(())
/// # }
/// ```
///
pub fn add_policy(&mut self, path: String, rego: String) -> Result<()> {
pub fn add_policy(&mut self, path: String, rego: String) -> Result<String> {
let source = Source::from_contents(path, rego)?;
let mut parser = Parser::new(&source)?;
self.modules.push(Ref::new(parser.parse()?));
let module = Ref::new(parser.parse()?);
self.modules.push(module.clone());
// if policies change, interpreter needs to be prepared again
self.prepared = false;
Ok(())
Interpreter::get_path_string(&module.package.refr, Some("data"))
}

/// Add a policy from a given file.
///
/// The policy file will be parsed and converted to AST representation.
/// Multiple policy files may be added to the engine.
/// Returns the Rego package name declared in the policy.
///
/// * `path`: Path to the policy file (.rego).
///
Expand All @@ -83,17 +88,44 @@ impl Engine {
/// # fn main() -> anyhow::Result<()> {
/// let mut engine = Engine::new();
///
/// engine.add_policy_from_file("tests/aci/framework.rego")?;
/// let package = engine.add_policy_from_file("tests/aci/framework.rego")?;
///
/// assert_eq!(package, "data.framework");
/// # Ok(())
/// # }
/// ```
#[cfg(feature = "std")]
pub fn add_policy_from_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<()> {
pub fn add_policy_from_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<String> {
let source = Source::from_file(path)?;
let mut parser = Parser::new(&source)?;
self.modules.push(Ref::new(parser.parse()?));
let module = Ref::new(parser.parse()?);
self.modules.push(module.clone());
// if policies change, interpreter needs to be prepared again
self.prepared = false;
Ok(())
Interpreter::get_path_string(&module.package.refr, Some("data"))
}

/// Get the list of packages defined by loaded policies.
///
/// ```
/// # use regorus::*;
/// # fn main() -> anyhow::Result<()> {
/// let mut engine = Engine::new();
///
/// let _ = engine.add_policy_from_file("tests/aci/framework.rego")?;
///
/// // Package names can be different from file names.
/// let _ = engine.add_policy("policy.rego".into(), "package hello.world".into())?;
///
/// assert_eq!(engine.get_packages()?, vec!["data.framework", "data.hello.world"]);
/// # Ok(())
/// # }
/// ```
pub fn get_packages(&self) -> Result<Vec<String>> {
self.modules
.iter()
.map(|m| Interpreter::get_path_string(&m.package.refr, Some("data")))
.collect()
}

/// Set the input document.
Expand Down
Loading