@@ -68,8 +68,20 @@ type Contract struct {
6868 Raw []byte
6969 // Detected format as provided by the user
7070 Format unmarshal.RawFormat
71- // marhalled proto contract
71+ // marshalled proto v1 contract
7272 Schema * schemav1.CraftingSchema
73+ // marshalled proto v2 contract
74+ Schemav2 * schemav1.CraftingSchemaV2
75+ }
76+
77+ // isV2Schema returns true if the contract uses the v2 CraftingSchema format
78+ func (c * Contract ) isV2Schema () bool {
79+ return c .Schemav2 != nil
80+ }
81+
82+ // isV1Schema returns true if the contract uses the v1 CraftingSchema format
83+ func (c * Contract ) isV1Schema () bool {
84+ return c .Schema != nil
7385}
7486
7587type WorkflowContractWithVersion struct {
@@ -388,20 +400,47 @@ func (uc *WorkflowContractUseCase) ValidateContractPolicies(rawSchema []byte, to
388400 return NewErrValidation (err )
389401 }
390402
391- for _ , att := range c .Schema .GetPolicies ().GetAttestation () {
392- if _ , err := uc .findAndValidatePolicy (att , token ); err != nil {
393- return NewErrValidation (err )
403+ switch {
404+ case c .isV1Schema ():
405+ // Handle v1 schema
406+ schema := c .Schema
407+ for _ , att := range schema .GetPolicies ().GetAttestation () {
408+ if _ , err := uc .findAndValidatePolicy (att , token ); err != nil {
409+ return NewErrValidation (err )
410+ }
394411 }
395- }
396- for _ , att := range c . Schema . GetPolicies (). GetMaterials () {
397- if _ , err := uc . findAndValidatePolicy ( att , token ); err != nil {
398- return NewErrValidation ( err )
412+ for _ , att := range schema . GetPolicies (). GetMaterials () {
413+ if _ , err := uc . findAndValidatePolicy ( att , token ); err != nil {
414+ return NewErrValidation ( err )
415+ }
399416 }
400- }
401- for _ , gatt := range c .Schema .GetPolicyGroups () {
402- if _ , err := uc .findPolicyGroup (gatt , token ); err != nil {
403- return NewErrValidation (err )
417+ for _ , gatt := range schema .GetPolicyGroups () {
418+ if _ , err := uc .findPolicyGroup (gatt , token ); err != nil {
419+ return NewErrValidation (err )
420+ }
421+ }
422+ case c .isV2Schema ():
423+ // Handle v2 schema
424+ spec := c .Schemav2 .GetSpec ()
425+ if spec .GetPolicies () != nil {
426+ for _ , att := range spec .GetPolicies ().GetAttestation () {
427+ if _ , err := uc .findAndValidatePolicy (att , token ); err != nil {
428+ return NewErrValidation (err )
429+ }
430+ }
431+ for _ , att := range spec .GetPolicies ().GetMaterials () {
432+ if _ , err := uc .findAndValidatePolicy (att , token ); err != nil {
433+ return NewErrValidation (err )
434+ }
435+ }
404436 }
437+ for _ , gatt := range spec .GetPolicyGroups () {
438+ if _ , err := uc .findPolicyGroup (gatt , token ); err != nil {
439+ return NewErrValidation (err )
440+ }
441+ }
442+ default :
443+ return NewErrValidation (fmt .Errorf ("invalid schema format" ))
405444 }
406445
407446 return nil
@@ -601,22 +640,36 @@ func (uc *WorkflowContractUseCase) findProvider(providerName string) (*policies.
601640
602641// UnmarshalAndValidateRawContract Takes the raw contract + format and will unmarshal the contract and validate it
603642func UnmarshalAndValidateRawContract (raw []byte , format unmarshal.RawFormat ) (* Contract , error ) {
604- contract := & schemav1.CraftingSchema {}
605- err := unmarshal .FromRaw (raw , format , contract , true )
606- if err != nil {
607- return nil , NewErrValidation (err )
608- }
609-
610- // Custom Validations
611- if err := contract .ValidateUniqueMaterialName (); err != nil {
612- return nil , NewErrValidation (err )
643+ // Try parsing as v2 Contract format first
644+ v2Contract := & schemav1.CraftingSchemaV2 {}
645+ v2Err := unmarshal .FromRaw (raw , format , v2Contract , true )
646+ if v2Err == nil {
647+ // Custom Validations
648+ if err := v2Contract .ValidateUniqueMaterialName (); err != nil {
649+ return nil , NewErrValidation (fmt .Errorf ("unique material name validation failed: %w" , err ))
650+ }
651+ if err := v2Contract .ValidatePolicyAttachments (); err != nil {
652+ return nil , NewErrValidation (fmt .Errorf ("policy attachment validation failed: %w" , err ))
653+ }
654+ return & Contract {Raw : raw , Format : format , Schemav2 : v2Contract }, nil
613655 }
614656
615- if err := contract .ValidatePolicyAttachments (); err != nil {
616- return nil , NewErrValidation (err )
657+ // Fallback to v1 CraftingSchema format
658+ v1Contract := & schemav1.CraftingSchema {}
659+ v1Err := unmarshal .FromRaw (raw , format , v1Contract , true )
660+ if v1Err == nil {
661+ // Custom Validations
662+ if err := v1Contract .ValidateUniqueMaterialName (); err != nil {
663+ return nil , NewErrValidation (fmt .Errorf ("unique material name validation failed: %w" , err ))
664+ }
665+ if err := v1Contract .ValidatePolicyAttachments (); err != nil {
666+ return nil , NewErrValidation (fmt .Errorf ("policy attachment validation failed: %w" , err ))
667+ }
668+ return & Contract {Raw : raw , Format : format , Schema : v1Contract }, nil
617669 }
618-
619- return & Contract {Raw : raw , Format : format , Schema : contract }, nil
670+ // Both parsing attempts failed
671+ // Best effort: provide errors for both schemas
672+ return nil , NewErrValidation (fmt .Errorf ("contract validation failed:\n v2 Contract format error: %w\n v1 CraftingSchema format error: %w" , v2Err , v1Err ))
620673}
621674
622675// Will try to figure out the format of the raw contract and validate it
0 commit comments