diff --git a/python/Makefile b/python/Makefile index 783001b6..c07e7034 100644 --- a/python/Makefile +++ b/python/Makefile @@ -70,5 +70,6 @@ protos: $(VENV_STAMP) @# Pydantic V2 is supported: https://github.com/danielgtaylor/python-betterproto/issues/530 protoc \ -I../protos \ - --python_betterproto_out=. \ + --python_betterproto_out=./in_toto_attestation/_internal \ $(PROTOS) + $(MAKE) reformat diff --git a/python/in_toto_attestation/__init__.py b/python/in_toto_attestation/__init__.py index 2ded3fc2..c5981731 100644 --- a/python/in_toto_attestation/__init__.py +++ b/python/in_toto_attestation/__init__.py @@ -1 +1 @@ -version = "0.9.3" +__version__ = "0.9.3" diff --git a/python/__init__.py b/python/in_toto_attestation/_internal/__init__.py similarity index 100% rename from python/__init__.py rename to python/in_toto_attestation/_internal/__init__.py diff --git a/python/in_toto_attestation/predicates/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/__init__.py diff --git a/python/in_toto_attestation/predicates/link/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/link/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/__init__.py diff --git a/python/in_toto_attestation/predicates/provenance/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/link/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/provenance/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/link/__init__.py diff --git a/python/in_toto_attestation/predicates/link/v0/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/link/v0/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/link/v0/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/link/v0/__init__.py diff --git a/python/in_toto_attestation/predicates/scai/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/provenance/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/scai/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/provenance/__init__.py diff --git a/python/in_toto_attestation/predicates/provenance/v1/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/provenance/v1/__init__.py similarity index 89% rename from python/in_toto_attestation/predicates/provenance/v1/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/provenance/v1/__init__.py index a5c6aaf4..f91e463a 100644 --- a/python/in_toto_attestation/predicates/provenance/v1/__init__.py +++ b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/provenance/v1/__init__.py @@ -36,9 +36,9 @@ class BuildDefinition(betterproto.Message): internal_parameters: "betterproto_lib_google_protobuf.Struct" = ( betterproto.message_field(3) ) - resolved_dependencies: List["___v1__.ResourceDescriptor"] = ( - betterproto.message_field(4) - ) + resolved_dependencies: List[ + "___v1__.ResourceDescriptor" + ] = betterproto.message_field(4) @dataclass(eq=False, repr=False) @@ -54,9 +54,9 @@ class Builder(betterproto.Message): version: Dict[str, str] = betterproto.map_field( 2, betterproto.TYPE_STRING, betterproto.TYPE_STRING ) - builder_dependencies: List["___v1__.ResourceDescriptor"] = ( - betterproto.message_field(3) - ) + builder_dependencies: List[ + "___v1__.ResourceDescriptor" + ] = betterproto.message_field(3) @dataclass(eq=False, repr=False) diff --git a/python/in_toto_attestation/predicates/test_result/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/scai/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/test_result/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/scai/__init__.py diff --git a/python/in_toto_attestation/predicates/scai/v0/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/scai/v0/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/scai/v0/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/scai/v0/__init__.py diff --git a/python/in_toto_attestation/predicates/vsa/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/test_result/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/vsa/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/test_result/__init__.py diff --git a/python/in_toto_attestation/predicates/test_result/v0/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/test_result/v0/__init__.py similarity index 100% rename from python/in_toto_attestation/predicates/test_result/v0/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/test_result/v0/__init__.py diff --git a/python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/in_toto_attestation/predicates/vsa/v0/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/v0/__init__.py similarity index 93% rename from python/in_toto_attestation/predicates/vsa/v0/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/v0/__init__.py index c6ab0b41..71720899 100644 --- a/python/in_toto_attestation/predicates/vsa/v0/__init__.py +++ b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/v0/__init__.py @@ -25,9 +25,9 @@ class VerificationSummary(betterproto.Message): time_verified: datetime = betterproto.message_field(2) resource_uri: str = betterproto.string_field(3) policy: "VerificationSummaryPolicy" = betterproto.message_field(4) - input_attestations: List["VerificationSummaryInputAttestation"] = ( - betterproto.message_field(5) - ) + input_attestations: List[ + "VerificationSummaryInputAttestation" + ] = betterproto.message_field(5) verification_result: str = betterproto.string_field(6) policy_level: str = betterproto.string_field(7) dependency_levels: Dict[str, int] = betterproto.map_field( diff --git a/python/in_toto_attestation/predicates/vsa/v1/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/v1/__init__.py similarity index 93% rename from python/in_toto_attestation/predicates/vsa/v1/__init__.py rename to python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/v1/__init__.py index 42b47532..bf3194b4 100644 --- a/python/in_toto_attestation/predicates/vsa/v1/__init__.py +++ b/python/in_toto_attestation/_internal/in_toto_attestation/predicates/vsa/v1/__init__.py @@ -25,9 +25,9 @@ class VerificationSummary(betterproto.Message): time_verified: datetime = betterproto.message_field(2) resource_uri: str = betterproto.string_field(3) policy: "VerificationSummaryPolicy" = betterproto.message_field(4) - input_attestations: List["VerificationSummaryInputAttestation"] = ( - betterproto.message_field(5) - ) + input_attestations: List[ + "VerificationSummaryInputAttestation" + ] = betterproto.message_field(5) verification_result: str = betterproto.string_field(6) verified_levels: str = betterproto.string_field(7) dependency_levels: Dict[str, int] = betterproto.map_field( diff --git a/python/in_toto_attestation/_internal/in_toto_attestation/v1/__init__.py b/python/in_toto_attestation/_internal/in_toto_attestation/v1/__init__.py new file mode 100644 index 00000000..f98c612b --- /dev/null +++ b/python/in_toto_attestation/_internal/in_toto_attestation/v1/__init__.py @@ -0,0 +1,57 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: in_toto_attestation/v1/resource_descriptor.proto, in_toto_attestation/v1/statement.proto +# plugin: python-betterproto +# This file has been @generated + +from dataclasses import dataclass +from typing import ( + Dict, + List, +) + +import betterproto +import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf + + +@dataclass(eq=False, repr=False) +class ResourceDescriptor(betterproto.Message): + """ + Proto representation of the in-toto v1 ResourceDescriptor. + https://github.com/in- + toto/attestation/blob/main/spec/v1/resource_descriptor.md Validation of all + fields is left to the users of this proto. + """ + + name: str = betterproto.string_field(1) + uri: str = betterproto.string_field(2) + digest: Dict[str, str] = betterproto.map_field( + 3, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + content: bytes = betterproto.bytes_field(4) + download_location: str = betterproto.string_field(5) + media_type: str = betterproto.string_field(6) + annotations: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(7) + """ + Per the Struct protobuf spec, this type corresponds to a JSON Object, which + is truly a map under the hood. So, the Struct a) is still + consistent with our specification for the `annotations` field, and b) has + native support in some language bindings making their use easier in + implementations. See: + https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#Struct + """ + + +@dataclass(eq=False, repr=False) +class Statement(betterproto.Message): + """ + Proto representation of the in-toto v1 Statement. https://github.com/in- + toto/attestation/tree/main/spec/v1 Validation of all fields is left to the + users of this proto. + """ + + type: str = betterproto.string_field(1) + """Expected to always be "https://in-toto.io/Statement/v1""" + + subject: List["ResourceDescriptor"] = betterproto.message_field(2) + predicate_type: str = betterproto.string_field(3) + predicate: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(4) diff --git a/python/in_toto_attestation/predicates/link/v0/link_pb2.py b/python/in_toto_attestation/predicates/link/v0/link_pb2.py deleted file mode 100644 index 6729a0fe..00000000 --- a/python/in_toto_attestation/predicates/link/v0/link_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/predicates/link/v0/link.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 - -from in_toto_attestation.v1 import ( - resource_descriptor_pb2 as in__toto__attestation_dot_v1_dot_resource__descriptor__pb2, -) - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n1in_toto_attestation/predicates/link/v0/link.proto\x12&in_toto_attestation.predicates.link.v0\x1a\x30in_toto_attestation/v1/resource_descriptor.proto\x1a\x1cgoogle/protobuf/struct.proto"\xbf\x01\n\x04Link\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x63ommand\x18\x02 \x03(\t\x12=\n\tmaterials\x18\x03 \x03(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor\x12+\n\nbyproducts\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\x12,\n\x0b\x65nvironment\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructBg\n/io.github.intoto.attestation.predicates.link.v0Z4github.com/in-toto/attestation/go/predicates/link/v0b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.predicates.link.v0.link_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n/io.github.intoto.attestation.predicates.link.v0Z4github.com/in-toto/attestation/go/predicates/link/v0" - _globals["_LINK"]._serialized_start = 174 - _globals["_LINK"]._serialized_end = 365 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/predicates/provenance/v1/provenance_pb2.py b/python/in_toto_attestation/predicates/provenance/v1/provenance_pb2.py deleted file mode 100644 index 55e37af5..00000000 --- a/python/in_toto_attestation/predicates/provenance/v1/provenance_pb2.py +++ /dev/null @@ -1,49 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/predicates/provenance/v1/provenance.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -from in_toto_attestation.v1 import ( - resource_descriptor_pb2 as in__toto__attestation_dot_v1_dot_resource__descriptor__pb2, -) - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n=in_toto_attestation/predicates/provenance/v1/provenance.proto\x12,in_toto_attestation.predicates.provenance.v1\x1a\x30in_toto_attestation/v1/resource_descriptor.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\xb4\x01\n\nProvenance\x12W\n\x10\x62uild_definition\x18\x01 \x01(\x0b\x32=.in_toto_attestation.predicates.provenance.v1.BuildDefinition\x12M\n\x0brun_details\x18\x02 \x01(\x0b\x32\x38.in_toto_attestation.predicates.provenance.v1.RunDetails"\xdc\x01\n\x0f\x42uildDefinition\x12\x12\n\nbuild_type\x18\x01 \x01(\t\x12\x34\n\x13\x65xternal_parameters\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x34\n\x13internal_parameters\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12I\n\x15resolved_dependencies\x18\x04 \x03(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor"\xe3\x01\n\nRunDetails\x12\x46\n\x07\x62uilder\x18\x01 \x01(\x0b\x32\x35.in_toto_attestation.predicates.provenance.v1.Builder\x12M\n\x08metadata\x18\x02 \x01(\x0b\x32;.in_toto_attestation.predicates.provenance.v1.BuildMetadata\x12>\n\nbyproducts\x18\x03 \x03(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor"\xe4\x01\n\x07\x42uilder\x12\n\n\x02id\x18\x01 \x01(\t\x12S\n\x07version\x18\x02 \x03(\x0b\x32\x42.in_toto_attestation.predicates.provenance.v1.Builder.VersionEntry\x12H\n\x14\x62uilder_dependencies\x18\x03 \x03(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor\x1a.\n\x0cVersionEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\x87\x01\n\rBuildMetadata\x12\x15\n\rinvocation_id\x18\x01 \x01(\t\x12.\n\nstarted_on\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0b\x66inished_on\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampBs\n5io.github.intoto.attestation.predicates.provenance.v1Z:github.com/in-toto/attestation/go/predicates/provenance/v1b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.predicates.provenance.v1.provenance_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n5io.github.intoto.attestation.predicates.provenance.v1Z:github.com/in-toto/attestation/go/predicates/provenance/v1" - _globals["_BUILDER_VERSIONENTRY"]._options = None - _globals["_BUILDER_VERSIONENTRY"]._serialized_options = b"8\001" - _globals["_PROVENANCE"]._serialized_start = 225 - _globals["_PROVENANCE"]._serialized_end = 405 - _globals["_BUILDDEFINITION"]._serialized_start = 408 - _globals["_BUILDDEFINITION"]._serialized_end = 628 - _globals["_RUNDETAILS"]._serialized_start = 631 - _globals["_RUNDETAILS"]._serialized_end = 858 - _globals["_BUILDER"]._serialized_start = 861 - _globals["_BUILDER"]._serialized_end = 1089 - _globals["_BUILDER_VERSIONENTRY"]._serialized_start = 1043 - _globals["_BUILDER_VERSIONENTRY"]._serialized_end = 1089 - _globals["_BUILDMETADATA"]._serialized_start = 1092 - _globals["_BUILDMETADATA"]._serialized_end = 1227 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/predicates/scai/v0/scai.py b/python/in_toto_attestation/predicates/scai/v0/scai.py deleted file mode 100644 index ccb7e127..00000000 --- a/python/in_toto_attestation/predicates/scai/v0/scai.py +++ /dev/null @@ -1,72 +0,0 @@ -# Wrapper class for in-toto attestation SCAI predicate protos. - -import in_toto_attestation.predicates.scai.v0.scai_pb2 as scaipb -from in_toto_attestation.v1.resource_descriptor import ResourceDescriptor - -SCAI_PREDICATE_TYPE = "https://in-toto.io/attestation/scai/attribute-report/" -SCAI_PREDICATE_VERSION = "v0.2" - - -class AttributeAssertion: - def __init__(self, attribute, target=None, conditions=None, evidence=None) -> None: - self.pb = scaipb.AttributeAssertion() # type: ignore[attr-defined] - self.pb.attribute = attribute - if target: - self.pb.target.CopyFrom(target) - if conditions: - self.pb.conditions.update(conditions) - if evidence: - self.pb.evidence.CopyFrom(evidence) - - @staticmethod - def copy_from_pb(proto: type[scaipb.AttributeAssertion]) -> "AttributeAssertion": # type: ignore[name-defined] - assertion = AttributeAssertion("tmp-attr") - assertion.pb.CopyFrom(proto) - return assertion - - def validate(self) -> None: - if len(self.pb.attribute) == 0: - raise ValueError("The attribute field is required") - - # check any resource descriptors are valid - if self.pb.target.ByteSize() > 0: - rd = ResourceDescriptor.copy_from_pb(self.pb.target) - rd.validate() - - if self.pb.evidence.ByteSize() > 0: - rd = ResourceDescriptor.copy_from_pb(self.pb.evidence) - rd.validate() - - -class AttributeReport: - def __init__(self, attributes: list, producer=None) -> None: - self.pb = scaipb.AttributeReport() # type: ignore[attr-defined] - self.pb.attributes.extend(attributes) - if producer: - self.pb.producer.CopyFrom(producer) - - @staticmethod - def copy_from_pb(proto: type[scaipb.AttributeReport]) -> "AttributeReport": # type: ignore[name-defined] - report = AttributeReport([None]) - report.pb.CopyFrom(proto) - return report - - def validate(self) -> None: - if len(self.pb.attributes) == 0: - raise ValueError("The attributes field is required") - - # check any attribute assertions are valid - attributes = self.pb.attributes - for i, attrpb in enumerate(attributes): - assertion = AttributeAssertion.copy_from_pb(attrpb) - - try: - assertion.validate() - except ValueError as e: - # return index in the attributes list in case of failure: - # can't assume any other fields in attribute assertion are set - raise ValueError(f"Invalid attributes field (index: {i})") from e - - if self.pb.producer.ByteSize() > 0: - rd = ResourceDescriptor.copy_from_pb(self.pb.producer) - rd.validate() diff --git a/python/in_toto_attestation/predicates/scai/v0/scai_pb2.py b/python/in_toto_attestation/predicates/scai/v0/scai_pb2.py deleted file mode 100644 index 8ce56c02..00000000 --- a/python/in_toto_attestation/predicates/scai/v0/scai_pb2.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/predicates/scai/v0/scai.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 - -from in_toto_attestation.v1 import ( - resource_descriptor_pb2 as in__toto__attestation_dot_v1_dot_resource__descriptor__pb2, -) - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n1in_toto_attestation/predicates/scai/v0/scai.proto\x12&in_toto_attestation.predicates.scai.v0\x1a\x1cgoogle/protobuf/struct.proto\x1a\x30in_toto_attestation/v1/resource_descriptor.proto"\xce\x01\n\x12\x41ttributeAssertion\x12\x11\n\tattribute\x18\x01 \x01(\t\x12:\n\x06target\x18\x02 \x01(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor\x12+\n\nconditions\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12<\n\x08\x65vidence\x18\x04 \x01(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor"\x9f\x01\n\x0f\x41ttributeReport\x12N\n\nattributes\x18\x01 \x03(\x0b\x32:.in_toto_attestation.predicates.scai.v0.AttributeAssertion\x12<\n\x08producer\x18\x02 \x01(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptorBg\n/io.github.intoto.attestation.predicates.scai.v0Z4github.com/in-toto/attestation/go/predicates/scai/v0b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.predicates.scai.v0.scai_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n/io.github.intoto.attestation.predicates.scai.v0Z4github.com/in-toto/attestation/go/predicates/scai/v0" - _globals["_ATTRIBUTEASSERTION"]._serialized_start = 174 - _globals["_ATTRIBUTEASSERTION"]._serialized_end = 380 - _globals["_ATTRIBUTEREPORT"]._serialized_start = 383 - _globals["_ATTRIBUTEREPORT"]._serialized_end = 542 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/predicates/test_result/v0/test_result_pb2.py b/python/in_toto_attestation/predicates/test_result/v0/test_result_pb2.py deleted file mode 100644 index 59712163..00000000 --- a/python/in_toto_attestation/predicates/test_result/v0/test_result_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/predicates/test_result/v0/test_result.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from in_toto_attestation.v1 import ( - resource_descriptor_pb2 as in__toto__attestation_dot_v1_dot_resource__descriptor__pb2, -) - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n?in_toto_attestation/predicates/test_result/v0/test_result.proto\x12-in_toto_attestation.predicates.test_result.v0\x1a\x30in_toto_attestation/v1/resource_descriptor.proto"\xae\x01\n\nTestResult\x12\x0e\n\x06result\x18\x01 \x01(\t\x12\x41\n\rconfiguration\x18\x02 \x03(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor\x12\x0b\n\x03url\x18\x03 \x01(\t\x12\x14\n\x0cpassed_tests\x18\x04 \x03(\t\x12\x14\n\x0cwarned_tests\x18\x05 \x03(\t\x12\x14\n\x0c\x66\x61iled_tests\x18\x06 \x03(\tBu\n6io.github.intoto.attestation.predicates.test_result.v0Z;github.com/in-toto/attestation/go/predicates/test_result/v0b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, - "in_toto_attestation.predicates.test_result.v0.test_result_pb2", - _globals, -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n6io.github.intoto.attestation.predicates.test_result.v0Z;github.com/in-toto/attestation/go/predicates/test_result/v0" - _globals["_TESTRESULT"]._serialized_start = 165 - _globals["_TESTRESULT"]._serialized_end = 339 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/predicates/vsa/v0/vsa_pb2.py b/python/in_toto_attestation/predicates/vsa/v0/vsa_pb2.py deleted file mode 100644 index 04894a8f..00000000 --- a/python/in_toto_attestation/predicates/vsa/v0/vsa_pb2.py +++ /dev/null @@ -1,56 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/predicates/vsa/v0/vsa.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n/in_toto_attestation/predicates/vsa/v0/vsa.proto\x12%in_toto_attestation.predicates.vsa.v0\x1a\x1fgoogle/protobuf/timestamp.proto"\xa9\x08\n\x13VerificationSummary\x12U\n\x08verifier\x18\x01 \x01(\x0b\x32\x43.in_toto_attestation.predicates.vsa.v0.VerificationSummary.Verifier\x12@\n\rtime_verified\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\rtime_verified\x12"\n\x0cresource_uri\x18\x03 \x01(\tR\x0cresource_uri\x12Q\n\x06policy\x18\x04 \x01(\x0b\x32\x41.in_toto_attestation.predicates.vsa.v0.VerificationSummary.Policy\x12{\n\x12input_attestations\x18\x05 \x03(\x0b\x32K.in_toto_attestation.predicates.vsa.v0.VerificationSummary.InputAttestationR\x12input_attestations\x12\x30\n\x13verification_result\x18\x06 \x01(\tR\x13verification_result\x12"\n\x0cpolicy_level\x18\x07 \x01(\tR\x0cpolicy_level\x12~\n\x11\x64\x65pendency_levels\x18\x08 \x03(\x0b\x32P.in_toto_attestation.predicates.vsa.v0.VerificationSummary.DependencyLevelsEntryR\x11\x64\x65pendency_levels\x1a\x16\n\x08Verifier\x12\n\n\x02id\x18\x01 \x01(\t\x1a\xa3\x01\n\x06Policy\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12]\n\x06\x64igest\x18\x02 \x03(\x0b\x32M.in_toto_attestation.predicates.vsa.v0.VerificationSummary.Policy.DigestEntry\x1a-\n\x0b\x44igestEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\xb7\x01\n\x10InputAttestation\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12g\n\x06\x64igest\x18\x02 \x03(\x0b\x32W.in_toto_attestation.predicates.vsa.v0.VerificationSummary.InputAttestation.DigestEntry\x1a-\n\x0b\x44igestEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x37\n\x15\x44\x65pendencyLevelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x04:\x02\x38\x01\x42\x65\n.io.github.intoto.attestation.predicates.vsa.v0Z3github.com/in-toto/attestation/go/predicates/vsa/v0b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.predicates.vsa.v0.vsa_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n.io.github.intoto.attestation.predicates.vsa.v0Z3github.com/in-toto/attestation/go/predicates/vsa/v0" - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._options = None - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._serialized_options = b"8\001" - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY"]._options = None - _globals[ - "_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY" - ]._serialized_options = b"8\001" - _globals["_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY"]._options = None - _globals[ - "_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY" - ]._serialized_options = b"8\001" - _globals["_VERIFICATIONSUMMARY"]._serialized_start = 124 - _globals["_VERIFICATIONSUMMARY"]._serialized_end = 1189 - _globals["_VERIFICATIONSUMMARY_VERIFIER"]._serialized_start = 758 - _globals["_VERIFICATIONSUMMARY_VERIFIER"]._serialized_end = 780 - _globals["_VERIFICATIONSUMMARY_POLICY"]._serialized_start = 783 - _globals["_VERIFICATIONSUMMARY_POLICY"]._serialized_end = 946 - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._serialized_start = 901 - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._serialized_end = 946 - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION"]._serialized_start = 949 - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION"]._serialized_end = 1132 - _globals[ - "_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY" - ]._serialized_start = 901 - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY"]._serialized_end = 946 - _globals["_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY"]._serialized_start = 1134 - _globals["_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY"]._serialized_end = 1189 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/predicates/vsa/v1/vsa_pb2.py b/python/in_toto_attestation/predicates/vsa/v1/vsa_pb2.py deleted file mode 100644 index 2bd9a2c6..00000000 --- a/python/in_toto_attestation/predicates/vsa/v1/vsa_pb2.py +++ /dev/null @@ -1,56 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/predicates/vsa/v1/vsa.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n/in_toto_attestation/predicates/vsa/v1/vsa.proto\x12%in_toto_attestation.predicates.vsa.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xcc\x08\n\x13VerificationSummary\x12U\n\x08verifier\x18\x01 \x01(\x0b\x32\x43.in_toto_attestation.predicates.vsa.v1.VerificationSummary.Verifier\x12?\n\rtime_verified\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x0ctimeVerified\x12!\n\x0cresource_uri\x18\x03 \x01(\tR\x0bresourceUri\x12Q\n\x06policy\x18\x04 \x01(\x0b\x32\x41.in_toto_attestation.predicates.vsa.v1.VerificationSummary.Policy\x12z\n\x12input_attestations\x18\x05 \x03(\x0b\x32K.in_toto_attestation.predicates.vsa.v1.VerificationSummary.InputAttestationR\x11inputAttestations\x12/\n\x13verification_result\x18\x06 \x01(\tR\x12verificationResult\x12'\n\x0fverified_levels\x18\x07 \x01(\tR\x0everifiedLevels\x12}\n\x11\x64\x65pendency_levels\x18\x08 \x03(\x0b\x32P.in_toto_attestation.predicates.vsa.v1.VerificationSummary.DependencyLevelsEntryR\x10\x64\x65pendencyLevels\x12!\n\x0cslsa_version\x18\t \x01(\tR\x0bslsaVersion\x1a\x16\n\x08Verifier\x12\n\n\x02id\x18\x01 \x01(\t\x1a\xa3\x01\n\x06Policy\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12]\n\x06\x64igest\x18\x02 \x03(\x0b\x32M.in_toto_attestation.predicates.vsa.v1.VerificationSummary.Policy.DigestEntry\x1a-\n\x0b\x44igestEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\xb7\x01\n\x10InputAttestation\x12\x0b\n\x03uri\x18\x01 \x01(\t\x12g\n\x06\x64igest\x18\x02 \x03(\x0b\x32W.in_toto_attestation.predicates.vsa.v1.VerificationSummary.InputAttestation.DigestEntry\x1a-\n\x0b\x44igestEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x37\n\x15\x44\x65pendencyLevelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x04:\x02\x38\x01\x42\x65\n.io.github.intoto.attestation.predicates.vsa.v1Z3github.com/in-toto/attestation/go/predicates/vsa/v1b\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.predicates.vsa.v1.vsa_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n.io.github.intoto.attestation.predicates.vsa.v1Z3github.com/in-toto/attestation/go/predicates/vsa/v1" - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._options = None - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._serialized_options = b"8\001" - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY"]._options = None - _globals[ - "_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY" - ]._serialized_options = b"8\001" - _globals["_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY"]._options = None - _globals[ - "_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY" - ]._serialized_options = b"8\001" - _globals["_VERIFICATIONSUMMARY"]._serialized_start = 124 - _globals["_VERIFICATIONSUMMARY"]._serialized_end = 1224 - _globals["_VERIFICATIONSUMMARY_VERIFIER"]._serialized_start = 793 - _globals["_VERIFICATIONSUMMARY_VERIFIER"]._serialized_end = 815 - _globals["_VERIFICATIONSUMMARY_POLICY"]._serialized_start = 818 - _globals["_VERIFICATIONSUMMARY_POLICY"]._serialized_end = 981 - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._serialized_start = 936 - _globals["_VERIFICATIONSUMMARY_POLICY_DIGESTENTRY"]._serialized_end = 981 - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION"]._serialized_start = 984 - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION"]._serialized_end = 1167 - _globals[ - "_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY" - ]._serialized_start = 936 - _globals["_VERIFICATIONSUMMARY_INPUTATTESTATION_DIGESTENTRY"]._serialized_end = 981 - _globals["_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY"]._serialized_start = 1169 - _globals["_VERIFICATIONSUMMARY_DEPENDENCYLEVELSENTRY"]._serialized_end = 1224 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/v1/__init__.py b/python/in_toto_attestation/v1/__init__.py index f98c612b..e69de29b 100644 --- a/python/in_toto_attestation/v1/__init__.py +++ b/python/in_toto_attestation/v1/__init__.py @@ -1,57 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# sources: in_toto_attestation/v1/resource_descriptor.proto, in_toto_attestation/v1/statement.proto -# plugin: python-betterproto -# This file has been @generated - -from dataclasses import dataclass -from typing import ( - Dict, - List, -) - -import betterproto -import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf - - -@dataclass(eq=False, repr=False) -class ResourceDescriptor(betterproto.Message): - """ - Proto representation of the in-toto v1 ResourceDescriptor. - https://github.com/in- - toto/attestation/blob/main/spec/v1/resource_descriptor.md Validation of all - fields is left to the users of this proto. - """ - - name: str = betterproto.string_field(1) - uri: str = betterproto.string_field(2) - digest: Dict[str, str] = betterproto.map_field( - 3, betterproto.TYPE_STRING, betterproto.TYPE_STRING - ) - content: bytes = betterproto.bytes_field(4) - download_location: str = betterproto.string_field(5) - media_type: str = betterproto.string_field(6) - annotations: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(7) - """ - Per the Struct protobuf spec, this type corresponds to a JSON Object, which - is truly a map under the hood. So, the Struct a) is still - consistent with our specification for the `annotations` field, and b) has - native support in some language bindings making their use easier in - implementations. See: - https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#Struct - """ - - -@dataclass(eq=False, repr=False) -class Statement(betterproto.Message): - """ - Proto representation of the in-toto v1 Statement. https://github.com/in- - toto/attestation/tree/main/spec/v1 Validation of all fields is left to the - users of this proto. - """ - - type: str = betterproto.string_field(1) - """Expected to always be "https://in-toto.io/Statement/v1""" - - subject: List["ResourceDescriptor"] = betterproto.message_field(2) - predicate_type: str = betterproto.string_field(3) - predicate: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(4) diff --git a/python/in_toto_attestation/v1/resource_descriptor.py b/python/in_toto_attestation/v1/resource_descriptor.py index 3ab4bb6e..a7ed3582 100644 --- a/python/in_toto_attestation/v1/resource_descriptor.py +++ b/python/in_toto_attestation/v1/resource_descriptor.py @@ -2,12 +2,9 @@ from __future__ import annotations -import json - -import google.protobuf.json_format as pb_json -from google.protobuf.struct_pb2 import Value - -import in_toto_attestation.v1.resource_descriptor_pb2 as rdpb +from in_toto_attestation._internal.in_toto_attestation.v1 import ( + ResourceDescriptor as _ResourceDescriptor, +) class ResourceDescriptor: @@ -21,24 +18,48 @@ def __init__( media_type: str = "", annotations: dict | None = None, ) -> None: - self.pb = rdpb.ResourceDescriptor() # type: ignore[attr-defined] + self.pb = _ResourceDescriptor() self.pb.name = name self.pb.uri = uri - if digest: - self.pb.digest.update(digest) + self.pb.digest = digest self.pb.content = content self.pb.download_location = download_location self.pb.media_type = media_type if annotations: - self.pb.annotations.update(annotations) + self.pb.annotations.fields = annotations + + self._validate() + + @classmethod + def from_pb(cls, raw: bytes) -> ResourceDescriptor: + pb = _ResourceDescriptor.parse(raw) + return cls( + pb.name, + pb.uri, + pb.digest, + pb.content, + pb.download_location, + pb.media_type, + pb.annotations, + ) + + @classmethod + def from_json(cls, raw: str) -> ResourceDescriptor: + pb = _ResourceDescriptor().from_json(raw) + return cls( + pb.name, + pb.uri, + pb.digest, + pb.content, + pb.download_location, + pb.media_type, + pb.annotations, + ) - @staticmethod - def copy_from_pb(proto: rdpb.ResourceDescriptor) -> ResourceDescriptor: # type: ignore[name-defined] - rd = ResourceDescriptor() - rd.pb.CopyFrom(proto) - return rd + def to_json(self) -> str: + self.pb.to_json() - def validate(self) -> None: + def _validate(self) -> None: # at least one of name, URI or digest are required if self.pb.name == "" and self.pb.uri == "" and len(self.pb.digest) == 0: raise ValueError("At least one of name, URI, or digest need to be set") diff --git a/python/in_toto_attestation/v1/resource_descriptor_pb2.py b/python/in_toto_attestation/v1/resource_descriptor_pb2.py deleted file mode 100644 index 1da6eb23..00000000 --- a/python/in_toto_attestation/v1/resource_descriptor_pb2.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/v1/resource_descriptor.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n0in_toto_attestation/v1/resource_descriptor.proto\x12\x16in_toto_attestation.v1\x1a\x1cgoogle/protobuf/struct.proto"\x94\x02\n\x12ResourceDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\x46\n\x06\x64igest\x18\x03 \x03(\x0b\x32\x36.in_toto_attestation.v1.ResourceDescriptor.DigestEntry\x12\x0f\n\x07\x63ontent\x18\x04 \x01(\x0c\x12\x19\n\x11\x64ownload_location\x18\x05 \x01(\t\x12\x12\n\nmedia_type\x18\x06 \x01(\t\x12,\n\x0b\x61nnotations\x18\x07 \x01(\x0b\x32\x17.google.protobuf.Struct\x1a-\n\x0b\x44igestEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42G\n\x1fio.github.intoto.attestation.v1Z$github.com/in-toto/attestation/go/v1b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.v1.resource_descriptor_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = ( - b"\n\037io.github.intoto.attestation.v1Z$github.com/in-toto/attestation/go/v1" - ) - _globals["_RESOURCEDESCRIPTOR_DIGESTENTRY"]._options = None - _globals["_RESOURCEDESCRIPTOR_DIGESTENTRY"]._serialized_options = b"8\001" - _globals["_RESOURCEDESCRIPTOR"]._serialized_start = 107 - _globals["_RESOURCEDESCRIPTOR"]._serialized_end = 383 - _globals["_RESOURCEDESCRIPTOR_DIGESTENTRY"]._serialized_start = 338 - _globals["_RESOURCEDESCRIPTOR_DIGESTENTRY"]._serialized_end = 383 -# @@protoc_insertion_point(module_scope) diff --git a/python/in_toto_attestation/v1/statement.py b/python/in_toto_attestation/v1/statement.py index 2f3b6f08..f15ada3a 100644 --- a/python/in_toto_attestation/v1/statement.py +++ b/python/in_toto_attestation/v1/statement.py @@ -1,46 +1,36 @@ # Wrapper class for in-toto attestation Statement protos. -import in_toto_attestation.v1.statement_pb2 as spb +from in_toto_attestation._internal.in_toto_attestation.v1 import Statement as _Statement from in_toto_attestation.v1.resource_descriptor import ResourceDescriptor -STATEMENT_TYPE_URI = "https://in-toto.io/Statement/v1" - +# import in_toto_attestation.v1.statement_pb2 as spb +# from in_toto_attestation.v1.resource_descriptor import ResourceDescriptor -class Statement: - def __init__(self, subjects: list, predicate_type: str, predicate: dict) -> None: - self.pb = spb.Statement() # type: ignore[attr-defined] - self.pb.type = STATEMENT_TYPE_URI - self.pb.subject.extend(subjects) - self.pb.predicate_type = predicate_type - self.pb.predicate.update(predicate) +STATEMENT_TYPE_URI = "https://in-toto.io/Statement/v1" - @staticmethod - def copy_from_pb(proto: spb.Statement) -> "Statement": # type: ignore[name-defined] - stmt = Statement([], "", {}) - stmt.pb.CopyFrom(proto) - return stmt +class Statement(_Statement): def validate(self) -> None: - if self.pb.type != STATEMENT_TYPE_URI: + if self.type != STATEMENT_TYPE_URI: raise ValueError("Wrong statement type") - if len(self.pb.subject) == 0: + if len(self.subject) == 0: raise ValueError("At least one subject required") # check all resource descriptors in the subject - subject = self.pb.subject + subject = self.subject for i, rdpb in enumerate(subject): - rd = ResourceDescriptor.copy_from_pb(rdpb) + rd = ResourceDescriptor().from_dict(rdpb.to_dict()) rd.validate() # v1 statements require the digest to be set in the subject - if len(rd.pb.digest) == 0: + if len(rd.digest) == 0: # return index in the subjects list in case of failure: # can't assume any other fields in subject are set raise ValueError(f"At least one digest required (subject {i})") - if self.pb.predicate_type == "": + if self.predicate_type == "": raise ValueError("Predicate type required") - if len(self.pb.predicate) == 0: + if len(self.predicate) == 0: raise ValueError("Predicate object required") diff --git a/python/in_toto_attestation/v1/statement_pb2.py b/python/in_toto_attestation/v1/statement_pb2.py deleted file mode 100644 index 391eab2d..00000000 --- a/python/in_toto_attestation/v1/statement_pb2.py +++ /dev/null @@ -1,38 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: in_toto_attestation/v1/statement.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 - -from in_toto_attestation.v1 import ( - resource_descriptor_pb2 as in__toto__attestation_dot_v1_dot_resource__descriptor__pb2, -) - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n&in_toto_attestation/v1/statement.proto\x12\x16in_toto_attestation.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x30in_toto_attestation/v1/resource_descriptor.proto"\xa1\x01\n\tStatement\x12\x13\n\x04type\x18\x01 \x01(\tR\x05_type\x12;\n\x07subject\x18\x02 \x03(\x0b\x32*.in_toto_attestation.v1.ResourceDescriptor\x12\x16\n\x0epredicate_type\x18\x03 \x01(\t\x12*\n\tpredicate\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructBG\n\x1fio.github.intoto.attestation.v1Z$github.com/in-toto/attestation/go/v1b\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "in_toto_attestation.v1.statement_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals["DESCRIPTOR"]._options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = ( - b"\n\037io.github.intoto.attestation.v1Z$github.com/in-toto/attestation/go/v1" - ) - _globals["_STATEMENT"]._serialized_start = 147 - _globals["_STATEMENT"]._serialized_end = 308 -# @@protoc_insertion_point(module_scope) diff --git a/python/pyproject.toml b/python/pyproject.toml index 420380d3..2ce5e93a 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -64,9 +64,6 @@ ignore = [ ] [tool.mypy] -# Don't bother type-checking the generated files. -# TODO: Use `mypy-protobuf` for these: https://github.com/nipunn1313/mypy-protobuf -exclude = ['^.+_pb2.py$'] warn_unused_configs = true warn_unused_ignores = true show_error_codes = true diff --git a/python/tests/test_resource_descriptor.py b/python/tests/test_resource_descriptor.py index 643a7620..01aaf59e 100644 --- a/python/tests/test_resource_descriptor.py +++ b/python/tests/test_resource_descriptor.py @@ -4,9 +4,6 @@ import unittest -import google.protobuf.json_format as pb_json - -import in_toto_attestation.v1.resource_descriptor_pb2 as rdpb from in_toto_attestation.v1.resource_descriptor import ResourceDescriptor @@ -26,51 +23,42 @@ def create_test_desc(): class TestResourceDescriptor(unittest.TestCase): def test_create_resource_descriptor(self): - test_rd = create_test_desc() - test_rd.validate() + create_test_desc() def test_json_parse_resource_descriptor(self): full_rd = '{"name":"theName","uri":"https://example.com","digest":{"alg":"abc123"},"content":"Ynl0ZXNjb250ZW50","downloadLocation":"https://example.com/test.zip","mediaType":"theMediaType","annotations":{"keyNum": 13,"keyStr":"val1","keyObj":{"subKey":"subVal"}}}' - got_pb = pb_json.Parse(full_rd, rdpb.ResourceDescriptor()) - got = got_pb.SerializeToString(deterministic=True) + + got_pb = ResourceDescriptor.from_json(full_rd) + got = got_pb.to_json() test_rd = create_test_desc() - want = test_rd.pb.SerializeToString(deterministic=True) + want = test_rd.to_json() self.assertEqual(got, want, "Protos do not match") def test_bad_resource_descriptor(self): bad_rd = '{"downloadLocation":"https://example.com/test.zip","mediaType":"theMediaType"}' - got_pb = pb_json.Parse(bad_rd, rdpb.ResourceDescriptor()) - got = ResourceDescriptor.copy_from_pb(got_pb) - with self.assertRaises( ValueError, msg="Error: created malformed ResourceDescriptor (no required fields)", ): - got.validate() + ResourceDescriptor.from_json(bad_rd) def test_empty_name_only(self): bad_rd = '{"name":"","downloadLocation":"https://example.com/test.zip","mediaType":"theMediaType"}' - got_pb = pb_json.Parse(bad_rd, rdpb.ResourceDescriptor()) - got = ResourceDescriptor.copy_from_pb(got_pb) - with self.assertRaises( ValueError, msg="Error: created malformed ResourceDescriptor (only empty required fields)", ): - got.validate() + ResourceDescriptor.from_json(bad_rd) def test_empty_digest(self): empty_digest = '{"name":"theName","digest":{},"downloadLocation":"https://example.com/test.zip","mediaType":"theMediaType"}' - got_pb = pb_json.Parse(empty_digest, rdpb.ResourceDescriptor()) - got = ResourceDescriptor.copy_from_pb(got_pb) - # this should not raise an error - got.validate() + ResourceDescriptor.from_json(empty_digest) if __name__ == "__main__":