Skip to content
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
2 changes: 2 additions & 0 deletions cedar-policy-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

## 2.4.6

## 2.4.5

## 2.4.4
Expand Down
6 changes: 3 additions & 3 deletions cedar-policy-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cedar-policy-cli"
edition = "2021"

version = "2.4.5"
version = "2.4.6"
license = "Apache-2.0"
categories = ["compilers", "config"]
description = "CLI interface for the Cedar Policy language."
Expand All @@ -11,8 +11,8 @@ homepage = "https://cedarpolicy.com"
repository = "https://github.com/cedar-policy/cedar"

[dependencies]
cedar-policy = { version = "=2.4.5", path = "../cedar-policy" }
cedar-policy-formatter = { version = "=2.4.5", path = "../cedar-policy-formatter" }
cedar-policy = { version = "=2.4.6", path = "../cedar-policy" }
cedar-policy-formatter = { version = "=2.4.6", path = "../cedar-policy-formatter" }
clap = { version = "4", features = ["derive", "env"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion cedar-policy-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "cedar-policy-core"
edition = "2021"
build = "build.rs"

version = "2.4.5"
version = "2.4.6"
license = "Apache-2.0"
categories = ["compilers", "config"]
description = "Core implemenation of the Cedar Policy language."
Expand Down
4 changes: 2 additions & 2 deletions cedar-policy-formatter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cedar-policy-formatter"
version = "2.4.5"
version = "2.4.6"
edition = "2021"
license = "Apache-2.0"
categories = ["compilers", "config"]
Expand All @@ -10,7 +10,7 @@ homepage = "https://cedarpolicy.com"
repository = "https://github.com/cedar-policy/cedar"

[dependencies]
cedar-policy-core = { version = "=2.4.5", path = "../cedar-policy-core" }
cedar-policy-core = { version = "=2.4.6", path = "../cedar-policy-core" }
pretty = "0.12.1"
logos = "0.13.0"
itertools = "0.10"
Expand Down
90 changes: 77 additions & 13 deletions cedar-policy-formatter/src/pprint/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
* limitations under the License.
*/

use std::collections::BTreeMap;

use miette::{miette, Result, WrapErr};

use cedar_policy_core::ast::{PolicySet, Template};
use cedar_policy_core::ast::PolicySet;
use cedar_policy_core::parser::parse_policyset;
use cedar_policy_core::parser::{err::ParseErrors, text_to_cst::parse_policies};
use smol_str::ToSmolStr;

use crate::token::get_comment;

Expand All @@ -40,24 +43,42 @@ fn tree_to_pretty<T: Doc>(t: &T, context: &mut config::Context<'_>) -> Result<St
}

fn soundness_check(ps: &str, ast: &PolicySet) -> Result<()> {
let formatted_ast = parse_policyset(ps).wrap_err("formatter produces invalid policies")?;
let formatted_ast =
parse_policyset(ps).wrap_err(format!("formatter produced an invalid policy set:\n{ps}"))?;
let (formatted_policies, policies) = (
formatted_ast.templates().collect::<Vec<&Template>>(),
ast.templates().collect::<Vec<&Template>>(),
formatted_ast
.policies()
.map(|p| (p.id().to_smolstr(), p))
.collect::<BTreeMap<_, _>>(),
ast.policies()
.map(|p| (p.id().to_smolstr(), p))
.collect::<BTreeMap<_, _>>(),
);

if formatted_policies.len() != policies.len() {
return Err(miette!("missing formatted policies"));
return Err(miette!(
"formatter changed the number of policies from {} to {}",
policies.len(),
formatted_policies.len()
));
}

for (f_p, p) in formatted_policies.into_iter().zip(policies.into_iter()) {
for ((f_p_id, f_p), (p_id, p)) in formatted_policies.into_iter().zip(policies.into_iter()) {
if f_p_id != p_id {
return Err(miette!(
"formatter changed the policy id from {p_id} to {f_p_id}"
));
}
let (f_anno, anno) = (
f_p.annotations()
.collect::<std::collections::HashMap<_, _>>(),
p.annotations().collect::<std::collections::HashMap<_, _>>(),
);
if !(f_anno == anno
&& f_p.effect() == p.effect()
if f_anno != anno {
return Err(miette!(
"formatter changed the annotations from {anno:?} to {f_anno:?}"
));
}
if !(f_p.effect() == p.effect()
&& f_p.principal_constraint() == p.principal_constraint()
&& f_p.action_constraint() == p.action_constraint()
&& f_p.resource_constraint() == p.resource_constraint()
Expand All @@ -66,9 +87,7 @@ fn soundness_check(ps: &str, ast: &PolicySet) -> Result<()> {
.eq_shape(p.non_head_constraints()))
{
return Err(miette!(
"policies differ:\nformatted: {}\ninput: {}",
f_p,
p
"formatter changed the policy structure:\noriginal:\n{p}\nformatted:\n{f_p}"
));
}
}
Expand Down Expand Up @@ -123,7 +142,9 @@ pub fn policies_str_to_pretty(ps: &str, config: &Config) -> Result<String> {
}
};
// add soundness check to make sure formatting doesn't alter policy ASTs
soundness_check(&formatted_policies, &ast)?;
soundness_check(&formatted_policies, &ast).wrap_err(
"internal error: please file an issue at <https://github.com/cedar-policy/cedar/issues>",
)?;
Ok(formatted_policies)
}

Expand Down Expand Up @@ -166,6 +187,49 @@ mod tests {
);
}

#[test]
fn test_soundness_check() {
let p1 = r#"permit (principal, action, resource)
when { "

a
" };"#;
let p2 = r#"permit (principal, action, resource)
when { "
a
" };"#;
assert!(soundness_check(p2, &parse_policyset(p1).unwrap()).is_err());

let p1 = r#"
permit (principal, action, resource)
when { "a"};
permit (principal, action, resource)
when { "

a
" };"#;
let p2 = r#"
permit (principal, action, resource)
when { "
a
" };
permit (principal, action, resource)
when { "a"};"#;
assert!(soundness_check(p2, &parse_policyset(p1).unwrap()).is_err());

let p1 = r#"
permit (principal, action, resource)
when { "a" };
permit (principal, action, resource)
when { "b" };"#;
let p2 = r#"
permit (principal, action, resource)
when { "a" };
permit (principal, action, resource)
when { "b"};"#;
assert!(soundness_check(p2, &parse_policyset(p1).unwrap()).is_ok());
}

#[test]
fn test_format_files() {
use std::fs::read_to_string;
Expand Down
4 changes: 2 additions & 2 deletions cedar-policy-validator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cedar-policy-validator"
edition = "2021"

version = "2.4.5"
version = "2.4.6"
license = "Apache-2.0"
categories = ["compilers", "config"]
description = "Validator for the Cedar Policy language."
Expand All @@ -11,7 +11,7 @@ homepage = "https://cedarpolicy.com"
repository = "https://github.com/cedar-policy/cedar"

[dependencies]
cedar-policy-core = { version = "=2.4.5", path = "../cedar-policy-core" }
cedar-policy-core = { version = "=2.4.6", path = "../cedar-policy-core" }
serde = { version = "=1.0.193", features = ["derive"] }
serde_json = { version = "=1.0.108", features = ["preserve_order"] }
serde_with = "=3.4.0"
Expand Down
6 changes: 6 additions & 0 deletions cedar-policy/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 2.4.6

### Fixed

- The formatter will now fail with an error if it changes a policy's semantics.

## 2.4.5

### Changed
Expand Down
6 changes: 3 additions & 3 deletions cedar-policy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cedar-policy"
edition = "2021"

version = "2.4.5"
version = "2.4.6"
license = "Apache-2.0"
categories = ["compilers", "config"]
description = "Cedar is a language for defining permissions as policies, which describe who should have access to what."
Expand All @@ -11,8 +11,8 @@ homepage = "https://cedarpolicy.com"
repository = "https://github.com/cedar-policy/cedar"

[dependencies]
cedar-policy-core = { version = "=2.4.5", path = "../cedar-policy-core" }
cedar-policy-validator = { version = "=2.4.5", path = "../cedar-policy-validator" }
cedar-policy-core = { version = "=2.4.6", path = "../cedar-policy-core" }
cedar-policy-validator = { version = "=2.4.6", path = "../cedar-policy-validator" }
ref-cast = "1.0"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
Expand Down