Repository: cedar-policy/cedar
Pull request #1578 (2025-04-18 17:25:19)

Bump Cedar language version
## Description of changes

Noted that the Cedar language version has been updated in the changelog but not in the `cedar-policy` getter. This PR updates it.

## Issue #, if available

## Checklist for requesting a review

The change in this PR is (choose one, and delete the other options):

- [ ] A breaking change requiring a major version bump to `cedar-policy` (e.g., changes to the signature of an existing API).
- [ ] A backwards-compatible change requiring a minor version bump to `cedar-policy` (e.g., addition of a new API).
- [ ] A bug fix or other functionality change requiring a patch to `cedar-policy`.
- [x] A change "invisible" to users (e.g., documentation, changes to "internal" crates like `cedar-policy-core`, `cedar-validator`, etc.)
- [ ] A change (breaking or otherwise) that only impacts unreleased or experimental code.

I confirm that this PR (choose one, and delete the other options):

- [ ] Updates the "Unreleased" section of the CHANGELOG with a description of my change (required for major/minor version bumps).
- [x] Does not update the CHANGELOG because my change does not significantly impact released code.

I confirm that [`cedar-spec`](https://github.com/cedar-policy/cedar-spec) (choose one, and delete the other options):

- [x] Does not require updates because my change does not impact the Cedar formal model or DRT infrastructure.
- [ ] Requires updates, and I have made / will make these updates myself. (Please include in your description a timeline or link to the relevant PR in `cedar-spec`, and how you have tested that your updates are correct.)
- [ ] Requires updates, but I do not plan to make them in the near future. (Make sure that your changes are hidden behind a feature flag to mark them as experimental.)
- [ ] I'm not sure how my change impacts `cedar-spec`. (Post your PR anyways, and we'll discuss in the comments.)

I confirm that [`docs.cedarpolicy.com`](https://docs.cedarpolicy.com/) (choose one, and delete the other options):

- [ ] Does not require updates because my change does not impact the Cedar language specification.
- [x] Requires updates, and @shaobo-he-aws has made these updates: https://github.com/cedar-policy/cedar-docs/pull/161
- [ ] I'm not sure how my change impacts the documentation. (Post your PR anyways, and we'll discuss in the comments.)


github-actions[bot]: 
# Coverage Report
Head Commit: ```92417ff0e95951afef9c9e257c9cdcdc66a8d119```

Base Commit: ```02e55fdaaaedcf3ad89d3b6ea5d78e28a4083c3c```

[Download the full coverage report.](https://github.com/cedar-policy/cedar/actions/runs/14539033962/artifacts/2970985419)

## Coverage of Added or Modified Lines of Rust Code
**Required coverage:** 80.00%

**Actual coverage:** 100.00%

**Status:** PASSED :white_check_mark:

<details>
<summary><b>Details</b></summary>

| File | Status | Covered | Coverage | Missed Lines |
|:-----|:------:|:-------:|---------:|:-------------|

</details>

## Coverage of All Lines of Rust Code
**Required coverage:** 80.00%

**Actual coverage:** 81.62%

**Status:** PASSED :white_check_mark:

<details>
<summary><b>Details</b></summary>

| Package | Status | Covered | Coverage | Base Coverage |
|:--------|:------:|:-------:|---------:|--------------:|
cedar-policy | :red_circle: | 3075/4473 | 68.75% | 68.75%
cedar-policy-cli | :red_circle: | 571/972 | 58.74% | 58.74%
cedar-policy-core | :green_circle: | 11716/13917 | 84.18% | 84.18%
cedar-policy-formatter | :green_circle: | 914/1043 | 87.63% | 87.63%
cedar-policy-validator | :green_circle: | 8540/9972 | 85.64% | 85.64%
cedar-wasm | :red_circle: | 0/29 | 0.00% | 0.00%
</details>


Patch:
diff --git a/cedar-policy-validator/src/level_validate.rs b/cedar-policy-validator/src/level_validate.rs
index edf938aa..f5b1bcfa 100644
--- a/cedar-policy-validator/src/level_validate.rs
+++ b/cedar-policy-validator/src/level_validate.rs
@@ -689,6 +689,14 @@ mod levels_validation_tests {
             [r#"principal.user.other"#, r#"principal["user"]["other"]"#],
             2,
         );
+        assert_requires_level(
+            r#"permit(principal, action, resource) when { principal.hasTag(principal.user.user.other) && principal.getTag(principal.user["user"]["other"]).bool};"#,
+            [
+                r#"principal.user.user.other"#,
+                r#"principal.user["user"]["other"]"#,
+            ],
+            3,
+        );
     }
 
     #[test]
@@ -701,12 +709,31 @@ mod levels_validation_tests {
     }
 
     #[test]
-    fn if_condition_is_checked() {
+    fn top_level_if_is_checked() {
         assert_requires_level(
             r#"permit(principal, action, resource) when { if principal.user.user.bool then principal.bool else resource.user.bool };"#,
             [r#"principal.user.user.bool"#],
             3,
         );
+        assert_requires_level(
+            r#"permit(principal, action, resource) when { if principal.bool then principal.bool else resource.user.user.bool };"#,
+            [r#"resource.user.user.bool"#],
+            3,
+        );
+        assert_requires_level(
+            r#"permit(principal, action, resource) when { if principal.bool then principal.user.user.bool else resource.user.bool };"#,
+            [r#"principal.user.user.bool"#],
+            3,
+        );
+        assert_requires_level(
+            r#"permit(principal, action, resource) when { if context.user.user.user.bool then resource.user.user.bool else principal.user.user.bool };"#,
+            [
+                "context.user.user.user.bool",
+                "principal.user.user.bool",
+                "principal.user.user.bool",
+            ],
+            3,
+        );
     }
 
     #[test]
@@ -778,6 +805,12 @@ mod levels_validation_tests {
             [r#"{foo: principal.user}.foo.bool"#],
             2,
         );
+        assert_fails_at_level(
+            r#"permit(principal, action, resource) when { {foo: principal.user}.foo.bool };"#,
+            ["{foo: principal.user}.foo.bool"],
+            0,
+            2,
+        );
         assert_requires_level(
             r#"permit(principal, action, resource) when { {biz: {foo: {bar: principal.user}}.foo}.biz.bar.bool};"#,
             ["{biz: {foo: {bar: principal.user}}.foo}.biz.bar.bool"],
@@ -900,8 +933,8 @@ mod levels_validation_tests {
             1,
         );
         assert_requires_level(
-            r#"permit(principal, action, resource) when { [principal.bool].contains(true) };"#,
-            [r#"principal.bool"#],
+            r#"permit(principal, action, resource) when { [context.user.user, principal.user].containsAny([resource.user]) };"#,
+            ["context.user.user", "principal.user", "resource.user"],
             1,
         );
         assert_requires_level(
@@ -909,10 +942,36 @@ mod levels_validation_tests {
             [r#"principal.ip.isInRange(ip("192.168.0.0/12"))"#],
             1,
         );
+        assert_requires_level(
+            r#"permit(principal, action, resource) when { ip("192.168.0.0").isInRange(principal.ip) };"#,
+            [r#"principal.ip"#],
+            1,
+        );
         assert_requires_level(
             r#"permit(principal, action, resource) when { principal.other like "*"};"#,
             ["principal.other"],
             1,
         );
+        assert_requires_level(
+            r#"permit(principal, action, resource) when { ! ( principal.bool )};"#,
+            ["principal.bool"],
+            1,
+        );
+    }
+
+    #[test]
+    fn fails_at_much_lower_level() {
+        assert_fails_at_level(
+            r#"permit(principal, action, resource) when { principal.user.user.user.user.user.bool };"#,
+            ["principal.user.user.user.user.user.bool"],
+            0,
+            6,
+        );
+        assert_fails_at_level(
+            r#"permit(principal, action, resource) when { principal.user.user.user.user.user.bool };"#,
+            ["principal.user.user.user.user.user.bool"],
+            2,
+            6,
+        );
     }
 }
diff --git a/cedar-policy/src/api.rs b/cedar-policy/src/api.rs
index f7ad3844..cb2c1581 100644
--- a/cedar-policy/src/api.rs
+++ b/cedar-policy/src/api.rs
@@ -72,7 +72,7 @@ pub(crate) mod version {
         static ref SDK_VERSION: Version = env!("CARGO_PKG_VERSION").parse().unwrap();
         // Cedar language version
         // The patch version field may be unnecessary
-        static ref LANG_VERSION: Version = Version::new(4, 2, 0);
+        static ref LANG_VERSION: Version = Version::new(4, 3, 0);
     }
     /// Get the Cedar SDK Semantic Versioning version
     #[allow(clippy::module_name_repetitions)]


Test patch:
diff --git a/cedar-policy/src/test/test.rs b/cedar-policy/src/test/test.rs
index 344043da..1f141559 100644
--- a/cedar-policy/src/test/test.rs
+++ b/cedar-policy/src/test/test.rs
@@ -6859,7 +6859,7 @@ mod version_tests {
 
     #[test]
     fn test_lang_version() {
-        assert_eq!(get_lang_version().to_string(), "4.2.0");
+        assert_eq!(get_lang_version().to_string(), "4.3.0");
     }
 }