From 4f02a4b56e75c36893b93ae0b7654c6f9f70c172 Mon Sep 17 00:00:00 2001 From: Vincent Michel Date: Fri, 20 Jan 2023 12:18:02 +0100 Subject: [PATCH] Do not use Vec as argument type in the binding See https://github.com/PyO3/pyo3/issues/2888 --- newsfragments/3925.misc.rst | 1 + src/addrs.rs | 11 ++++-- src/binding_utils.rs | 72 +++++++++++++++++++++++++++++++++++- src/data/organization.rs | 9 +++-- src/data/pki.rs | 16 +++++--- src/protocol/block.rs | 7 +++- src/protocol/invite.rs | 25 +++++++++---- src/protocol/message.rs | 10 ++++- src/protocol/mod.rs | 4 +- src/protocol/organization.rs | 26 +++++++++---- src/protocol/pki.rs | 57 ++++++++++++++++++++-------- src/protocol/realm.rs | 17 ++++++--- src/protocol/user.rs | 42 +++++++++++++++------ src/protocol/vlob.rs | 21 +++++++---- src/trustchain.rs | 16 ++++---- 15 files changed, 251 insertions(+), 83 deletions(-) create mode 100644 newsfragments/3925.misc.rst diff --git a/newsfragments/3925.misc.rst b/newsfragments/3925.misc.rst new file mode 100644 index 00000000000..3f56d2fc38d --- /dev/null +++ b/newsfragments/3925.misc.rst @@ -0,0 +1 @@ +Fix an underlying issue that caused an overall performance degradation diff --git a/src/addrs.rs b/src/addrs.rs index a917b1a0b56..ef304f1dd33 100644 --- a/src/addrs.rs +++ b/src/addrs.rs @@ -10,6 +10,7 @@ use std::str::FromStr; use crate::{ api_crypto::VerifyKey, + binding_utils::BytesWrapper, enumerate::InvitationType, ids::{EntryID, InvitationToken, OrganizationID}, }; @@ -447,10 +448,11 @@ impl BackendOrganizationFileLinkAddr { fn new( organization_id: OrganizationID, workspace_id: EntryID, - encrypted_path: Vec, - encrypted_timestamp: Option>, + encrypted_path: BytesWrapper, + encrypted_timestamp: Option, py_kwargs: Option<&PyDict>, ) -> PyResult { + crate::binding_utils::unwrap_bytes!(encrypted_path, encrypted_timestamp); let addr = match py_kwargs { Some(dict) => BackendAddr::new( match dict.get_item("hostname") { @@ -568,9 +570,10 @@ impl BackendOrganizationFileLinkAddr { _cls: &PyType, organization_addr: BackendOrganizationAddr, workspace_id: EntryID, - encrypted_path: Vec, - encrypted_timestamp: Option>, + encrypted_path: BytesWrapper, + encrypted_timestamp: Option, ) -> PyResult { + crate::binding_utils::unwrap_bytes!(encrypted_path, encrypted_timestamp); Ok(Self( libparsec::types::BackendOrganizationFileLinkAddr::new( organization_addr.get_backend_addr().0, diff --git a/src/binding_utils.rs b/src/binding_utils.rs index e52278ea69f..98bd722651f 100644 --- a/src/binding_utils.rs +++ b/src/binding_utils.rs @@ -1,14 +1,80 @@ // Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 (eventually AGPL-3.0) 2016-present Scille SAS use pyo3::{ - exceptions::PyNotImplementedError, pyclass::CompareOp, types::PyFrozenSet, FromPyObject, PyAny, - PyResult, + exceptions::PyNotImplementedError, pyclass::CompareOp, types::PyByteArray, types::PyBytes, + types::PyFrozenSet, FromPyObject, PyAny, PyResult, }; use std::{ collections::{hash_map::DefaultHasher, HashSet}, hash::{Hash, Hasher}, }; +#[derive(FromPyObject)] +pub enum BytesWrapper<'py> { + Bytes(&'py PyBytes), + ByteArray(&'py PyByteArray), +} + +impl From> for Vec { + fn from(wrapper: BytesWrapper) -> Self { + match wrapper { + BytesWrapper::Bytes(bytes) => bytes.as_bytes().to_vec(), + BytesWrapper::ByteArray(byte_array) => byte_array.to_vec(), + } + } +} + +pub trait UnwrapBytesWrapper { + type ResultType; + fn unwrap_bytes(self) -> Self::ResultType; +} + +impl UnwrapBytesWrapper for BytesWrapper<'_> { + type ResultType = Vec; + fn unwrap_bytes(self) -> Self::ResultType { + self.into() + } +} + +impl UnwrapBytesWrapper for Option +where + T: UnwrapBytesWrapper, +{ + type ResultType = Option; + fn unwrap_bytes(self) -> Self::ResultType { + self.map(|x| x.unwrap_bytes()) + } +} + +impl UnwrapBytesWrapper for Vec +where + T: UnwrapBytesWrapper, +{ + type ResultType = Vec; + fn unwrap_bytes(self) -> Self::ResultType { + self.into_iter().map(|x| x.unwrap_bytes()).collect() + } +} + +macro_rules! _unwrap_bytes { + ($name:ident) => { + let $name = $name.unwrap_bytes(); + }; + ($x:ident, $($y:ident),+) => { + crate::binding_utils::_unwrap_bytes!($x); + crate::binding_utils::_unwrap_bytes!($($y),+); + + } +} + +macro_rules! unwrap_bytes { + ($($name:ident),+) => { + use crate::binding_utils::UnwrapBytesWrapper; + crate::binding_utils::_unwrap_bytes!($($name),+); + + } +} + pub fn comp_eq(op: CompareOp, h1: T, h2: T) -> PyResult { Ok(match op { CompareOp::Eq => h1 == h2, @@ -233,9 +299,11 @@ macro_rules! impl_enum_field { }; } +pub(crate) use _unwrap_bytes; pub(crate) use create_exception; pub(crate) use gen_proto; pub(crate) use impl_enum_field; pub(crate) use parse_kwargs; pub(crate) use parse_kwargs_optional; pub(crate) use py_object; +pub(crate) use unwrap_bytes; diff --git a/src/data/organization.rs b/src/data/organization.rs index 7a61b90195a..3adb02d923b 100644 --- a/src/data/organization.rs +++ b/src/data/organization.rs @@ -3,7 +3,9 @@ use pyo3::{ types::{PyBytes, PyTuple}, }; -use crate::{data::UsersPerProfileDetailItem, protocol::ActiveUsersLimit}; +use crate::{ + binding_utils::BytesWrapper, data::UsersPerProfileDetailItem, protocol::ActiveUsersLimit, +}; #[pyclass] pub(crate) struct OrganizationStats(pub libparsec::types::OrganizationStats); @@ -81,9 +83,10 @@ impl OrganizationConfig { fn new( user_profile_outsider_allowed: bool, active_users_limit: ActiveUsersLimit, - sequester_authority: Option>, - sequester_services: Option>>, + sequester_authority: Option, + sequester_services: Option>, ) -> Self { + crate::binding_utils::unwrap_bytes!(sequester_authority, sequester_services); Self(libparsec::types::OrganizationConfig { user_profile_outsider_allowed, active_users_limit: active_users_limit.0, diff --git a/src/data/pki.rs b/src/data/pki.rs index 0f75114da59..d86f5f36d65 100644 --- a/src/data/pki.rs +++ b/src/data/pki.rs @@ -8,6 +8,7 @@ use std::{collections::HashMap, path::Path}; use crate::{ addrs::BackendPkiEnrollmentAddr, api_crypto::{PublicKey, VerifyKey}, + binding_utils::BytesWrapper, data::{DataResult, PkiEnrollmentLocalPendingResult}, enumerate::UserProfile, ids::{DeviceID, DeviceLabel, EnrollmentID, HumanHandle}, @@ -135,10 +136,11 @@ impl X509Certificate { fn new( issuer: HashMap, subject: HashMap, - der_x509_certificate: Vec, - certificate_sha1: Vec, + der_x509_certificate: BytesWrapper, + certificate_sha1: BytesWrapper, certificate_id: Option, ) -> Self { + crate::binding_utils::unwrap_bytes!(der_x509_certificate, certificate_sha1); Self(libparsec::types::X509Certificate { issuer, subject, @@ -154,10 +156,11 @@ impl X509Certificate { py_kwargs, [issuer: HashMap, "issuer"], [subject: HashMap, "subject"], - [der_x509_certificate: Vec, "der_x509_certificate"], - [certificate_sha1: Vec, "certificate_sha1"], + [der_x509_certificate: BytesWrapper, "der_x509_certificate"], + [certificate_sha1: BytesWrapper, "certificate_sha1"], [certificate_id: Option, "certificate_id"], ); + crate::binding_utils::unwrap_bytes!(der_x509_certificate, certificate_sha1); let mut r = self.0.clone(); @@ -241,9 +244,10 @@ impl LocalPendingEnrollment { submitted_on: DateTime, enrollment_id: EnrollmentID, submit_payload: PkiEnrollmentSubmitPayload, - encrypted_key: Vec, - ciphertext: Vec, + encrypted_key: BytesWrapper, + ciphertext: BytesWrapper, ) -> Self { + crate::binding_utils::unwrap_bytes!(encrypted_key, ciphertext); Self(libparsec::types::LocalPendingEnrollment { x509_certificate: x509_certificate.0, addr: addr.0, diff --git a/src/protocol/block.rs b/src/protocol/block.rs index a7d840c73c7..f24b52e2fc5 100644 --- a/src/protocol/block.rs +++ b/src/protocol/block.rs @@ -8,6 +8,7 @@ use libparsec::protocol::{ }; use crate::{ + binding_utils::BytesWrapper, ids::{BlockID, RealmID}, protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, @@ -25,7 +26,8 @@ crate::binding_utils::gen_proto!(BlockCreateReq, __richcmp__, eq); #[pymethods] impl BlockCreateReq { #[new] - fn new(block_id: BlockID, realm_id: RealmID, block: Vec) -> PyResult { + fn new(block_id: BlockID, realm_id: RealmID, block: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(block); Ok(Self(block_create::Req { block_id: block_id.0, realm_id: realm_id.0, @@ -130,7 +132,8 @@ pub(crate) struct BlockReadRepOk; #[pymethods] impl BlockReadRepOk { #[new] - fn new(block: Vec) -> PyResult<(Self, BlockReadRep)> { + fn new(block: BytesWrapper) -> PyResult<(Self, BlockReadRep)> { + crate::binding_utils::unwrap_bytes!(block); Ok((Self, BlockReadRep(block_read::Rep::Ok { block }))) } diff --git a/src/protocol/invite.rs b/src/protocol/invite.rs index af6e26d5dc0..d86309d6840 100644 --- a/src/protocol/invite.rs +++ b/src/protocol/invite.rs @@ -24,6 +24,7 @@ use libparsec::protocol::{ use crate::{ api_crypto, api_crypto::{HashDigest, PublicKey}, + binding_utils::BytesWrapper, enumerate::{ InvitationDeletedReason, InvitationEmailSentStatus, InvitationStatus, InvitationType, }, @@ -677,7 +678,8 @@ pub(crate) struct Invite2aClaimerSendHashedNonceRepOk; #[pymethods] impl Invite2aClaimerSendHashedNonceRepOk { #[new] - fn new(greeter_nonce: Vec) -> PyResult<(Self, Invite2aClaimerSendHashedNonceRep)> { + fn new(greeter_nonce: BytesWrapper) -> PyResult<(Self, Invite2aClaimerSendHashedNonceRep)> { + crate::binding_utils::unwrap_bytes!(greeter_nonce); Ok(( Self, Invite2aClaimerSendHashedNonceRep(invite_2a_claimer_send_hashed_nonce::Rep::Ok { @@ -775,7 +777,8 @@ crate::binding_utils::gen_proto!(Invite2bClaimerSendNonceReq, __richcmp__, eq); #[pymethods] impl Invite2bClaimerSendNonceReq { #[new] - fn new(claimer_nonce: Vec) -> PyResult { + fn new(claimer_nonce: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(claimer_nonce); Ok(Self(invite_2b_claimer_send_nonce::Req { claimer_nonce })) } @@ -829,7 +832,8 @@ crate::binding_utils::gen_proto!(Invite2bGreeterSendNonceReq, __richcmp__, eq); #[pymethods] impl Invite2bGreeterSendNonceReq { #[new] - fn new(token: InvitationToken, greeter_nonce: Vec) -> PyResult { + fn new(token: InvitationToken, greeter_nonce: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(greeter_nonce); let token = token.0; Ok(Self(invite_2b_greeter_send_nonce::Req { token, @@ -874,7 +878,8 @@ pub(crate) struct Invite2bGreeterSendNonceRepOk; #[pymethods] impl Invite2bGreeterSendNonceRepOk { #[new] - fn new(claimer_nonce: Vec) -> PyResult<(Self, Invite2bGreeterSendNonceRep)> { + fn new(claimer_nonce: BytesWrapper) -> PyResult<(Self, Invite2bGreeterSendNonceRep)> { + crate::binding_utils::unwrap_bytes!(claimer_nonce); Ok(( Self, Invite2bGreeterSendNonceRep(invite_2b_greeter_send_nonce::Rep::Ok { claimer_nonce }), @@ -1110,7 +1115,8 @@ crate::binding_utils::gen_proto!(Invite4ClaimerCommunicateReq, __richcmp__, eq); #[pymethods] impl Invite4ClaimerCommunicateReq { #[new] - fn new(payload: Vec) -> PyResult { + fn new(payload: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(payload); Ok(Self(invite_4_claimer_communicate::Req { payload })) } @@ -1146,7 +1152,8 @@ pub(crate) struct Invite4ClaimerCommunicateRepOk; #[pymethods] impl Invite4ClaimerCommunicateRepOk { #[new] - fn new(payload: Vec) -> PyResult<(Self, Invite4ClaimerCommunicateRep)> { + fn new(payload: BytesWrapper) -> PyResult<(Self, Invite4ClaimerCommunicateRep)> { + crate::binding_utils::unwrap_bytes!(payload); Ok(( Self, Invite4ClaimerCommunicateRep(invite_4_claimer_communicate::Rep::Ok { payload }), @@ -1174,7 +1181,8 @@ crate::binding_utils::gen_proto!(Invite4GreeterCommunicateReq, __richcmp__, eq); #[pymethods] impl Invite4GreeterCommunicateReq { #[new] - fn new(token: InvitationToken, payload: Vec) -> PyResult { + fn new(token: InvitationToken, payload: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(payload); let token = token.0; Ok(Self(invite_4_greeter_communicate::Req { token, payload })) } @@ -1216,7 +1224,8 @@ pub(crate) struct Invite4GreeterCommunicateRepOk; #[pymethods] impl Invite4GreeterCommunicateRepOk { #[new] - fn new(payload: Vec) -> PyResult<(Self, Invite4GreeterCommunicateRep)> { + fn new(payload: BytesWrapper) -> PyResult<(Self, Invite4GreeterCommunicateRep)> { + crate::binding_utils::unwrap_bytes!(payload); Ok(( Self, Invite4GreeterCommunicateRep(invite_4_greeter_communicate::Rep::Ok { payload }), diff --git a/src/protocol/message.rs b/src/protocol/message.rs index 2eb95744895..c951b5a6286 100644 --- a/src/protocol/message.rs +++ b/src/protocol/message.rs @@ -8,12 +8,12 @@ use pyo3::{ use libparsec::protocol::{authenticated_cmds::v2::message_get, Request}; -use crate::ids::DeviceID; use crate::protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, gen_rep, }; use crate::time::DateTime; +use crate::{binding_utils::BytesWrapper, ids::DeviceID}; #[pyclass] #[derive(Clone)] @@ -25,7 +25,13 @@ crate::binding_utils::gen_proto!(Message, __richcmp__, eq); #[pymethods] impl Message { #[new] - fn new(count: u64, sender: DeviceID, timestamp: DateTime, body: Vec) -> PyResult { + fn new( + count: u64, + sender: DeviceID, + timestamp: DateTime, + body: BytesWrapper, + ) -> PyResult { + crate::binding_utils::unwrap_bytes!(body); let sender = sender.0; let timestamp = timestamp.0; Ok(Self(message_get::Message { diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 2e8f7aadcb4..af77875b4e5 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -148,9 +148,11 @@ macro_rules! gen_rep { } #[classmethod] - fn load<'py>(_cls: &::pyo3::types::PyType, buf: Vec, py: Python<'py>) -> PyResult { + fn load<'py>(_cls: &::pyo3::types::PyType, buf: crate::binding_utils::BytesWrapper, py: Python<'py>) -> PyResult { use pyo3::{pyclass_init::PyObjectInit, PyTypeInfo}; + crate::binding_utils::unwrap_bytes!(buf); + let rep = $mod::Rep::load(&buf) .map_err(|e| ProtocolErrorFields(libparsec::protocol::ProtocolError::DecodingError { exc: e.to_string() })) .map_err(|e| ProtocolError::new_err(e))?; diff --git a/src/protocol/organization.rs b/src/protocol/organization.rs index 5ebdadccd10..61ac311af1a 100644 --- a/src/protocol/organization.rs +++ b/src/protocol/organization.rs @@ -18,6 +18,7 @@ use libparsec::{ use crate::{ api_crypto::VerifyKey, binding_utils::gen_proto, + binding_utils::BytesWrapper, data::UsersPerProfileDetailItem, protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, @@ -240,9 +241,13 @@ impl OrganizationConfigRepOk { fn new( user_profile_outsider_allowed: bool, active_users_limit: ActiveUsersLimit, - sequester_authority_certificate: Option>, - sequester_services_certificates: Option>>, + sequester_authority_certificate: Option, + sequester_services_certificates: Option>, ) -> PyResult<(Self, OrganizationConfigRep)> { + crate::binding_utils::unwrap_bytes!( + sequester_authority_certificate, + sequester_services_certificates + ); Ok(( Self, OrganizationConfigRep(organization_config::Rep::Ok { @@ -330,19 +335,26 @@ impl OrganizationBootstrapReq { fn new( bootstrap_token: String, root_verify_key: VerifyKey, - user_certificate: Vec, - device_certificate: Vec, - redacted_user_certificate: Vec, - redacted_device_certificate: Vec, + user_certificate: BytesWrapper, + device_certificate: BytesWrapper, + redacted_user_certificate: BytesWrapper, + redacted_device_certificate: BytesWrapper, py_kwargs: Option<&PyDict>, ) -> PyResult { crate::binding_utils::parse_kwargs_optional!( py_kwargs, [ - sequester_authority_certificate: Option>, + sequester_authority_certificate: Option, "sequester_authority_certificate" ] ); + crate::binding_utils::unwrap_bytes!( + user_certificate, + device_certificate, + redacted_user_certificate, + redacted_device_certificate, + sequester_authority_certificate + ); let sequester_authority_certificate = match sequester_authority_certificate { None => Maybe::Absent, diff --git a/src/protocol/pki.rs b/src/protocol/pki.rs index c00ed503950..3ea9a79ad7b 100644 --- a/src/protocol/pki.rs +++ b/src/protocol/pki.rs @@ -14,6 +14,7 @@ use pyo3::{ }; use crate::{ + binding_utils::BytesWrapper, ids::EnrollmentID, protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, @@ -33,15 +34,24 @@ impl PkiEnrollmentAcceptReq { #[new] #[allow(clippy::too_many_arguments)] fn new( - accept_payload: Vec, - accept_payload_signature: Vec, - accepter_der_x509_certificate: Vec, + accept_payload: BytesWrapper, + accept_payload_signature: BytesWrapper, + accepter_der_x509_certificate: BytesWrapper, enrollment_id: &EnrollmentID, - device_certificate: Vec, - user_certificate: Vec, - redacted_device_certificate: Vec, - redacted_user_certificate: Vec, + device_certificate: BytesWrapper, + user_certificate: BytesWrapper, + redacted_device_certificate: BytesWrapper, + redacted_user_certificate: BytesWrapper, ) -> Self { + crate::binding_utils::unwrap_bytes!( + accept_payload, + accept_payload_signature, + accepter_der_x509_certificate, + device_certificate, + user_certificate, + redacted_device_certificate, + redacted_user_certificate + ); Self(pki_enrollment_accept::Req { accept_payload, accept_payload_signature, @@ -177,10 +187,15 @@ impl PkiEnrollmentInfoStatus { _cls: &PyType, submitted_on: DateTime, accepted_on: DateTime, - accepter_der_x509_certificate: Vec, - accept_payload_signature: Vec, - accept_payload: Vec, + accepter_der_x509_certificate: BytesWrapper, + accept_payload_signature: BytesWrapper, + accept_payload: BytesWrapper, ) -> Self { + crate::binding_utils::unwrap_bytes!( + accepter_der_x509_certificate, + accept_payload_signature, + accept_payload + ); Self(pki_enrollment_info::PkiEnrollmentInfoStatus::Accepted { submitted_on: submitted_on.0, accepted_on: accepted_on.0, @@ -258,11 +273,16 @@ impl PkiEnrollmentListItem { #[new] fn new( enrollment_id: EnrollmentID, - submit_payload: Vec, - submit_payload_signature: Vec, + submit_payload: BytesWrapper, + submit_payload_signature: BytesWrapper, submitted_on: DateTime, - submitter_der_x509_certificate: Vec, + submitter_der_x509_certificate: BytesWrapper, ) -> Self { + crate::binding_utils::unwrap_bytes!( + submit_payload, + submit_payload_signature, + submitter_der_x509_certificate + ); Self(pki_enrollment_list::PkiEnrollmentListItem { enrollment_id: enrollment_id.0, submit_payload, @@ -395,11 +415,16 @@ impl PkiEnrollmentSubmitReq { fn new( enrollment_id: EnrollmentID, force: bool, - submitter_der_x509_certificate: Vec, - submit_payload_signature: Vec, - submit_payload: Vec, + submitter_der_x509_certificate: BytesWrapper, + submit_payload_signature: BytesWrapper, + submit_payload: BytesWrapper, submitter_der_x509_certificate_email: Option, ) -> Self { + crate::binding_utils::unwrap_bytes!( + submitter_der_x509_certificate, + submit_payload_signature, + submit_payload + ); Self(pki_enrollment_submit::Req { enrollment_id: enrollment_id.0, force, diff --git a/src/protocol/realm.rs b/src/protocol/realm.rs index 9f6f7bced37..97638cc31ca 100644 --- a/src/protocol/realm.rs +++ b/src/protocol/realm.rs @@ -16,6 +16,7 @@ use libparsec::protocol::{ }; use crate::{ + binding_utils::BytesWrapper, ids::{DeviceID, RealmID, UserID}, protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, @@ -55,7 +56,8 @@ crate::binding_utils::gen_proto!(RealmCreateReq, __richcmp__, eq); #[pymethods] impl RealmCreateReq { #[new] - fn new(role_certificate: Vec) -> PyResult { + fn new(role_certificate: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(role_certificate); Ok(Self(realm_create::Req { role_certificate })) } @@ -340,7 +342,8 @@ pub(crate) struct RealmGetRoleCertificatesRepOk; #[pymethods] impl RealmGetRoleCertificatesRepOk { #[new] - fn new(certificates: Vec>) -> PyResult<(Self, RealmGetRoleCertificatesRep)> { + fn new(certificates: Vec) -> PyResult<(Self, RealmGetRoleCertificatesRep)> { + crate::binding_utils::unwrap_bytes!(certificates); Ok(( Self, RealmGetRoleCertificatesRep(realm_get_role_certificates::Rep::Ok { certificates }), @@ -368,7 +371,11 @@ crate::binding_utils::gen_proto!(RealmUpdateRolesReq, __richcmp__, eq); #[pymethods] impl RealmUpdateRolesReq { #[new] - fn new(role_certificate: Vec, recipient_message: Option>) -> PyResult { + fn new( + role_certificate: BytesWrapper, + recipient_message: Option, + ) -> PyResult { + crate::binding_utils::unwrap_bytes!(role_certificate, recipient_message); Ok(Self(realm_update_roles::Req { role_certificate, recipient_message, @@ -446,13 +453,13 @@ impl RealmStartReencryptionMaintenanceReq { realm_id: RealmID, encryption_revision: u64, timestamp: DateTime, - per_participant_message: HashMap>, + per_participant_message: HashMap, ) -> PyResult { let realm_id = realm_id.0; let timestamp = timestamp.0; let per_participant_message = per_participant_message .into_iter() - .map(|(k, v)| (k.0, v)) + .map(|(k, v)| (k.0, v.into())) .collect(); Ok(Self(realm_start_reencryption_maintenance::Req { realm_id, diff --git a/src/protocol/user.rs b/src/protocol/user.rs index f8075ac6172..de55f7e3cd8 100644 --- a/src/protocol/user.rs +++ b/src/protocol/user.rs @@ -14,6 +14,7 @@ use libparsec::protocol::{ }; use crate::{ + binding_utils::BytesWrapper, ids::{HumanHandle, UserID}, protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, @@ -34,10 +35,11 @@ crate::binding_utils::gen_proto!(Trustchain, __richcmp__, eq); impl Trustchain { #[new] fn new( - devices: Vec>, - users: Vec>, - revoked_users: Vec>, + devices: Vec, + users: Vec, + revoked_users: Vec, ) -> PyResult { + crate::binding_utils::unwrap_bytes!(devices, users, revoked_users); Ok(Self(user_get::Trustchain { devices, users, @@ -147,11 +149,16 @@ pub(crate) struct UserGetRepOk; impl UserGetRepOk { #[new] fn new( - user_certificate: Vec, - revoked_user_certificate: Option>, - device_certificates: Vec>, + user_certificate: BytesWrapper, + revoked_user_certificate: Option, + device_certificates: Vec, trustchain: Trustchain, ) -> PyResult<(Self, UserGetRep)> { + crate::binding_utils::unwrap_bytes!( + user_certificate, + revoked_user_certificate, + device_certificates + ); Ok(( Self, UserGetRep(user_get::Rep::Ok { @@ -223,11 +230,17 @@ crate::binding_utils::gen_proto!(UserCreateReq, __richcmp__, eq); impl UserCreateReq { #[new] fn new( - user_certificate: Vec, - device_certificate: Vec, - redacted_user_certificate: Vec, - redacted_device_certificate: Vec, + user_certificate: BytesWrapper, + device_certificate: BytesWrapper, + redacted_user_certificate: BytesWrapper, + redacted_device_certificate: BytesWrapper, ) -> PyResult { + crate::binding_utils::unwrap_bytes!( + user_certificate, + device_certificate, + redacted_user_certificate, + redacted_device_certificate + ); Ok(Self(user_create::Req { user_certificate, device_certificate, @@ -299,7 +312,8 @@ crate::binding_utils::gen_proto!(UserRevokeReq, __richcmp__, eq); #[pymethods] impl UserRevokeReq { #[new] - fn new(revoked_user_certificate: Vec) -> PyResult { + fn new(revoked_user_certificate: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(revoked_user_certificate); Ok(Self(user_revoke::Req { revoked_user_certificate, })) @@ -352,7 +366,11 @@ crate::binding_utils::gen_proto!(DeviceCreateReq, __richcmp__, eq); #[pymethods] impl DeviceCreateReq { #[new] - fn new(device_certificate: Vec, redacted_device_certificate: Vec) -> PyResult { + fn new( + device_certificate: BytesWrapper, + redacted_device_certificate: BytesWrapper, + ) -> PyResult { + crate::binding_utils::unwrap_bytes!(device_certificate, redacted_device_certificate); Ok(Self(device_create::Req { device_certificate, redacted_device_certificate, diff --git a/src/protocol/vlob.rs b/src/protocol/vlob.rs index 4e956beef73..55055df9e1d 100644 --- a/src/protocol/vlob.rs +++ b/src/protocol/vlob.rs @@ -17,6 +17,7 @@ use libparsec::protocol::{ }; use crate::{ + binding_utils::BytesWrapper, ids::{DeviceID, RealmID, SequesterServiceID, VlobID}, protocol::{ error::{ProtocolError, ProtocolErrorFields, ProtocolResult}, @@ -35,7 +36,8 @@ crate::binding_utils::gen_proto!(ReencryptionBatchEntry, __richcmp__, eq); #[pymethods] impl ReencryptionBatchEntry { #[new] - fn new(vlob_id: VlobID, version: u64, blob: Vec) -> PyResult { + fn new(vlob_id: VlobID, version: u64, blob: BytesWrapper) -> PyResult { + crate::binding_utils::unwrap_bytes!(blob); let vlob_id = vlob_id.0; Ok(Self(libparsec::types::ReencryptionBatchEntry { vlob_id, @@ -75,14 +77,15 @@ impl VlobCreateReq { encryption_revision: u64, vlob_id: VlobID, timestamp: DateTime, - blob: Vec, - sequester_blob: Option>>, + blob: BytesWrapper, + sequester_blob: Option>, ) -> PyResult { + crate::binding_utils::unwrap_bytes!(blob); let realm_id = realm_id.0; let vlob_id = vlob_id.0; let timestamp = timestamp.0; let sequester_blob = libparsec::types::Maybe::Present( - sequester_blob.map(|x| x.into_iter().map(|(k, v)| (k.0, v)).collect()), + sequester_blob.map(|x| x.into_iter().map(|(k, v)| (k.0, v.into())).collect()), ); Ok(Self(vlob_create::Req { realm_id, @@ -265,11 +268,12 @@ impl VlobReadRepOk { #[new] fn new( version: u32, - blob: Vec, + blob: BytesWrapper, author: DeviceID, timestamp: DateTime, author_last_role_granted_on: DateTime, ) -> PyResult<(Self, VlobReadRep)> { + crate::binding_utils::unwrap_bytes!(blob); Ok(( Self, VlobReadRep(vlob_read::Rep::Ok { @@ -346,13 +350,14 @@ impl VlobUpdateReq { vlob_id: VlobID, timestamp: DateTime, version: u32, - blob: Vec, - sequester_blob: Option>>, + blob: BytesWrapper, + sequester_blob: Option>, ) -> PyResult { + crate::binding_utils::unwrap_bytes!(blob); let vlob_id = vlob_id.0; let timestamp = timestamp.0; let sequester_blob = libparsec::types::Maybe::Present( - sequester_blob.map(|x| x.into_iter().map(|(k, v)| (k.0, v)).collect()), + sequester_blob.map(|x| x.into_iter().map(|(k, v)| (k.0, v.into())).collect()), ); Ok(Self(vlob_update::Req { encryption_revision, diff --git a/src/trustchain.rs b/src/trustchain.rs index ac8b091df68..b7d44bc914f 100644 --- a/src/trustchain.rs +++ b/src/trustchain.rs @@ -2,7 +2,7 @@ use crate::{ api_crypto::VerifyKey, - binding_utils::gen_proto, + binding_utils::{gen_proto, BytesWrapper}, data::{DeviceCertificate, RevokedUserCertificate, UserCertificate}, ids::{DeviceID, UserID}, protocol::Trustchain, @@ -66,11 +66,12 @@ impl TrustchainContext { fn load_trustchain<'py>( &mut self, - users: Vec>, - revoked_users: Vec>, - devices: Vec>, + users: Vec, + revoked_users: Vec, + devices: Vec, py: Python<'py>, ) -> Result<(&'py PyTuple, &'py PyTuple, &'py PyTuple), TrustchainError> { + crate::binding_utils::unwrap_bytes!(users, revoked_users, devices); let (users, revoked_users, devices) = self.0.load_trustchain(&users, &revoked_users, &devices)?; @@ -92,9 +93,9 @@ impl TrustchainContext { fn load_user_and_devices<'py>( &mut self, trustchain: Trustchain, - user_certif: Vec, - revoked_user_certif: Option>, - devices_certifs: Vec>, + user_certif: BytesWrapper, + revoked_user_certif: Option, + devices_certifs: Vec, expected_user_id: Option, py: Python<'py>, ) -> Result< @@ -105,6 +106,7 @@ impl TrustchainContext { ), TrustchainError, > { + crate::binding_utils::unwrap_bytes!(user_certif, revoked_user_certif, devices_certifs); let (user, revoked_user, devices) = self.0.load_user_and_devices( trustchain.0, user_certif,