Example #1
0
class EventsRealmVlobsUpdatedRepSchema(BaseRepSchema):
    status = fields.CheckedConstant("ok", required=True)
    event = fields.CheckedConstant("realm.vlobs_updated", required=True)
    realm_id = fields.UUID(required=True)
    checkpoint = fields.Integer(required=True)
    src_id = fields.UUID(required=True)
    src_version = fields.Integer(required=True)
Example #2
0
class EventsBeaconUpdatedRepSchema(BaseRepSchema):
    status = fields.CheckedConstant("ok", required=True)
    event = fields.CheckedConstant("beacon.updated", required=True)
    beacon_id = fields.UUID(required=True)
    index = fields.Integer(required=True)
    src_id = fields.UUID(required=True)
    src_version = fields.Integer(required=True)
Example #3
0
class HandshakeAnonymousAnswerSchema(BaseSchema):
    handshake = fields.CheckedConstant("answer", required=True)
    type = fields.CheckedConstant("anonymous", required=True)
    client_api_version = ApiVersionField(required=True)
    organization_id = OrganizationIDField(required=True)
    # Cannot provide rvk during organization bootstrap
    rvk = fields.VerifyKey(missing=None)
Example #4
0
class HandshakeAuthenticatedAnswerSchema(BaseSchema):
    handshake = fields.CheckedConstant("answer", required=True)
    type = fields.CheckedConstant("authenticated", required=True)
    client_api_version = ApiVersionField(required=True)
    organization_id = OrganizationIDField(required=True)
    device_id = DeviceIDField(required=True)
    rvk = fields.VerifyKey(required=True)
    answer = fields.Bytes(required=True)
Example #5
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        # Override author field to allow for None value if signed by the root key
        author = DeviceIDField(required=True, allow_none=True)

        type = fields.CheckedConstant("user_certificate", required=True)
        user_id = UserIDField(required=True)
        # Human handle can be none in case of redacted certificate
        human_handle = HumanHandleField(allow_none=True, missing=None)
        public_key = fields.PublicKey(required=True)
        # `profile` replaces `is_admin` field (which is still required for backward
        # compatibility), hence `None` is not allowed
        is_admin = fields.Boolean(required=True)
        profile = UserProfileField(allow_none=False)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "UserCertificateContent":
            data.pop("type")

            # Handle legacy `is_admin` field
            default_profile = UserProfile.ADMIN if data.pop("is_admin") else UserProfile.STANDARD
            try:
                profile = data["profile"]
            except KeyError:
                data["profile"] = default_profile
            else:
                if default_profile == UserProfile.ADMIN and profile != UserProfile.ADMIN:
                    raise ValidationError(
                        "Fields `profile` and `is_admin` have incompatible values"
                    )

            return UserCertificateContent(**data)
Example #6
0
class HandshakeInvitedAnswerSchema(BaseSchema):
    handshake = fields.CheckedConstant("answer", required=True)
    type = fields.EnumCheckedConstant(HandshakeType.INVITED, required=True)
    client_api_version = ApiVersionField(required=True)
    organization_id = OrganizationIDField(required=True)
    invitation_type = InvitationTypeField(required=True)
    token = fields.UUID(required=True)
class UserClaimSchema(UnknownCheckedSchema):
    type = fields.CheckedConstant("user_claim", required=True)
    token = fields.String(required=True)
    # Note claiming user also imply creating a first device
    device_id = fields.DeviceID(required=True)
    public_key = fields.PublicKey(required=True)
    verify_key = fields.VerifyKey(required=True)
Example #8
0
class TimestampOutOfBallparkRepSchema(BaseRepSchema):
    """This schema has been added to API version 2.4 (Parsec v2.7.0).

    However, it re-uses the `bad_timestamp` status that was used for similar errors in previous backend versions.
    For compatibility purposes, this schema should be compatible with `ErrorRepSchema` in the sense that:
    - an `ErrorRepSchema` with status `bad_timestamp` should be able to deserialize into a `TimestampOutOfBallparkRepSchema`
    - a `TimestampOutOfBallparkRepSchema` should be able to deserialize into an `ErrorRepSchema` with status `bad_timestamp

    New clients who wishes to use those fields should check for their existence first.
    TODO: This backward compatibility should be removed once Parsec < 2.4 support is dropped
    """

    # `bad_timestamp` is kept for backward compatibility,
    # even though `timestamp_out_of_ballpark` would be more explicit
    status: fields.CheckedConstant = fields.CheckedConstant("bad_timestamp", required=True)
    ballpark_client_early_offset = fields.Float(required=False, allow_none=False)
    ballpark_client_late_offset = fields.Float(required=False, allow_none=False)
    client_timestamp = fields.DateTime(required=False, allow_none=False)
    backend_timestamp = fields.DateTime(required=False, allow_none=False)

    @post_load
    def make_obj(self, data: Dict[str, Any]) -> Dict[str, Any]:  # type: ignore[misc]
        # Cannot use `missing=None` with `allow_none=False`
        data.setdefault("ballpark_client_early_offset", None)
        data.setdefault("ballpark_client_late_offset", None)
        data.setdefault("client_timestamp", None)
        data.setdefault("backend_timestamp", None)
        return data
Example #9
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("sharing.revoked", required=True)
        id = EntryIDField(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return SharingRevokedMessageContent(**data)
Example #10
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("ping", required=True)
        ping = fields.String(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return PingMessageContent(**data)
Example #11
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("revoked_user_certificate", required=True)
        user_id = UserIDField(required=True)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "RevokedUserCertificateContent":
            data.pop("type")
            return RevokedUserCertificateContent(**data)
Example #12
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("device_certificate", required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return DeviceCertificateContent(**data)
Example #13
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("device_claim_answer", required=True)
        private_key = fields.PrivateKey(required=True)
        user_manifest_id = EntryIDField(required=True)
        user_manifest_key = fields.SecretKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return DeviceClaimAnswerContent(**data)
Example #14
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("user_certificate", required=True)
        user_id = UserIDField(required=True)
        public_key = fields.PublicKey(required=True)
        is_admin = fields.Boolean(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return UserCertificateContent(**data)
Example #15
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("invite_device_data", required=True)
        # Claimer ask for device_label, but greeter has final word on this
        requested_device_label = fields.String(allow_none=True, missing=None)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return InviteDeviceData(**data)
Example #16
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("realm_role_certificate", required=True)
        realm_id = fields.UUID(required=True)
        user_id = UserIDField(required=True)
        role = RealmRoleField(required=True, allow_none=True)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "RealmRoleCertificateContent":
            data.pop("type")
            return RealmRoleCertificateContent(**data)
Example #17
0
    class SCHEMA_CLS(SharingGrantedMessageContent.SCHEMA_CLS):
        type = fields.CheckedConstant("sharing.reencrypted", required=True)
        # This message is similar to `sharing.granted`. Hence both can be processed
        # interchangeably, which avoid possible concurrency issues when a sharing
        # occurs right before a reencryption.

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return SharingReencryptedMessageContent(**data)
Example #18
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("device_certificate", required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)
        # Device label can be none in case of redacted certificate
        device_label = fields.String(allow_none=True, missing=None)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return DeviceCertificateContent(**data)
Example #19
0
class DeviceFileSchema(BaseSchema):
    type = fields.CheckedConstant("password", required=True)
    salt = fields.Bytes(required=True)
    ciphertext = fields.Bytes(required=True)

    # Since human_handle/device_label has been introduced, device_id is
    # redacted (i.e. user_id and device_name are 2 random uuids), hence
    # those fields have been added to the device file so the login page in
    # the GUI can use them to provide useful information.
    human_handle = HumanHandleField(allow_none=True, missing=None)
    device_label = fields.String(allow_none=True, missing=None)
Example #20
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("device_claim", required=True)
        token = fields.String(required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)
        answer_public_key = fields.PublicKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return DeviceClaimContent(**data)
Example #21
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("user_claim", required=True)
        token = fields.String(required=True)
        # Note claiming user also imply creating a first device
        device_id = DeviceIDField(required=True)
        public_key = fields.PublicKey(required=True)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "APIV1_UserClaimContent":  # type: ignore[misc]
            data.pop("type")
            return APIV1_UserClaimContent(**data)
Example #22
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("invite_user_confirmation", required=True)
        device_id = DeviceIDField(required=True)
        device_label = fields.String(allow_none=True, missing=None)
        human_handle = HumanHandleField(allow_none=True, missing=None)
        profile = UserProfileField(required=True)
        root_verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return InviteUserConfirmation(**data)
Example #23
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("x509_certificate", required=True)
        issuer = fields.Dict(required=True)
        subject = fields.Dict(required=True)
        der_x509_certificate = fields.Bytes(required=True)
        certificate_sha1 = fields.Bytes(required=True)
        certificate_id = fields.String(required=True, allow_none=True)

        @post_load
        def make_obj(self, data):
            data.pop("type", None)
            return X509Certificate(**data)
Example #24
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("device_claim_answer", required=True)
        private_key = fields.PrivateKey(required=True)
        user_manifest_id = EntryIDField(required=True)
        user_manifest_key = fields.SecretKey(required=True)

        @post_load
        def make_obj(  # type: ignore[misc]
            self, data: Dict[str, Any]
        ) -> "APIV1_DeviceClaimAnswerContent":
            data.pop("type")
            return APIV1_DeviceClaimAnswerContent(**data)
Example #25
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("device_claim", required=True)
        token = fields.String(required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)
        answer_public_key = fields.PublicKey(required=True)

        @post_load
        def make_obj(  # type: ignore[misc]
            self, data: Dict[str, Any]
        ) -> "APIV1_DeviceClaimContent":
            data.pop("type")
            return APIV1_DeviceClaimContent(**data)
Example #26
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("invite_user_data", required=True)
        # Claimer ask for device_label/human_handle, but greeter has final word on this
        requested_device_label = fields.String(allow_none=True, missing=None)
        requested_human_handle = HumanHandleField(allow_none=True, missing=None)
        # Note claiming user also imply creating a first device
        public_key = fields.PublicKey(required=True)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return InviteUserData(**data)
Example #27
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        # Override author field to allow for None value if signed by the root key
        author = DeviceIDField(required=True, allow_none=True)

        type = fields.CheckedConstant("device_certificate", required=True)
        device_id = DeviceIDField(required=True)
        # Device label can be none in case of redacted certificate
        device_label = fields.String(allow_none=True, missing=None)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "DeviceCertificateContent":
            data.pop("type")
            return DeviceCertificateContent(**data)
Example #28
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("local_pending_enrollment", required=True)
        x509_certificate = fields.Nested(X509Certificate.SCHEMA_CLS, required=True)
        addr = BackendPkiEnrollmentAddrField(required=True)
        submitted_on = fields.DateTime(required=True)
        enrollment_id = fields.UUID(required=True)
        submit_payload = fields.Nested(PkiEnrollmentSubmitPayload.SCHEMA_CLS, required=True)
        encrypted_key = fields.Bytes(required=True)
        ciphertext = fields.Bytes(required=True)  # An encrypted PendingDeviceKeys

        @post_load
        def make_obj(self, data):
            data.pop("type", None)
            return LocalPendingEnrollment(**data)
Example #29
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("pki_enrollment_answer_payload",
                                      required=True)
        device_id = DeviceIDField(required=True)
        device_label = DeviceLabelField(allow_none=True, required=True)
        human_handle = HumanHandleField(allow_none=True, required=True)
        profile = UserProfileField(required=True)
        root_verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data: Dict[str,
                                      Any]) -> "PkiEnrollmentAcceptPayload":
            data.pop("type")
            return PkiEnrollmentAcceptPayload(**data)
Example #30
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("pki_enrollment_submit_payload",
                                      required=True)
        verify_key = fields.VerifyKey(required=True)
        public_key = fields.PublicKey(required=True)
        requested_device_label = DeviceLabelField(required=True)
        # No requested human handle given the accepter should use instead the
        # information from the submitter's X509 certificate

        @post_load
        def make_obj(self, data: Dict[str,
                                      Any]) -> "PkiEnrollmentSubmitPayload":
            data.pop("type")
            return PkiEnrollmentSubmitPayload(**data)