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)
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)