1use serde::Serialize;
21
22use crate::verifying::ps::error::VerificationError;
23use crate::verifying::verify::{
24 AnalysisResult, CdniVerificationKey, MetadataAnalysisContext, MetadataVerificationError,
25 Verifier,
26};
27use crate::{
28 cdni::{
29 gmd::spec::TypedGenericMetadata,
30 ps::spec::{
31 ClientRequestStage, ClientResponseStage, ExpressionMatch, Header, HeaderTransform,
32 MatchGroup, OriginRequestStage, OriginResponseStage, ProcessingStages,
33 RequestTransform, ResponseTransform, StageMetadata, StageRules, SyntheticResponse,
34 TypedClientRequestStage, TypedClientResponseStage, TypedExpressionMatch,
35 TypedGenericStage, TypedHeader, TypedHeaderTransform, TypedMatchGroup,
36 TypedOriginRequestStage, TypedOriginResponseStage, TypedProcessingStages,
37 TypedRequestTransform, TypedResponseTransform, TypedStage, TypedStageMetadata,
38 TypedStageRules, TypedSyntheticResponse,
39 },
40 },
41 environment::scope::Scopes,
42 mel::{
43 analysis::{Analyzed, analyze},
44 ast::Expr,
45 compiler,
46 types::Type,
47 },
48 visitors::PsVisitor,
49};
50
51use std::fmt::Debug;
52
53type PsVisitorResult<T, E> = Result<T, E>;
54
55#[derive(Debug, Clone, Default)]
56pub enum PsVerificationKey {
57 Expr(Expr<Analyzed>),
58 ExprPair(Option<Expr<Analyzed>>, Option<Expr<Analyzed>>),
59 #[default]
60 None,
61}
62
63impl Serialize for PsVerificationKey {
64 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
65 where
66 S: serde::Serializer,
67 {
68 serializer.serialize_none()
69 }
70}
71
72impl TypedGenericStage {
73 pub fn typed(&self) -> Result<TypedStage<()>, Box<VerificationError>> {
74 if self.tpe == TypedClientRequestStage::<()>::typed_cdni_metadata_name() {
75 let stages = serde_json::from_str::<TypedClientRequestStage<()>>(
76 &(serde_json::to_string(self).map_err(|_| VerificationError::ParseError)?),
77 )
78 .map_err(|_| VerificationError::ParseError)?;
79 Ok(TypedStage::ClientRequest(stages))
80 } else if self.tpe == TypedClientResponseStage::<()>::typed_cdni_metadata_name() {
81 let stages = serde_json::from_str::<TypedClientResponseStage<()>>(
82 &(serde_json::to_string(self).map_err(|_| VerificationError::ParseError)?),
83 )
84 .map_err(|_| VerificationError::ParseError)?;
85 Ok(TypedStage::ClientResponse(stages))
86 } else if self.tpe == TypedOriginRequestStage::<()>::typed_cdni_metadata_name() {
87 let stages = serde_json::from_str::<TypedOriginRequestStage<()>>(
88 &(serde_json::to_string(self).map_err(|_| VerificationError::ParseError)?),
89 )
90 .map_err(|_| VerificationError::ParseError)?;
91 Ok(TypedStage::OriginRequest(stages))
92 } else if self.tpe == TypedOriginResponseStage::<()>::typed_cdni_metadata_name() {
93 let stages = serde_json::from_str::<TypedOriginResponseStage<()>>(
94 &(serde_json::to_string(self).map_err(|_| VerificationError::ParseError)?),
95 )
96 .map_err(|_| VerificationError::ParseError)?;
97 Ok(TypedStage::OriginResponse(stages))
98 } else {
99 Err(VerificationError::InvalidTypedResponseStage.into())
100 }
101 }
102}
103
104#[derive(Debug, Clone, Default)]
105pub(crate) struct PsVerifier {}
106
107impl PsVerifier {
108 pub fn compile_and_analyze_expr(
109 source: &str,
110 scopes: &Scopes<Type>,
111 ) -> Result<Expr<Analyzed>, Box<VerificationError>> {
112 let expr = compiler::compile(source)
113 .map_err(|e| Box::new(VerificationError::ExpressionCompile(Box::new(e))))?;
114 analyze(&expr, scopes).map_err(|e| Box::new(VerificationError::ExpressionAnalyze(e)))
115 }
116}
117
118#[allow(clippy::large_enum_variant)]
119#[derive(Debug, Clone)]
120pub(crate) enum PsVerifierContextValue {
121 ProcessingStages(TypedProcessingStages<PsVerificationKey>),
122 StageRules(TypedStageRules<PsVerificationKey>),
123 ExpressionMatch(TypedExpressionMatch<PsVerificationKey>),
124 StageMetadata(TypedStageMetadata<PsVerificationKey>),
125 GenericMetadata(TypedGenericMetadata<PsVerificationKey>),
126 RequestTransform(TypedRequestTransform<PsVerificationKey>),
127 ResponseTransform(TypedResponseTransform<PsVerificationKey>),
128 HeaderTransform(TypedHeaderTransform<PsVerificationKey>),
129 Header(TypedHeader<PsVerificationKey>),
130 SyntheticResponse(TypedSyntheticResponse<PsVerificationKey>),
131 MatchGroup(TypedMatchGroup<PsVerificationKey>),
132 ClientRequestStage(TypedClientRequestStage<PsVerificationKey>),
133 ClientResponseStage(TypedClientResponseStage<PsVerificationKey>),
134 OriginRequestStage(TypedOriginRequestStage<PsVerificationKey>),
135 OriginResponseStage(TypedOriginResponseStage<PsVerificationKey>),
136}
137
138#[derive(Debug, Default)]
139pub(crate) struct PsVerifierContext {
140 pub value: Option<PsVerifierContextValue>,
141 pub scopes: Scopes<Type>,
142}
143
144type VerifiedPs = ProcessingStages<PsVerificationKey>;
145
146macro_rules! expect_maybe_some_value {
147 ($name:expr, $value:path) => {
148 match &$name {
149 Some($value(v)) => Some(v),
150 None => None,
151 _ => return Err(Box::new(VerificationError::WrongType)),
152 }
153 };
154}
155
156macro_rules! expect_some_value {
157 ($name:expr, $value:path) => {
158 match &$name {
159 Some($value(v)) => v,
160 None => return Err(Box::new(VerificationError::NoVerifiedValue)),
161 _ => return Err(Box::new(VerificationError::WrongType)),
162 }
163 };
164}
165
166macro_rules! make_context_value {
167 ($value:expr, $vt:path, $a:ident, $tvt:ident) => {
168 Some($vt($tvt::<$a>::typed_value($value)))
169 };
170}
171
172macro_rules! check_generic_md_typename {
173 ($value:expr, $tn:ident) => {
174 if $value.tpe != $tn::<()>::typed_cdni_metadata_name() {
175 return Err(Box::new(VerificationError::WrongGenericMetadataTypeName(
176 $tn::<()>::typed_cdni_metadata_name(),
177 $value.tpe.clone(),
178 )));
179 }
180 };
181}
182
183#[derive(Debug)]
184pub struct PsMetadataAnalyzer {}
185
186impl Verifier<MetadataAnalysisContext, MetadataVerificationError> for PsMetadataAnalyzer {
187 fn analyze(
188 &self,
189 v: &TypedGenericMetadata<()>,
190 input: MetadataAnalysisContext,
191 ) -> AnalysisResult<MetadataAnalysisContext, MetadataVerificationError> {
192 let generic_stage = serde_json::from_value::<TypedGenericStage>(
193 serde_json::to_value(v)
194 .map_err(|e| MetadataVerificationError::JsonError(e.to_string()))?,
195 )
196 .map_err(|e| MetadataVerificationError::JsonError(e.to_string()))?;
197
198 let res = verify_ps_request_stage(&generic_stage, &input.scopes)
201 .map_err(MetadataVerificationError::PsVerificationError)?;
202
203 Ok((input, CdniVerificationKey::Stage(Box::new(res))))
204 }
205
206 fn type_name(&self, candidate: &str) -> bool {
207 candidate == TypedClientRequestStage::<()>::typed_cdni_metadata_name()
208 || candidate == TypedClientResponseStage::<()>::typed_cdni_metadata_name()
209 || candidate == TypedOriginRequestStage::<()>::typed_cdni_metadata_name()
210 || candidate == TypedOriginResponseStage::<()>::typed_cdni_metadata_name()
211 }
212}
213
214impl PsVisitor<(), PsVerifierContext, PsVerifierContext, Box<VerificationError>> for PsVerifier {
215 fn visit_processing_stages(
216 &mut self,
217 v: &TypedProcessingStages<()>,
218 c: PsVerifierContext,
219 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
220 check_generic_md_typename!(v, TypedProcessingStages);
221
222 let mut result = ProcessingStages::<PsVerificationKey>::default();
223 let mut rc = c;
224
225 let v = &v.value;
226
227 for csr in &v.client_req {
228 rc = self.visit_stage_rules(csr, rc)?;
229 if let Some(tsr) =
230 expect_maybe_some_value!(rc.value, PsVerifierContextValue::StageRules)
231 {
232 result.client_req.push(tsr.clone());
233 };
234 }
235
236 for csr in &v.client_res {
237 rc = self.visit_stage_rules(csr, rc)?;
238 if let Some(tsr) =
239 expect_maybe_some_value!(rc.value, PsVerifierContextValue::StageRules)
240 {
241 result.client_res.push(tsr.clone());
242 };
243 }
244
245 for csr in &v.origin_req {
246 rc = self.visit_stage_rules(csr, rc)?;
247 if let Some(tsr) =
248 expect_maybe_some_value!(rc.value, PsVerifierContextValue::StageRules)
249 {
250 result.origin_req.push(tsr.clone());
251 };
252 }
253
254 for csr in &v.origin_res {
255 rc = self.visit_stage_rules(csr, rc)?;
256 if let Some(tsr) =
257 expect_maybe_some_value!(rc.value, PsVerifierContextValue::StageRules)
258 {
259 result.origin_res.push(tsr.clone());
260 };
261 }
262
263 rc.value = make_context_value!(
264 result,
265 PsVerifierContextValue::ProcessingStages,
266 PsVerificationKey,
267 TypedProcessingStages
268 );
269
270 Ok(rc)
271 }
272
273 fn visit_stage_rules(
274 &mut self,
275 v: &TypedStageRules<()>,
276 mut c: PsVerifierContext,
277 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
278 check_generic_md_typename!(v, TypedStageRules);
281
282 let v = &v.value;
283
284 let mut result = if let Some(mtch) = &v.mtch {
285 c = self.visit_expression_match(mtch, c)?;
286
287 let expr = expect_maybe_some_value!(&c.value, PsVerifierContextValue::ExpressionMatch);
288
289 StageRules::<PsVerificationKey> {
290 mtch: expr.cloned(),
291 stage_metadata: TypedStageMetadata::default(),
292 aug: PsVerificationKey::None,
293 }
294 } else {
295 StageRules::<PsVerificationKey> {
296 mtch: None,
297 stage_metadata: TypedStageMetadata::default(),
298 aug: PsVerificationKey::None,
299 }
300 };
301
302 c = self.visit_stage_metadata(&v.stage_metadata, c)?;
303
304 result.stage_metadata =
305 expect_some_value!(&c.value, PsVerifierContextValue::StageMetadata).clone();
306
307 Ok(PsVerifierContext {
308 scopes: c.scopes.clone(),
309 value: make_context_value!(
310 result,
311 PsVerifierContextValue::StageRules,
312 PsVerificationKey,
313 TypedStageRules
314 ),
315 })
316 }
317
318 fn visit_expression_match(
319 &mut self,
320 v: &TypedExpressionMatch<()>,
321 c: PsVerifierContext,
322 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
323 check_generic_md_typename!(v, TypedExpressionMatch);
324
325 let v = &v.value;
326
327 let expr = Self::compile_and_analyze_expr(&v.expression, &c.scopes)?;
328
329 if expr.tipe() != Type::Boolean {
330 return Err(Box::new(VerificationError::ExpressionWrongType(
331 Type::Boolean,
332 expr.tipe(),
333 )));
334 }
335 Ok(PsVerifierContext {
336 scopes: c.scopes.clone(),
337 value: make_context_value!(
338 ExpressionMatch {
339 expression: v.expression.clone(),
340 aug: PsVerificationKey::Expr(expr),
341 },
342 PsVerifierContextValue::ExpressionMatch,
343 PsVerificationKey,
344 TypedExpressionMatch
345 ),
346 })
347 }
348
349 fn visit_stage_metadata(
350 &mut self,
351 v: &TypedStageMetadata<()>,
352 mut c: PsVerifierContext,
353 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
354 check_generic_md_typename!(v, TypedStageMetadata);
355
356 let v = &v.value;
357
358 let mut result = if let Some(generic) = &v.generic {
359 let mut result: Vec<TypedGenericMetadata<PsVerificationKey>> = vec![];
360 for generics in generic {
361 c = self.visit_generic_metadata(generics, c)?;
362 let generic =
363 expect_some_value!(&c.value, PsVerifierContextValue::GenericMetadata).clone();
364 result.push(generic);
365 }
366
367 StageMetadata {
368 request_xform: None,
369 response_xform: None,
370 generic: Some(result),
371 aug: PsVerificationKey::None,
372 }
373 } else {
374 StageMetadata {
375 request_xform: None,
376 response_xform: None,
377 generic: None,
378 aug: PsVerificationKey::None,
379 }
380 };
381
382 result.request_xform = if let Some(reqt) = &v.request_xform {
383 c = self.visit_request_transform(reqt, c)?;
384 Some(expect_some_value!(&c.value, PsVerifierContextValue::RequestTransform).clone())
385 } else {
386 None
387 };
388
389 result.response_xform = if let Some(reqt) = &v.response_xform {
390 c = self.visit_response_transform(reqt, c)?;
391 Some(expect_some_value!(&c.value, PsVerifierContextValue::ResponseTransform).clone())
392 } else {
393 None
394 };
395
396 Ok(PsVerifierContext {
397 scopes: c.scopes.clone(),
398 value: make_context_value!(
399 result,
400 PsVerifierContextValue::StageMetadata,
401 PsVerificationKey,
402 TypedStageMetadata
403 ),
404 })
405 }
406
407 fn visit_request_transform(
408 &mut self,
409 v: &TypedRequestTransform<()>,
410 mut c: PsVerifierContext,
411 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
412 check_generic_md_typename!(v, TypedRequestTransform);
413
414 let v = &v.value;
415
416 let mut result = if let Some(header_xform) = &v.xform {
417 c = self.visit_header_transform(header_xform, c)?;
418 let header =
419 Some(expect_some_value!(&c.value, PsVerifierContextValue::HeaderTransform).clone());
420
421 RequestTransform {
422 xform: header,
423 uri: v.uri.clone(),
424 uri_is_expr: v.uri_is_expr,
425 aug: PsVerificationKey::None,
426 }
427 } else {
428 RequestTransform {
429 xform: None,
430 uri: v.uri.clone(),
431 uri_is_expr: v.uri_is_expr,
432 aug: PsVerificationKey::None,
433 }
434 };
435
436 result.aug = if let Some(uri) = &v.uri {
437 if let Some(uri_is_expr) = &v.uri_is_expr
438 && *uri_is_expr
439 {
440 let expr = Self::compile_and_analyze_expr(uri, &c.scopes)?;
441
442 if expr.tipe() != Type::String {
443 return Err(Box::new(VerificationError::ExpressionWrongType(
444 Type::String,
445 expr.tipe(),
446 )));
447 }
448 PsVerificationKey::Expr(expr)
449 } else {
450 PsVerificationKey::None
451 }
452 } else {
453 PsVerificationKey::None
454 };
455
456 Ok(PsVerifierContext {
457 scopes: c.scopes.clone(),
458 value: make_context_value!(
459 result,
460 PsVerifierContextValue::RequestTransform,
461 PsVerificationKey,
462 TypedRequestTransform
463 ),
464 })
465 }
466
467 fn visit_response_transform(
468 &mut self,
469 v: &TypedResponseTransform<()>,
470 mut c: PsVerifierContext,
471 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
472 check_generic_md_typename!(v, TypedResponseTransform);
473
474 let v = &v.value;
475
476 let mut result = if let Some(header_xform) = &v.xform {
477 c = self.visit_header_transform(header_xform, c)?;
478 let header =
479 Some(expect_some_value!(&c.value, PsVerifierContextValue::HeaderTransform).clone());
480
481 ResponseTransform {
482 xform: header,
483 response_status: v.response_status.clone(),
484 response_status_expr: v.response_status_expr,
485 synthetic: None,
486 aug: PsVerificationKey::None,
487 }
488 } else {
489 ResponseTransform {
490 xform: None,
491 response_status: v.response_status.clone(),
492 response_status_expr: v.response_status_expr,
493 synthetic: None,
494 aug: PsVerificationKey::None,
495 }
496 };
497
498 result.synthetic = if let Some(synthetic) = &v.synthetic {
499 c = self.visit_synthetic_response(synthetic, c)?;
500 Some(expect_some_value!(&c.value, PsVerifierContextValue::SyntheticResponse).clone())
501 } else {
502 None
503 };
504
505 result.aug = if let Some(rs) = &v.response_status {
506 if let Some(rs_is_expr) = &v.response_status_expr
507 && *rs_is_expr
508 {
509 let expr = Self::compile_and_analyze_expr(rs, &c.scopes)?;
510
511 if expr.tipe() != Type::Integer {
512 return Err(Box::new(VerificationError::ExpressionWrongType(
513 Type::Integer,
514 expr.tipe(),
515 )));
516 }
517 PsVerificationKey::Expr(expr)
518 } else {
519 PsVerificationKey::None
520 }
521 } else {
522 PsVerificationKey::None
523 };
524
525 Ok(PsVerifierContext {
526 scopes: c.scopes.clone(),
527 value: make_context_value!(
528 result,
529 PsVerifierContextValue::ResponseTransform,
530 PsVerificationKey,
531 TypedResponseTransform
532 ),
533 })
534 }
535
536 fn visit_generic_metadata(
537 &mut self,
538 v: &TypedGenericMetadata<()>,
539 c: PsVerifierContext,
540 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
541 if !v.tpe.starts_with("MI.") {
543 return Err(Box::new(VerificationError::WrongGenericMetadataTypeName(
544 "MI. ...".to_string(),
545 v.tpe.clone(),
546 )));
547 }
548
549 Ok(PsVerifierContext {
550 scopes: c.scopes.clone(),
551 value: make_context_value!(
552 TypedGenericMetadata {
553 tpe: v.tpe.clone(),
554 value: v.value.clone(),
555 aug: PsVerificationKey::None
556 },
557 PsVerifierContextValue::GenericMetadata,
558 PsVerificationKey,
559 TypedGenericMetadata
560 ),
561 })
562 }
563
564 fn visit_header_transform(
565 &mut self,
566 v: &TypedHeaderTransform<()>,
567 mut c: PsVerifierContext,
568 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
569 check_generic_md_typename!(v, TypedHeaderTransform);
570 let v = &v.value;
571
572 let mut result = HeaderTransform {
573 delete: v.delete.clone(),
574 ..Default::default()
575 };
576
577 result.add = if let Some(adds) = &v.add {
578 let mut verified_adds: Vec<TypedHeader<PsVerificationKey>> = vec![];
579 for add in adds {
580 c = self.visit_header(add, c)?;
581 verified_adds
582 .push(expect_some_value!(&c.value, PsVerifierContextValue::Header).clone());
583 }
584 Some(verified_adds)
585 } else {
586 None
587 };
588
589 result.replace = if let Some(replaceds) = &v.replace {
590 let mut verified_replaceds: Vec<TypedHeader<PsVerificationKey>> = vec![];
591 for replaced in replaceds {
592 c = self.visit_header(replaced, c)?;
593 verified_replaceds
594 .push(expect_some_value!(&c.value, PsVerifierContextValue::Header).clone());
595 }
596 Some(verified_replaceds)
597 } else {
598 None
599 };
600 Ok(PsVerifierContext {
601 scopes: c.scopes.clone(),
602 value: make_context_value!(
603 result,
604 PsVerifierContextValue::HeaderTransform,
605 PsVerificationKey,
606 TypedHeaderTransform
607 ),
608 })
609 }
610
611 fn visit_header(
612 &mut self,
613 v: &TypedHeader<()>,
614 c: PsVerifierContext,
615 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
616 check_generic_md_typename!(v, TypedHeader);
617
618 let v = &v.value;
619 let mut result = Header::<PsVerificationKey> {
620 name: v.name.clone(),
621 value: v.value.clone(),
622 value_expr: v.value_expr,
623 aug: PsVerificationKey::None,
624 };
625
626 result.aug = if let Some(hv_is_expr) = &v.value_expr
627 && *hv_is_expr
628 {
629 let expr = Self::compile_and_analyze_expr(&v.value, &c.scopes)?;
630
631 if expr.tipe() != Type::String {
632 return Err(Box::new(VerificationError::ExpressionWrongType(
633 Type::String,
634 expr.tipe(),
635 )));
636 }
637 PsVerificationKey::Expr(expr)
638 } else {
639 PsVerificationKey::None
640 };
641
642 Ok(PsVerifierContext {
643 scopes: c.scopes.clone(),
644 value: make_context_value!(
645 result,
646 PsVerifierContextValue::Header,
647 PsVerificationKey,
648 TypedHeader
649 ),
650 })
651 }
652
653 fn visit_synthetic_response(
654 &mut self,
655 v: &TypedSyntheticResponse<()>,
656 mut c: PsVerifierContext,
657 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
658 check_generic_md_typename!(v, TypedSyntheticResponse);
659 let v = &v.value;
660
661 let mut result = SyntheticResponse {
662 headers: None,
663 response_status: v.response_status.clone(),
664 response_status_expr: v.response_status_expr,
665 body: v.body.clone(),
666 body_expr: v.body_expr,
667 aug: PsVerificationKey::None,
668 };
669
670 result.headers = if let Some(headers) = &v.headers {
671 let mut verified_headers: Vec<TypedHeader<PsVerificationKey>> = vec![];
672 for header in headers {
673 c = self.visit_header(header, c)?;
674 verified_headers
675 .push(expect_some_value!(&c.value, PsVerifierContextValue::Header).clone());
676 }
677 Some(verified_headers)
678 } else {
679 None
680 };
681
682 let response_status_expr = if let Some(rs) = &v.response_status {
683 if let Some(rs_is_expr) = &v.response_status_expr
684 && *rs_is_expr
685 {
686 let expr = Self::compile_and_analyze_expr(rs, &c.scopes)?;
687
688 if expr.tipe() != Type::Integer {
689 return Err(Box::new(VerificationError::ExpressionWrongType(
690 Type::Integer,
691 expr.tipe(),
692 )));
693 }
694 Some(expr)
695 } else {
696 None
697 }
698 } else {
699 None
700 };
701
702 let body_expr = if let Some(body) = &v.body {
703 if let Some(body_is_expr) = &v.body_expr
704 && *body_is_expr
705 {
706 let expr = Self::compile_and_analyze_expr(body, &c.scopes)?;
707
708 if expr.tipe() != Type::String {
709 return Err(Box::new(VerificationError::ExpressionWrongType(
710 Type::String,
711 expr.tipe(),
712 )));
713 }
714 Some(expr)
715 } else {
716 None
717 }
718 } else {
719 None
720 };
721
722 result.aug = PsVerificationKey::ExprPair(response_status_expr, body_expr);
723
724 Ok(PsVerifierContext {
725 scopes: c.scopes.clone(),
726 value: make_context_value!(
727 result,
728 PsVerifierContextValue::SyntheticResponse,
729 PsVerificationKey,
730 TypedSyntheticResponse
731 ),
732 })
733 }
734
735 fn visit_client_request_stage(
736 &mut self,
737 v: &TypedClientRequestStage<()>,
738 mut c: PsVerifierContext,
739 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
740 check_generic_md_typename!(v, TypedClientRequestStage);
741 let v = &v.value;
742
743 let mut verified_mgs: Vec<TypedMatchGroup<PsVerificationKey>> = vec![];
745 for mg in &v.match_groups {
746 c = self.visit_match_group(mg, c)?;
747 verified_mgs
748 .push(expect_some_value!(&c.value, PsVerifierContextValue::MatchGroup).clone());
749 }
750
751 let result = ClientRequestStage {
752 match_groups: verified_mgs,
753 aug: PsVerificationKey::None,
754 };
755
756 Ok(PsVerifierContext {
757 scopes: c.scopes.clone(),
758 value: make_context_value!(
759 result,
760 PsVerifierContextValue::ClientRequestStage,
761 PsVerificationKey,
762 TypedClientRequestStage
763 ),
764 })
765 }
766
767 fn visit_match_group(
768 &mut self,
769 v: &TypedMatchGroup<()>,
770 mut c: PsVerifierContext,
771 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
772 check_generic_md_typename!(v, TypedMatchGroup);
773 let v = &v.value;
774
775 c = self.visit_stage_rules(&v.if_rule, c)?;
776 let verified_if_rule =
777 expect_some_value!(&c.value, PsVerifierContextValue::StageRules).clone();
778
779 let result = if let Some(else_if_rules) = &v.else_ifs {
780 let mut verified_eirs: Vec<TypedStageRules<PsVerificationKey>> = vec![];
782 for eir in else_if_rules {
783 c = self.visit_stage_rules(eir, c)?;
784 verified_eirs
785 .push(expect_some_value!(&c.value, PsVerifierContextValue::StageRules).clone());
786 }
787 MatchGroup {
788 if_rule: verified_if_rule,
789 else_ifs: Some(verified_eirs),
790 aug: PsVerificationKey::None,
791 }
792 } else {
793 MatchGroup {
794 if_rule: verified_if_rule,
795 else_ifs: None,
796 aug: PsVerificationKey::None,
797 }
798 };
799 Ok(PsVerifierContext {
800 scopes: c.scopes.clone(),
801 value: make_context_value!(
802 result,
803 PsVerifierContextValue::MatchGroup,
804 PsVerificationKey,
805 TypedMatchGroup
806 ),
807 })
808 }
809
810 fn visit_origin_request_stage(
811 &mut self,
812 v: &TypedOriginRequestStage<()>,
813 mut c: PsVerifierContext,
814 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
815 check_generic_md_typename!(v, TypedOriginRequestStage);
816 let v = &v.value;
817
818 let mut verified_mgs: Vec<TypedMatchGroup<PsVerificationKey>> = vec![];
820 for mg in &v.match_groups {
821 c = self.visit_match_group(mg, c)?;
822 verified_mgs
823 .push(expect_some_value!(&c.value, PsVerifierContextValue::MatchGroup).clone());
824 }
825
826 let result = OriginRequestStage {
827 match_groups: verified_mgs,
828 aug: PsVerificationKey::None,
829 };
830
831 Ok(PsVerifierContext {
832 scopes: c.scopes.clone(),
833 value: make_context_value!(
834 result,
835 PsVerifierContextValue::OriginRequestStage,
836 PsVerificationKey,
837 TypedOriginRequestStage
838 ),
839 })
840 }
841
842 fn visit_client_response_stage(
843 &mut self,
844 v: &TypedClientResponseStage<()>,
845 mut c: PsVerifierContext,
846 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
847 check_generic_md_typename!(v, TypedClientResponseStage);
848 let v = &v.value;
849
850 let mut verified_mgs: Vec<TypedMatchGroup<PsVerificationKey>> = vec![];
852 for mg in &v.match_groups {
853 c = self.visit_match_group(mg, c)?;
854 verified_mgs
855 .push(expect_some_value!(&c.value, PsVerifierContextValue::MatchGroup).clone());
856 }
857
858 let result = ClientResponseStage {
859 match_groups: verified_mgs,
860 aug: PsVerificationKey::None,
861 };
862
863 Ok(PsVerifierContext {
864 scopes: c.scopes.clone(),
865 value: make_context_value!(
866 result,
867 PsVerifierContextValue::ClientResponseStage,
868 PsVerificationKey,
869 TypedClientResponseStage
870 ),
871 })
872 }
873
874 fn visit_origin_response_stage(
875 &mut self,
876 v: &TypedOriginResponseStage<()>,
877 mut c: PsVerifierContext,
878 ) -> PsVisitorResult<PsVerifierContext, Box<VerificationError>> {
879 check_generic_md_typename!(v, TypedOriginResponseStage);
880 let v = &v.value;
881
882 let mut verified_mgs: Vec<TypedMatchGroup<PsVerificationKey>> = vec![];
884 for mg in &v.match_groups {
885 c = self.visit_match_group(mg, c)?;
886 verified_mgs
887 .push(expect_some_value!(&c.value, PsVerifierContextValue::MatchGroup).clone());
888 }
889
890 let result = OriginResponseStage {
891 match_groups: verified_mgs,
892 aug: PsVerificationKey::None,
893 };
894
895 Ok(PsVerifierContext {
896 scopes: c.scopes.clone(),
897 value: make_context_value!(
898 result,
899 PsVerifierContextValue::OriginResponseStage,
900 PsVerificationKey,
901 TypedOriginResponseStage
902 ),
903 })
904 }
905}
906
907pub(crate) fn verifier() -> (PsVerifier, PsVerifierContext) {
908 (PsVerifier {}, PsVerifierContext::default())
909}
910
911pub fn verify_ps(
918 stages: &TypedProcessingStages<()>,
919) -> Result<TypedProcessingStages<PsVerificationKey>, Box<VerificationError>> {
920 let (mut verifier, context) = verifier();
921 let value = &stages;
922 let result = verifier.visit_processing_stages(value, context)?;
923 Ok(expect_some_value!(&result.value, PsVerifierContextValue::ProcessingStages).clone())
924}
925
926pub fn verify_ps_request_stage(
929 stage: &TypedGenericStage,
930 scopes: &Scopes<Type>,
931) -> Result<TypedStage<PsVerificationKey>, Box<VerificationError>> {
932 match stage.typed()? {
933 TypedStage::ClientRequest(crq) => {
934 let (mut verifier, mut context) = verifier();
935 context.scopes = scopes.clone();
936 let result = verifier.visit_client_request_stage(&crq, context)?;
937 Ok(TypedStage::ClientRequest(
938 expect_some_value!(&result.value, PsVerifierContextValue::ClientRequestStage)
939 .clone(),
940 ))
941 }
942 TypedStage::ClientResponse(crs) => {
943 let (mut verifier, mut context) = verifier();
944 context.scopes = scopes.clone();
945 let result = verifier.visit_client_response_stage(&crs, context)?;
946 Ok(TypedStage::ClientResponse(
947 expect_some_value!(&result.value, PsVerifierContextValue::ClientResponseStage)
948 .clone(),
949 ))
950 }
951 TypedStage::OriginRequest(orq) => {
952 let (mut verifier, mut context) = verifier();
953 context.scopes = scopes.clone();
954 let result = verifier.visit_origin_request_stage(&orq, context)?;
955 Ok(TypedStage::OriginRequest(
956 expect_some_value!(&result.value, PsVerifierContextValue::OriginRequestStage)
957 .clone(),
958 ))
959 }
960 TypedStage::OriginResponse(ors) => {
961 let (mut verifier, mut context) = verifier();
962 context.scopes = scopes.clone();
963 let result = verifier.visit_origin_response_stage(&ors, context)?;
964 Ok(TypedStage::OriginResponse(
965 expect_some_value!(&result.value, PsVerifierContextValue::OriginResponseStage)
966 .clone(),
967 ))
968 }
969 }
970}
971
972#[cfg(test)]
973mod test_verify {
974 use std::assert_matches;
975
976 use crate::cdni::ps::spec::{
977 HeaderTransform, ResponseTransform, SyntheticResponse, TypedHeaderTransform,
978 TypedSyntheticResponse,
979 };
980 use crate::mel::types::Type;
981 use crate::verifying::ps::verify::{
982 PsVerificationKey, PsVerifierContextValue, VerificationError, verifier, verify_ps,
983 };
984 use crate::visitors::PsVisitor;
985 use crate::{cdni::ps::spec::TypedResponseTransform, mel::ast::Expr::BinaryExpr};
986
987 use crate::cdni::tests::test_helpers::{
988 expression_match, generic_metadata, header_transform, processing_stages, request_transform,
989 response_transform, synthetic_response, typed_header,
990 };
991
992 #[test]
993 fn test_verify_bad_generic_md_typename() {
994 let mut stages = processing_stages(vec![], vec![], vec![], vec![]);
995 stages.tpe = "MI.ProcessigStages".to_string();
996
997 let result = verify_ps(&stages)
998 .expect_err("Could verify CDNI generic metadata with invalid metadata type name");
999
1000 assert_matches!(*result, VerificationError::WrongGenericMetadataTypeName(expected, actual) if expected == "MI.ProcessingStages" && actual == "MI.ProcessigStages")
1001 }
1002
1003 #[test]
1004 fn test_verify_generic_metadata_with_bad_type_name() {
1005 let generic = generic_metadata("Mi.CachePolicy", None);
1006
1007 let (mut verifier, context) = verifier();
1008 let result = verifier
1009 .visit_generic_metadata(&generic, context)
1010 .expect_err("Could verify CDNI generic metadata with invalid metadata type name");
1011
1012 assert_matches!(*result, VerificationError::WrongGenericMetadataTypeName(expected, actual) if expected == "MI. ..." && actual == "Mi.CachePolicy");
1013 }
1014
1015 #[test]
1016 fn test_verify_match_wrong_type() {
1017 let mtch = expression_match("5 + 4");
1018 let (mut verifier, context) = verifier();
1019 let result = verifier
1020 .visit_expression_match(&mtch, context)
1021 .expect_err("Could verify PS expression match with incorrect MEL type");
1022
1023 assert_matches!(
1024 *result,
1025 VerificationError::ExpressionWrongType(Type::Boolean, Type::Integer)
1026 )
1027 }
1028
1029 #[test]
1030 fn test_verify_request_transform_uri_expr_wrong_type() {
1031 let xform = request_transform(None, Some("5+4".to_string()), Some(true));
1032 let (mut verifier, context) = verifier();
1033 let result = verifier
1034 .visit_request_transform(&xform, context)
1035 .expect_err("Could verify PS with incorrect MEL type of expression to calculate URI");
1036
1037 assert_matches!(
1038 *result,
1039 VerificationError::ExpressionWrongType(Type::String, Type::Integer)
1040 );
1041 }
1042
1043 #[test]
1044 fn test_verify_response_transform() {
1045 let xform = response_transform(None, Some("404".to_string()), None, None);
1046 let (mut verifier, context) = verifier();
1047 let result = verifier
1048 .visit_response_transform(&xform, context)
1049 .expect("Could not verify correct PS")
1050 .value
1051 .expect("No value in PS Verification Context");
1052
1053 assert_matches!(
1054 result,
1055 PsVerifierContextValue::ResponseTransform(TypedResponseTransform {
1056 tpe: _,
1057 value: ResponseTransform {
1058 xform: _,
1059 response_status: _,
1060 response_status_expr: None,
1061 synthetic: None,
1062 aug: PsVerificationKey::None
1063 }
1064 })
1065 );
1066 }
1067
1068 #[test]
1069 fn test_verify_response_transform_rs_expr() {
1070 let xform = response_transform(None, Some("400+4".to_string()), Some(true), None);
1071 let (mut verifier, context) = verifier();
1072 let result = verifier
1073 .visit_response_transform(&xform, context)
1074 .expect("Could not verify correct PS")
1075 .value
1076 .expect("No value in PS Verification Context");
1077
1078 assert_matches!(
1079 result,
1080 PsVerifierContextValue::ResponseTransform(TypedResponseTransform {
1081 tpe: _,
1082 value: ResponseTransform {
1083 xform: _,
1084 response_status: _,
1085 response_status_expr: Some(true),
1086 synthetic: None,
1087 aug: PsVerificationKey::Expr(BinaryExpr(_))
1088 }
1089 })
1090 );
1091 }
1092 #[test]
1093 fn test_verify_response_transform_rs_expr_wrong_type() {
1094 let xform = response_transform(None, Some("false".to_string()), Some(true), None);
1095 let (mut verifier, context) = verifier();
1096 let result = verifier
1097 .visit_response_transform(&xform, context)
1098 .expect_err("Could verify PS response transform with incorrect MEL type of expression to calculate response status");
1099
1100 assert_matches!(
1101 *result,
1102 VerificationError::ExpressionWrongType(Type::Integer, Type::Boolean)
1103 );
1104 }
1105
1106 #[test]
1107 fn test_verify_header_transform() {
1108 let header_to_add = typed_header("add", "value", None);
1109 let header_to_replace = typed_header("replace", "value", None);
1110 let header_to_delete = vec!["delete1".to_string(), "delete2".to_string()];
1111
1112 let header_xform = header_transform(
1113 Some(header_to_delete),
1114 Some(vec![header_to_add]),
1115 Some(vec![header_to_replace]),
1116 );
1117
1118 let (mut verifier, context) = verifier();
1119 let result = verifier
1120 .visit_header_transform(&header_xform, context)
1121 .expect("Could not verify correct PS")
1122 .value
1123 .expect("No value in PS Verification Context");
1124
1125 assert_matches!(
1126 &result,
1127 PsVerifierContextValue::HeaderTransform(TypedHeaderTransform {
1128 tpe: _,
1129 value: HeaderTransform {
1130 delete: Some(d),
1131 add: Some(a),
1132 replace: Some(b),
1133 aug: PsVerificationKey::None
1134 }
1135 }) if d.len() == 2 && a.len() == 1 && b.len() == 1
1136 );
1137 }
1138
1139 #[test]
1140 fn test_verify_header_transform_value_expr() {
1141 let header_to_add = typed_header("add", "\"value\"", Some(true));
1142 let header_to_replace = typed_header("replace", "\"testing\" . \"one\"", Some(true));
1143
1144 let header_xform = header_transform(
1145 None,
1146 Some(vec![header_to_add]),
1147 Some(vec![header_to_replace]),
1148 );
1149
1150 let (mut verifier, context) = verifier();
1151 let result = verifier
1152 .visit_header_transform(&header_xform, context)
1153 .expect("Could not verify correct PS")
1154 .value
1155 .expect("No value in PS Verification Context");
1156
1157 assert_matches!(
1158 &result,
1159 PsVerifierContextValue::HeaderTransform(TypedHeaderTransform {
1160 tpe: _,
1161 value: HeaderTransform {
1162 delete: None,
1163 add: Some(a),
1164 replace: Some(b),
1165 aug: PsVerificationKey::None
1166 }
1167 }) if matches!(a[0].value.aug, PsVerificationKey::Expr(_)) && matches!(b[0].value.aug, PsVerificationKey::Expr(_))
1168 );
1169 }
1170
1171 #[test]
1172 fn test_verify_header_transform_value_expr_wrong_type_add() {
1173 let header_to_add = typed_header("add", "5", Some(true));
1174 let header_to_replace = typed_header("replace", "\"testing\"", Some(true));
1175
1176 let header_xform = header_transform(
1177 None,
1178 Some(vec![header_to_add]),
1179 Some(vec![header_to_replace]),
1180 );
1181
1182 let (mut verifier, context) = verifier();
1183 let result = verifier
1184 .visit_header_transform(&header_xform, context)
1185 .expect_err("Could verify PS typed header with incorrect MEL type of expression to calculate header value");
1186
1187 assert_matches!(
1188 *result,
1189 VerificationError::ExpressionWrongType(Type::String, Type::Integer)
1190 );
1191 }
1192
1193 #[test]
1194 fn test_verify_header_transform_value_expr_wrong_type_replace() {
1195 let header_to_add = typed_header("add", "\"value\"", Some(true));
1196 let header_to_replace = typed_header("replace", "true", Some(true));
1197
1198 let header_xform = header_transform(
1199 None,
1200 Some(vec![header_to_add]),
1201 Some(vec![header_to_replace]),
1202 );
1203
1204 let (mut verifier, context) = verifier();
1205 let result = verifier
1206 .visit_header_transform(&header_xform, context)
1207 .expect_err("Could verify PS typed header with incorrect MEL type of expression to calculate header value");
1208
1209 assert_matches!(
1210 *result,
1211 VerificationError::ExpressionWrongType(Type::String, Type::Boolean)
1212 );
1213 }
1214
1215 #[test]
1216 fn test_verify_synthetic_response() {
1217 let header_to_add = typed_header("add", "value", None);
1218 let header_to_replace = typed_header("replace", "value", None);
1219 let headers = Some(vec![header_to_add, header_to_replace]);
1220
1221 let srt = synthetic_response(headers, None, None, None, None);
1222
1223 let (mut verifier, context) = verifier();
1224 let result = verifier
1225 .visit_synthetic_response(&srt, context)
1226 .expect("Could not verify correct PS")
1227 .value
1228 .expect("No value in PS Verification Context");
1229
1230 assert_matches!(
1231 &result,
1232 PsVerifierContextValue::SyntheticResponse(TypedSyntheticResponse {
1233 tpe: _,
1234 value: SyntheticResponse {
1235 headers: _,
1236 response_status: _,
1237 response_status_expr: _,
1238 body: _,
1239 body_expr: _,
1240 aug: PsVerificationKey::ExprPair(None, None)
1241 }
1242 })
1243 )
1244 }
1245
1246 #[test]
1247 fn test_verify_synthetic_response_response_expr() {
1248 let header_to_add = typed_header("add", "value", None);
1249 let header_to_replace = typed_header("replace", "value", None);
1250 let headers = Some(vec![header_to_add, header_to_replace]);
1251
1252 let srt = synthetic_response(headers, Some("400 + 4".to_string()), Some(true), None, None);
1253
1254 let (mut verifier, context) = verifier();
1255 let result = verifier
1256 .visit_synthetic_response(&srt, context)
1257 .expect("Could not verify correct PS")
1258 .value
1259 .expect("No value in PS Verification Context");
1260
1261 assert_matches!(
1262 &result,
1263 PsVerifierContextValue::SyntheticResponse(TypedSyntheticResponse {
1264 tpe: _,
1265 value: SyntheticResponse {
1266 headers: _,
1267 response_status: _,
1268 response_status_expr: _,
1269 body: _,
1270 body_expr: _,
1271 aug: PsVerificationKey::ExprPair(Some(_), None)
1272 }
1273 })
1274 )
1275 }
1276
1277 #[test]
1278 fn test_verify_synthetic_response_body_expr() {
1279 let header_to_add = typed_header("add", "value", None);
1280 let header_to_replace = typed_header("replace", "value", None);
1281 let headers = Some(vec![header_to_add, header_to_replace]);
1282
1283 let srt = synthetic_response(
1284 headers,
1285 None,
1286 None,
1287 Some("\"testing\"".to_string()),
1288 Some(true),
1289 );
1290
1291 let (mut verifier, context) = verifier();
1292 let result = verifier
1293 .visit_synthetic_response(&srt, context)
1294 .expect("Could not verify correct PS")
1295 .value
1296 .expect("No value in PS Verification Context");
1297
1298 assert_matches!(
1299 &result,
1300 PsVerifierContextValue::SyntheticResponse(TypedSyntheticResponse {
1301 tpe: _,
1302 value: SyntheticResponse {
1303 headers: _,
1304 response_status: _,
1305 response_status_expr: _,
1306 body: _,
1307 body_expr: _,
1308 aug: PsVerificationKey::ExprPair(None, Some(_))
1309 }
1310 })
1311 )
1312 }
1313
1314 #[test]
1315 fn test_verify_synthetic_response_body_and_response_expr() {
1316 let header_to_add = typed_header("add", "value", None);
1317 let header_to_replace = typed_header("replace", "value", None);
1318 let headers = Some(vec![header_to_add, header_to_replace]);
1319
1320 let srt = synthetic_response(
1321 headers,
1322 Some("400 + 4".to_string()),
1323 Some(true),
1324 Some("\"testing\"".to_string()),
1325 Some(true),
1326 );
1327
1328 let (mut verifier, context) = verifier();
1329 let result = verifier
1330 .visit_synthetic_response(&srt, context)
1331 .expect("Could not verify correct PS")
1332 .value
1333 .expect("No value in PS Verification Context");
1334
1335 assert_matches!(
1336 &result,
1337 PsVerifierContextValue::SyntheticResponse(TypedSyntheticResponse {
1338 tpe: _,
1339 value: SyntheticResponse {
1340 headers: _,
1341 response_status: _,
1342 response_status_expr: _,
1343 body: _,
1344 body_expr: _,
1345 aug: PsVerificationKey::ExprPair(Some(_), Some(_))
1346 }
1347 })
1348 )
1349 }
1350
1351 #[test]
1352 fn test_verify_synthetic_response_wrong_response_expr_type() {
1353 let header_to_add = typed_header("add", "value", None);
1354 let header_to_replace = typed_header("replace", "value", None);
1355 let headers = Some(vec![header_to_add, header_to_replace]);
1356
1357 let srt = synthetic_response(headers, Some("true".to_string()), Some(true), None, None);
1358
1359 let (mut verifier, context) = verifier();
1360 let result = verifier
1361 .visit_synthetic_response(&srt, context)
1362 .expect_err("Could verify PS synthetic response with incorrect MEL type of expression to calculate response");
1363
1364 assert_matches!(
1365 *result,
1366 VerificationError::ExpressionWrongType(Type::Integer, Type::Boolean)
1367 );
1368 }
1369
1370 #[test]
1371 fn test_verify_synthetic_response_wrong_body_expr_type() {
1372 let header_to_add = typed_header("add", "value", None);
1373 let header_to_replace = typed_header("replace", "value", None);
1374 let headers = Some(vec![header_to_add, header_to_replace]);
1375
1376 let srt = synthetic_response(headers, None, None, Some("true".to_string()), Some(true));
1377
1378 let (mut verifier, context) = verifier();
1379 let result = verifier
1380 .visit_synthetic_response(&srt, context)
1381 .expect_err("Could verify PS synthetic response with incorrect MEL type of expression to calculate body");
1382
1383 assert_matches!(
1384 *result,
1385 VerificationError::ExpressionWrongType(Type::String, Type::Boolean)
1386 );
1387 }
1388}
1389
1390#[cfg(test)]
1391mod test_verify_from_json {
1392 use std::assert_matches;
1393
1394 use crate::cdni::ps::spec::{
1395 HeaderTransform, ResponseTransform, SyntheticResponse, TypedGenericStage,
1396 TypedHeaderTransform, TypedStage, TypedSyntheticResponse,
1397 };
1398 use crate::environment::scope::Scopes;
1399 use crate::mel::types::Type;
1400 use crate::tests::read_test_file;
1401 use crate::verifying::ps::verify::VerificationError::{
1402 ExpressionWrongType, WrongGenericMetadataTypeName,
1403 };
1404 use crate::verifying::ps::verify::{PsVerificationKey, verify_ps, verify_ps_request_stage};
1405 use crate::{
1406 cdni::ps::spec::{
1407 RequestTransform, TypedProcessingStages, TypedRequestTransform, TypedResponseTransform,
1408 },
1409 mel::ast::Expr::BinaryExpr,
1410 };
1411
1412 use std::path::Path;
1413
1414 #[test]
1415 fn test_verify_simple() {
1416 let json = read_test_file(Path::new(
1417 "./tests/data/processing/simple/deserialize_verify.json",
1418 ));
1419 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1420 .expect("Could not parse JSON test file");
1421
1422 let result = verify_ps(&stages).expect("Could not verify proper PS");
1423
1424 let result_serialized =
1425 serde_json::to_string_pretty(&result).expect("Could not serialize verified PS");
1426 pretty_assertions::assert_eq!(json, result_serialized);
1427 }
1428
1429 #[test]
1430 fn test_verify_bad_generic_md_typename() {
1431 let json = read_test_file(Path::new(
1432 "./tests/data/processing/generic_metadata/bad-typename.json",
1433 ));
1434 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1435 .expect("Could not parse JSON test file");
1436
1437 let result = verify_ps(&stages)
1438 .expect_err("Could verify CDNI generic metadata with invalid metadata type name");
1439
1440 assert_matches!(*result, WrongGenericMetadataTypeName(expected, actual) if expected == "MI.ProcessingStages" && actual == "MI.ProcessigStages")
1441 }
1442
1443 #[test]
1444 fn test_verify_stage_metadata_with_generic_metadata_bad_type_name() {
1445 let json = read_test_file(Path::new(
1446 "./tests/data/processing/generic_metadata/bad-typename2.json",
1447 ));
1448 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1449 .expect("Could not parse JSON test file");
1450
1451 let result = verify_ps(&stages).expect_err("Could verify mistyped PS");
1452
1453 assert_matches!(*result, WrongGenericMetadataTypeName(expected, actual) if expected == "MI. ..." && actual == "Mi.CachePolicy");
1454 }
1455
1456 #[test]
1457 fn test_verify_match_wrong_type() {
1458 let json = read_test_file(Path::new(
1459 "./tests/data/processing/stage_rules/wrong_match_type.json",
1460 ));
1461 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1462 .expect("Could not parse JSON test file");
1463
1464 let result = verify_ps(&stages)
1465 .expect_err("Could verify PS expression match with incorrect MEL type");
1466
1467 assert_matches!(*result, ExpressionWrongType(Type::Boolean, Type::Integer))
1468 }
1469
1470 #[test]
1471 fn test_verify_request_transform() {
1472 let json = read_test_file(Path::new(
1473 "./tests/data/processing/request_transform/uri_no_expr.json",
1474 ));
1475 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1476 .expect("Could not parse JSON test file");
1477
1478 let result = verify_ps(&stages).expect("Could not verify correct PS");
1479
1480 assert_matches!(
1481 result.value.client_req[0]
1482 .value
1483 .stage_metadata
1484 .value
1485 .request_xform,
1486 Some(TypedRequestTransform {
1487 tpe: _,
1488 value: RequestTransform {
1489 xform: _,
1490 uri: _,
1491 uri_is_expr: Some(false),
1492 aug: PsVerificationKey::None
1493 }
1494 })
1495 );
1496 }
1497
1498 #[test]
1499 fn test_verify_request_transform_uri_expr() {
1500 let json = read_test_file(Path::new(
1501 "./tests/data/processing/request_transform/uri_expr.json",
1502 ));
1503 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1504 .expect("Could not parse JSON test file");
1505
1506 let result = verify_ps(&stages).expect("Could not verify correct PS");
1507
1508 assert_matches!(
1509 result.value.client_req[0]
1510 .value
1511 .stage_metadata
1512 .value
1513 .request_xform,
1514 Some(TypedRequestTransform {
1515 tpe: _,
1516 value: RequestTransform {
1517 xform: _,
1518 uri: _,
1519 uri_is_expr: Some(true),
1520 aug: PsVerificationKey::Expr(BinaryExpr(_))
1521 }
1522 })
1523 );
1524 }
1525
1526 #[test]
1527 fn test_verify_request_transform_uri_expr_wrong_type() {
1528 let json = read_test_file(Path::new(
1529 "./tests/data/processing/request_transform/uri_expr_wrong_type.json",
1530 ));
1531 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1532 .expect("Could not parse JSON test file");
1533
1534 let result = verify_ps(&stages)
1535 .expect_err("Could verify PS with incorrect MEL type of expression to calculate URI");
1536
1537 assert_matches!(*result, ExpressionWrongType(Type::String, Type::Integer));
1538 }
1539
1540 #[test]
1541 fn test_verify_response_transform() {
1542 let json = read_test_file(Path::new(
1543 "./tests/data/processing/response_transform/rs_no_expr.json",
1544 ));
1545 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1546 .expect("Could not parse JSON test file");
1547
1548 let result = verify_ps(&stages).expect("Could not verify correct PS");
1549
1550 assert_matches!(
1551 result.value.client_req[0]
1552 .value
1553 .stage_metadata
1554 .value
1555 .response_xform,
1556 Some(TypedResponseTransform {
1557 tpe: _,
1558 value: ResponseTransform {
1559 xform: _,
1560 response_status: _,
1561 response_status_expr: None,
1562 synthetic: None,
1563 aug: PsVerificationKey::None
1564 }
1565 })
1566 );
1567 }
1568
1569 #[test]
1570 fn test_verify_response_transform_rs_expr() {
1571 let json = read_test_file(Path::new(
1572 "./tests/data/processing/response_transform/rs_expr.json",
1573 ));
1574 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1575 .expect("Could not parse JSON test file");
1576
1577 let result = verify_ps(&stages).expect("Could not verify correct PS");
1578
1579 assert_matches!(
1580 result.value.client_req[0]
1581 .value
1582 .stage_metadata
1583 .value
1584 .response_xform,
1585 Some(TypedResponseTransform {
1586 tpe: _,
1587 value: ResponseTransform {
1588 xform: _,
1589 response_status: _,
1590 response_status_expr: Some(true),
1591 synthetic: None,
1592 aug: PsVerificationKey::Expr(BinaryExpr(_))
1593 }
1594 })
1595 );
1596 }
1597
1598 #[test]
1599 fn test_verify_response_transform_rs_expr_wrong_type() {
1600 let json = read_test_file(Path::new(
1601 "./tests/data/processing/response_transform/rs_expr_wrong_type.json",
1602 ));
1603 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1604 .expect("Could not parse JSON test file");
1605
1606 let result = verify_ps(&stages)
1607 .expect_err("Could verify PS response transform with incorrect MEL type of expression to calculate response status");
1608
1609 assert_matches!(*result, ExpressionWrongType(Type::Integer, Type::Boolean));
1610 }
1611
1612 #[test]
1613 fn test_verify_header_transform() {
1614 let json = read_test_file(Path::new(
1615 "./tests/data/processing/header_transform/value_no_expr.json",
1616 ));
1617 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1618 .expect("Could not parse JSON test file");
1619
1620 let result = verify_ps(&stages).expect("Could not verify correct PS");
1621
1622 assert_matches!(
1623 &result.value.client_req[0]
1624 .value
1625 .stage_metadata
1626 .value
1627 .response_xform,
1628 Some(TypedResponseTransform {
1629 tpe: _,
1630 value: ResponseTransform {
1631 xform: Some(TypedHeaderTransform {
1632 tpe: _,
1633 value: HeaderTransform {
1634 delete: Some(d),
1635 add: Some(a),
1636 replace: Some(b),
1637 aug: PsVerificationKey::None
1638 }
1639 }),
1640 response_status: _,
1641 response_status_expr: None,
1642 synthetic: None,
1643 aug: PsVerificationKey::None
1644 }
1645 }) if d.len() == 2 && a.len() == 1 && b.len() == 1
1646 );
1647 }
1648
1649 #[test]
1650 fn test_verify_header_transform_value_expr() {
1651 let json = read_test_file(Path::new(
1652 "./tests/data/processing/header_transform/value_expr.json",
1653 ));
1654 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1655 .expect("Could not parse JSON test file");
1656
1657 let result = verify_ps(&stages).expect("Could not verify correct PS");
1658
1659 assert_matches!(
1660 &result.value.client_req[0]
1661 .value
1662 .stage_metadata
1663 .value
1664 .response_xform,
1665 Some(TypedResponseTransform {
1666 tpe: _,
1667 value: ResponseTransform {
1668 xform: Some(TypedHeaderTransform {
1669 tpe: _,
1670 value: HeaderTransform {
1671 delete: _,
1672 add: Some(a),
1673 replace: Some(b),
1674 aug: PsVerificationKey::None
1675 }
1676 }),
1677 response_status: _,
1678 response_status_expr: None,
1679 synthetic: None,
1680 aug: PsVerificationKey::None
1681 }
1682 }) if matches!(a[0].value.aug, PsVerificationKey::Expr(_)) && matches!(b[0].value.aug, PsVerificationKey::Expr(_))
1683 );
1684 }
1685
1686 #[test]
1687 fn test_verify_header_transform_value_expr_wrong_type_add() {
1688 let json = read_test_file(Path::new(
1689 "./tests/data/processing/header_transform/value_expr_wrong_type.json",
1690 ));
1691 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1692 .expect("Could not parse JSON test file");
1693
1694 let result = verify_ps(&stages)
1695 .expect_err("Could verify PS typed header with incorrect MEL type of expression to calculate header value");
1696
1697 assert_matches!(*result, ExpressionWrongType(Type::String, Type::Boolean));
1698 }
1699
1700 #[test]
1701 fn test_verify_header_transform_value_expr_wrong_type_replace() {
1702 let json = read_test_file(Path::new(
1703 "./tests/data/processing/header_transform/value_expr_wrong_type_replace.json",
1704 ));
1705 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1706 .expect("Could not parse JSON test file");
1707
1708 let result =
1709 verify_ps(&stages).expect_err("Could verify PS with invalid metadata type name");
1710 assert_matches!(*result, ExpressionWrongType(Type::String, Type::Boolean));
1711 }
1712
1713 #[test]
1714 fn test_verify_synthetic_response() {
1715 let json = read_test_file(Path::new(
1716 "./tests/data/processing/synthetic_response/no_expr.json",
1717 ));
1718 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1719 .expect("Could not parse JSON test file");
1720
1721 let result = verify_ps(&stages).expect("Could not verify correct PS");
1722
1723 assert_matches!(
1724 &result.value.client_req[0]
1725 .value
1726 .stage_metadata
1727 .value
1728 .response_xform,
1729 Some(TypedResponseTransform {
1730 tpe: _,
1731 value: ResponseTransform {
1732 xform: None,
1733 response_status: _,
1734 response_status_expr: _,
1735 synthetic: Some(TypedSyntheticResponse {
1736 tpe: _,
1737 value: SyntheticResponse {
1738 headers: _,
1739 response_status: _,
1740 response_status_expr: _,
1741 body: _,
1742 body_expr: _,
1743 aug: PsVerificationKey::ExprPair(None, None)
1744 }
1745 }),
1746 aug: PsVerificationKey::None
1747 }
1748 })
1749 );
1750 }
1751
1752 #[test]
1753 fn test_verify_synthetic_response_response_expr() {
1754 let json = read_test_file(Path::new(
1755 "./tests/data/processing/synthetic_response/response_expr.json",
1756 ));
1757 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1758 .expect("Could not parse JSON test file");
1759
1760 let result = verify_ps(&stages).expect("Could not verify correct PS");
1761
1762 assert_matches!(
1763 &result.value.client_req[0]
1764 .value
1765 .stage_metadata
1766 .value
1767 .response_xform,
1768 Some(TypedResponseTransform {
1769 tpe: _,
1770 value: ResponseTransform {
1771 xform: None,
1772 response_status: _,
1773 response_status_expr: _,
1774 synthetic: Some(TypedSyntheticResponse {
1775 tpe: _,
1776 value: SyntheticResponse {
1777 headers: _,
1778 response_status: _,
1779 response_status_expr: _,
1780 body: _,
1781 body_expr: _,
1782 aug: PsVerificationKey::ExprPair(Some(_), None)
1783 }
1784 }),
1785 aug: PsVerificationKey::None
1786 }
1787 })
1788 );
1789 }
1790
1791 #[test]
1792 fn test_verify_synthetic_response_body_expr() {
1793 let json = read_test_file(Path::new(
1794 "./tests/data/processing/synthetic_response/body_expr.json",
1795 ));
1796 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1797 .expect("Could not parse JSON test file");
1798
1799 let result = verify_ps(&stages).expect("Could not verify correct PS");
1800
1801 assert_matches!(
1802 &result.value.client_req[0]
1803 .value
1804 .stage_metadata
1805 .value
1806 .response_xform,
1807 Some(TypedResponseTransform {
1808 tpe: _,
1809 value: ResponseTransform {
1810 xform: None,
1811 response_status: _,
1812 response_status_expr: _,
1813 synthetic: Some(TypedSyntheticResponse {
1814 tpe: _,
1815 value: SyntheticResponse {
1816 headers: _,
1817 response_status: _,
1818 response_status_expr: _,
1819 body: _,
1820 body_expr: _,
1821 aug: PsVerificationKey::ExprPair(None, Some(_))
1822 }
1823 }),
1824 aug: PsVerificationKey::None
1825 }
1826 })
1827 );
1828 }
1829
1830 #[test]
1831 fn test_verify_synthetic_response_body_and_response_expr() {
1832 let json = read_test_file(Path::new(
1833 "./tests/data/processing/synthetic_response/both_body_response_exprs.json",
1834 ));
1835 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1836 .expect("Could not parse JSON test file");
1837
1838 let result = verify_ps(&stages).expect("Could not verify correct PS");
1839
1840 assert_matches!(
1841 &result.value.client_req[0]
1842 .value
1843 .stage_metadata
1844 .value
1845 .response_xform,
1846 Some(TypedResponseTransform {
1847 tpe: _,
1848 value: ResponseTransform {
1849 xform: None,
1850 response_status: _,
1851 response_status_expr: _,
1852 synthetic: Some(TypedSyntheticResponse {
1853 tpe: _,
1854 value: SyntheticResponse {
1855 headers: _,
1856 response_status: _,
1857 response_status_expr: _,
1858 body: _,
1859 body_expr: _,
1860 aug: PsVerificationKey::ExprPair(Some(_), Some(_))
1861 }
1862 }),
1863 aug: PsVerificationKey::None
1864 }
1865 })
1866 );
1867 }
1868
1869 #[test]
1870 fn test_verify_synthetic_response_wrong_response_expr_type() {
1871 let json = read_test_file(Path::new(
1872 "./tests/data/processing/synthetic_response/response_expr_wrong_type.json",
1873 ));
1874 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1875 .expect("Could not parse JSON test file");
1876
1877 let result = verify_ps(&stages)
1878 .expect_err("Could verify PS synthetic response with incorrect MEL type of expression to calculate response");
1879
1880 assert_matches!(*result, ExpressionWrongType(Type::Integer, Type::String));
1881 }
1882
1883 #[test]
1884 fn test_verify_synthetic_response_wrong_body_expr_type() {
1885 let json = read_test_file(Path::new(
1886 "./tests/data/processing/synthetic_response/body_expr_wrong_type.json",
1887 ));
1888 let stages = serde_json::from_str::<TypedProcessingStages<()>>(&json)
1889 .expect("Could not parse JSON test file");
1890
1891 let result = verify_ps(&stages)
1892 .expect_err("Could verify PS synthetic response with incorrect MEL type of expression to calculate body");
1893
1894 assert_matches!(*result, ExpressionWrongType(Type::String, Type::Boolean));
1895 }
1896
1897 #[test]
1898 fn test_verify_client_request_stage() {
1899 let json = read_test_file(Path::new(
1900 "./tests/data/processing/client_request_stage/if.json",
1901 ));
1902 let stages = serde_json::from_str::<TypedGenericStage>(&json)
1903 .expect("Could not parse JSON test file");
1904
1905 let result = verify_ps_request_stage(&stages, &Scopes::<Type>::default())
1906 .expect("Could not verify PS client request stage");
1907
1908 assert_matches!(result, TypedStage::ClientRequest(_))
1909 }
1910
1911 #[test]
1912 fn test_verify_client_request_stage_request_response_header_transform() {
1913 let json = read_test_file(Path::new(
1914 "./tests/data/processing/client_request_stage/request_response_header_transform.json",
1915 ));
1916 let stages = serde_json::from_str::<TypedGenericStage>(&json)
1917 .expect("Could not parse JSON test file");
1918
1919 let result = verify_ps_request_stage(&stages, &Scopes::<Type>::default())
1920 .expect("Could not verify PS client request stage");
1921
1922 assert_matches!(result, TypedStage::ClientRequest(_))
1923 }
1924}