diff --git a/Makefile b/Makefile index 6d6e9397..0d2b5f1a 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ python: docker-image -v ${PWD}:/defs \ -e PYTHONPATH="/opt/mypy-protobuf/" \ --entrypoint bash ${PROTOC_IMAGE} \ - -c "cd ./gen/pb-python/sigstore_protobuf_specs && protoc -I/opt/include -I../../../protos/ --python_betterproto_out=. ../../../protos/*.proto" + -c "cd ./gen/pb-python/sigstore_protobuf_specs && protoc -I/opt/include -I../../../protos/ --python_betterproto_out=. --python_betterproto_opt=pydantic_dataclasses ../../../protos/*.proto" typescript: docker-image @echo "Generating javascript protobuf files" diff --git a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/bundle/v1/__init__.py b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/bundle/v1/__init__.py index e08307fb..439be181 100644 --- a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/bundle/v1/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/bundle/v1/__init__.py @@ -3,10 +3,22 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass -from typing import List +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + +from typing import ( + List, + Optional, +) import betterproto +from pydantic import model_validator +from pydantic.dataclasses import rebuild_dataclass from .....io import intoto as ____io_intoto__ from ...common import v1 as __common_v1__ @@ -47,14 +59,14 @@ class VerificationMaterial(betterproto.Message): extension is attached to. """ - public_key: "__common_v1__.PublicKeyIdentifier" = betterproto.message_field( - 1, group="content" + public_key: Optional["__common_v1__.PublicKeyIdentifier"] = ( + betterproto.message_field(1, optional=True, group="content") ) - x509_certificate_chain: "__common_v1__.X509CertificateChain" = ( - betterproto.message_field(2, group="content") + x509_certificate_chain: Optional["__common_v1__.X509CertificateChain"] = ( + betterproto.message_field(2, optional=True, group="content") ) - certificate: "__common_v1__.X509Certificate" = betterproto.message_field( - 5, group="content" + certificate: Optional["__common_v1__.X509Certificate"] = betterproto.message_field( + 5, optional=True, group="content" ) tlog_entries: List["__rekor_v1__.TransparencyLogEntry"] = betterproto.message_field( 3 @@ -77,6 +89,10 @@ class VerificationMaterial(betterproto.Message): tlog_entries.inclusion_promise.signed_entry_timestamp. """ + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) + @dataclass(eq=False, repr=False) class Bundle(betterproto.Message): @@ -104,11 +120,11 @@ class Bundle(betterproto.Message): DSSE envelope. """ - message_signature: "__common_v1__.MessageSignature" = betterproto.message_field( - 3, group="content" + message_signature: Optional["__common_v1__.MessageSignature"] = ( + betterproto.message_field(3, optional=True, group="content") ) - dsse_envelope: "____io_intoto__.Envelope" = betterproto.message_field( - 4, group="content" + dsse_envelope: Optional["____io_intoto__.Envelope"] = betterproto.message_field( + 4, optional=True, group="content" ) """ A DSSE envelope can contain arbitrary payloads. @@ -125,3 +141,12 @@ class Bundle(betterproto.Message): During verification a client MUST reject an envelope if the number of signatures is not equal to one. """ + + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) + + +rebuild_dataclass(TimestampVerificationData) # type: ignore +rebuild_dataclass(VerificationMaterial) # type: ignore +rebuild_dataclass(Bundle) # type: ignore diff --git a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/common/v1/__init__.py b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/common/v1/__init__.py index 70d14f2b..8c9e2883 100644 --- a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/common/v1/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/common/v1/__init__.py @@ -3,7 +3,14 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + from datetime import datetime from typing import ( List, @@ -11,6 +18,8 @@ ) import betterproto +from pydantic import model_validator +from pydantic.dataclasses import rebuild_dataclass class HashAlgorithm(betterproto.Enum): @@ -31,6 +40,12 @@ class HashAlgorithm(betterproto.Enum): SHA3_256 = 4 SHA3_384 = 5 + @classmethod + def __get_pydantic_core_schema__(cls, _source_type, _handler): + from pydantic_core import core_schema + + return core_schema.int_schema(ge=0) + class PublicKeyDetails(betterproto.Enum): """ @@ -98,6 +113,12 @@ class PublicKeyDetails(betterproto.Enum): LMOTS_SHA256 = 15 + @classmethod + def __get_pydantic_core_schema__(cls, _source_type, _handler): + from pydantic_core import core_schema + + return core_schema.int_schema(ge=0) + class SubjectAlternativeNameType(betterproto.Enum): UNSPECIFIED = 0 @@ -110,6 +131,12 @@ class SubjectAlternativeNameType(betterproto.Enum): for more details. """ + @classmethod + def __get_pydantic_core_schema__(cls, _source_type, _handler): + from pydantic_core import core_schema + + return core_schema.int_schema(ge=0) + @dataclass(eq=False, repr=False) class HashOutput(betterproto.Message): @@ -235,15 +262,19 @@ class X509Certificate(betterproto.Message): @dataclass(eq=False, repr=False) class SubjectAlternativeName(betterproto.Message): type: "SubjectAlternativeNameType" = betterproto.enum_field(1) - regexp: str = betterproto.string_field(2, group="identity") + regexp: Optional[str] = betterproto.string_field(2, optional=True, group="identity") """ A regular expression describing the expected value for the SAN. """ - value: str = betterproto.string_field(3, group="identity") + value: Optional[str] = betterproto.string_field(3, optional=True, group="identity") """The exact value to match against.""" + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) + @dataclass(eq=False, repr=False) class X509CertificateChain(betterproto.Message): @@ -276,3 +307,12 @@ class TimeRange(betterproto.Message): start: datetime = betterproto.message_field(1) end: Optional[datetime] = betterproto.message_field(2, optional=True) + + +rebuild_dataclass(HashOutput) # type: ignore +rebuild_dataclass(MessageSignature) # type: ignore +rebuild_dataclass(PublicKey) # type: ignore +rebuild_dataclass(ObjectIdentifierValuePair) # type: ignore +rebuild_dataclass(SubjectAlternativeName) # type: ignore +rebuild_dataclass(X509CertificateChain) # type: ignore +rebuild_dataclass(TimeRange) # type: ignore diff --git a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/events/v1/__init__.py b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/events/v1/__init__.py index bb257568..a31b8514 100644 --- a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/events/v1/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/events/v1/__init__.py @@ -3,15 +3,25 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + from datetime import datetime from typing import ( Dict, List, + Optional, ) import betterproto -import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf +import betterproto.lib.pydantic.google.protobuf as betterproto_lib_pydantic_google_protobuf +from pydantic import model_validator +from pydantic.dataclasses import rebuild_dataclass @dataclass(eq=False, repr=False) @@ -27,24 +37,41 @@ class CloudEvent(betterproto.Message): ) """Optional & Extension Attributes""" - binary_data: bytes = betterproto.bytes_field(6, group="data") - text_data: str = betterproto.string_field(7, group="data") - proto_data: "betterproto_lib_google_protobuf.Any" = betterproto.message_field( - 8, group="data" + binary_data: Optional[bytes] = betterproto.bytes_field( + 6, optional=True, group="data" ) + text_data: Optional[str] = betterproto.string_field(7, optional=True, group="data") + proto_data: Optional["betterproto_lib_pydantic_google_protobuf.Any"] = ( + betterproto.message_field(8, optional=True, group="data") + ) + + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) @dataclass(eq=False, repr=False) class CloudEventCloudEventAttributeValue(betterproto.Message): - ce_boolean: bool = betterproto.bool_field(1, group="attr") - ce_integer: int = betterproto.int32_field(2, group="attr") - ce_string: str = betterproto.string_field(3, group="attr") - ce_bytes: bytes = betterproto.bytes_field(4, group="attr") - ce_uri: str = betterproto.string_field(5, group="attr") - ce_uri_ref: str = betterproto.string_field(6, group="attr") - ce_timestamp: datetime = betterproto.message_field(7, group="attr") + ce_boolean: Optional[bool] = betterproto.bool_field(1, optional=True, group="attr") + ce_integer: Optional[int] = betterproto.int32_field(2, optional=True, group="attr") + ce_string: Optional[str] = betterproto.string_field(3, optional=True, group="attr") + ce_bytes: Optional[bytes] = betterproto.bytes_field(4, optional=True, group="attr") + ce_uri: Optional[str] = betterproto.string_field(5, optional=True, group="attr") + ce_uri_ref: Optional[str] = betterproto.string_field(6, optional=True, group="attr") + ce_timestamp: Optional[datetime] = betterproto.message_field( + 7, optional=True, group="attr" + ) + + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) @dataclass(eq=False, repr=False) class CloudEventBatch(betterproto.Message): events: List["CloudEvent"] = betterproto.message_field(1) + + +rebuild_dataclass(CloudEvent) # type: ignore +rebuild_dataclass(CloudEventCloudEventAttributeValue) # type: ignore +rebuild_dataclass(CloudEventBatch) # type: ignore diff --git a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/rekor/v1/__init__.py b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/rekor/v1/__init__.py index e8670943..376e5857 100644 --- a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/rekor/v1/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/rekor/v1/__init__.py @@ -3,10 +3,18 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + from typing import List import betterproto +from pydantic.dataclasses import rebuild_dataclass from ...common import v1 as __common_v1__ @@ -164,3 +172,7 @@ class TransparencyLogEntry(betterproto.Message): If not set, clients are responsible for constructing an equivalent payload from other sources to verify the signature. """ + + +rebuild_dataclass(InclusionProof) # type: ignore +rebuild_dataclass(TransparencyLogEntry) # type: ignore diff --git a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/trustroot/v1/__init__.py b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/trustroot/v1/__init__.py index 4337b19e..f089c7a9 100644 --- a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/trustroot/v1/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/trustroot/v1/__init__.py @@ -3,10 +3,18 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + from typing import List import betterproto +from pydantic.dataclasses import rebuild_dataclass from ...common import v1 as __common_v1__ @@ -237,3 +245,9 @@ class ClientTrustConfig(betterproto.Message): signing_config: "SigningConfig" = betterproto.message_field(3) """Configuration for signing clients, which MUST be present.""" + + +rebuild_dataclass(TransparencyLogInstance) # type: ignore +rebuild_dataclass(CertificateAuthority) # type: ignore +rebuild_dataclass(TrustedRoot) # type: ignore +rebuild_dataclass(ClientTrustConfig) # type: ignore diff --git a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/verification/v1/__init__.py b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/verification/v1/__init__.py index 296c7f04..392d14c1 100644 --- a/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/verification/v1/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/dev/sigstore/verification/v1/__init__.py @@ -3,13 +3,22 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + from typing import ( List, Optional, ) import betterproto +from pydantic import model_validator +from pydantic.dataclasses import rebuild_dataclass from ...bundle import v1 as __bundle_v1__ from ...common import v1 as __common_v1__ @@ -49,10 +58,12 @@ class ArtifactVerificationOptions(betterproto.Message): used during verification of a single artifact. """ - certificate_identities: "CertificateIdentities" = betterproto.message_field( - 1, group="signers" + certificate_identities: Optional["CertificateIdentities"] = ( + betterproto.message_field(1, optional=True, group="signers") + ) + public_keys: Optional["PublicKeyIdentities"] = betterproto.message_field( + 2, optional=True, group="signers" ) - public_keys: "PublicKeyIdentities" = betterproto.message_field(2, group="signers") """ To simplify verification implementation, the logic for bundle verification should be implemented as a @@ -116,6 +127,10 @@ class ArtifactVerificationOptions(betterproto.Message): Disable: false """ + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) + @dataclass(eq=False, repr=False) class ArtifactVerificationOptionsTlogOptions(betterproto.Message): @@ -176,12 +191,18 @@ class ArtifactVerificationOptionsObserverTimestampOptions(betterproto.Message): @dataclass(eq=False, repr=False) class Artifact(betterproto.Message): - artifact_uri: str = betterproto.string_field(1, group="data") + artifact_uri: Optional[str] = betterproto.string_field( + 1, optional=True, group="data" + ) """Location of the artifact""" - artifact: bytes = betterproto.bytes_field(2, group="data") + artifact: Optional[bytes] = betterproto.bytes_field(2, optional=True, group="data") """The raw bytes of the artifact""" + @model_validator(mode="after") + def check_oneof(cls, values): + return cls._validate_field_groups(values) + @dataclass(eq=False, repr=False) class Input(betterproto.Message): @@ -211,3 +232,10 @@ class Input(betterproto.Message): If the bundle contains a message signature, the artifact must be provided. """ + + +rebuild_dataclass(CertificateIdentity) # type: ignore +rebuild_dataclass(CertificateIdentities) # type: ignore +rebuild_dataclass(PublicKeyIdentities) # type: ignore +rebuild_dataclass(ArtifactVerificationOptions) # type: ignore +rebuild_dataclass(Input) # type: ignore diff --git a/gen/pb-python/sigstore_protobuf_specs/google/api/__init__.py b/gen/pb-python/sigstore_protobuf_specs/google/api/__init__.py index b97fbf18..5929742a 100644 --- a/gen/pb-python/sigstore_protobuf_specs/google/api/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/google/api/__init__.py @@ -3,9 +3,16 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass import betterproto +from pydantic.dataclasses import rebuild_dataclass class FieldBehavior(betterproto.Enum): @@ -64,3 +71,9 @@ class FieldBehavior(betterproto.Enum): in any arbitrary order, rather than the order the user originally provided. Additionally, the list's order may or may not be stable. """ + + @classmethod + def __get_pydantic_core_schema__(cls, _source_type, _handler): + from pydantic_core import core_schema + + return core_schema.int_schema(ge=0) diff --git a/gen/pb-python/sigstore_protobuf_specs/io/intoto/__init__.py b/gen/pb-python/sigstore_protobuf_specs/io/intoto/__init__.py index eba60a6b..b3c48224 100644 --- a/gen/pb-python/sigstore_protobuf_specs/io/intoto/__init__.py +++ b/gen/pb-python/sigstore_protobuf_specs/io/intoto/__init__.py @@ -3,10 +3,18 @@ # plugin: python-betterproto # This file has been @generated -from dataclasses import dataclass +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from pydantic.dataclasses import dataclass + from typing import List import betterproto +from pydantic.dataclasses import rebuild_dataclass @dataclass(eq=False, repr=False) @@ -52,3 +60,6 @@ class Signature(betterproto.Message): *Unauthenticated* hint identifying which public key was used. OPTIONAL. """ + + +rebuild_dataclass(Envelope) # type: ignore