@@ -177,47 +177,50 @@ pub fn run_val_test(
177
177
178
178
let definitional_res = custom_impl. validate ( & schema, policies, mode) ;
179
179
180
- match definitional_res {
181
- Err ( err) => {
182
- // TODO(#175): For now, ignore cases where the Lean code returned an error due to
183
- // an unknown extension function.
184
- if !err. contains ( "jsonToExtFun: unknown extension function" ) {
185
- panic ! (
186
- "Unexpected parse error\n Policies:\n {}\n Schema:\n {:?}\n Error: {err}" ,
187
- & policies, schema
188
- ) ;
189
- }
190
- }
191
- Ok ( definitional_res) => {
192
- // TODO:(#126) Temporary fix to ignore a known mismatch between the spec and `cedar-policy`.
193
- // The issue is that the `cedar-policy` will always return an error for an
194
- // unrecognized entity or action, even if that part of the expression
195
- // should be excluded from typechecking (e.g., `true || Undefined::"foo"`
196
- // should be well typed due to short-circuiting).
197
- if rust_res. validation_errors ( ) . any ( |e| {
198
- matches ! (
199
- e. error_kind( ) ,
200
- ValidationErrorKind :: UnrecognizedEntityType ( _)
201
- | ValidationErrorKind :: UnrecognizedActionId ( _)
202
- )
203
- } ) {
204
- return ;
180
+ // If `cedar-policy` does not return an error, then the spec should not return an error.
181
+ // This implies type soundness of the `cedar-policy` validator since type soundness of the
182
+ // spec is formally proven.
183
+ //
184
+ // In particular, we have proven that if the spec validator does not return an error (B),
185
+ // then there are no authorization-time errors modulo some restrictions (C). So (B) ==> (C).
186
+ // DRT checks that if the `cedar-policy` validator does not return an error (A), then neither
187
+ // does the spec validator (B). So (A) ==> (B). By transitivity then, (A) ==> (C).
188
+
189
+ if rust_res. validation_passed ( ) {
190
+ match definitional_res {
191
+ Err ( err) => {
192
+ // TODO(#175): For now, ignore cases where the Lean code returned an error due to
193
+ // an unknown extension function.
194
+ if !err. contains ( "jsonToExtFun: unknown extension function" ) {
195
+ panic ! (
196
+ "Unexpected parse error\n Policies:\n {}\n Schema:\n {:?}\n Error: {err}" ,
197
+ & policies, schema
198
+ ) ;
199
+ }
205
200
}
201
+ Ok ( definitional_res) => {
202
+ // Even if the Rust validator succeeds, the definitional validator may
203
+ // return "impossiblePolicy" due to greater precision. In this case, the
204
+ // input policy is well-typed, although it is guaranteed to always evaluate
205
+ // to false.
206
+ if definitional_res. validation_errors == vec ! [ "impossiblePolicy" . to_string( ) ] {
207
+ return ;
208
+ }
206
209
207
- // The `validation_passed` decisions should match.
208
- assert_eq ! (
209
- rust_res. validation_passed( ) ,
210
- definitional_res. validation_passed( ) ,
211
- "Mismatch for Policies:\n {}\n Schema:\n {:?}\n cedar-policy response: {:?}\n Test engine response: {:?}\n " ,
212
- & policies,
213
- schema,
214
- rust_res,
215
- definitional_res,
216
- ) ;
210
+ // But the definitional validator should not return any other error.
211
+ assert ! (
212
+ definitional_res. validation_passed( ) ,
213
+ "Mismatch for Policies:\n {}\n Schema:\n {:?}\n cedar-policy response: {:?}\n Test engine response: {:?}\n " ,
214
+ & policies,
215
+ schema,
216
+ rust_res,
217
+ definitional_res,
218
+ ) ;
217
219
218
- // TODO(#69): We currently don't check for a relationship between validation errors.
219
- // E.g., the error reported by the definitional validator should be in the list
220
- // of errors reported by the production validator, but we don't check this.
220
+ // TODO(#69): We currently don't check for a relationship between validation errors.
221
+ // E.g., the error reported by the definitional validator should be in the list
222
+ // of errors reported by the production validator, but we don't check this.
223
+ }
221
224
}
222
225
}
223
226
}
0 commit comments