diff --git a/server/parsec/_parsec_pyi/protocol/__init__.pyi b/server/parsec/_parsec_pyi/protocol/__init__.pyi index efb946e39ea..b5b30134396 100644 --- a/server/parsec/_parsec_pyi/protocol/__init__.pyi +++ b/server/parsec/_parsec_pyi/protocol/__init__.pyi @@ -4,7 +4,7 @@ from __future__ import annotations -from . import anonymous_cmds, authenticated_cmds, invited_cmds +from . import anonymous_cmds, authenticated_cmds, invited_cmds, tos_cmds class ActiveUsersLimit: NO_LIMIT: ActiveUsersLimit @@ -23,4 +23,4 @@ class ActiveUsersLimit: def __lt__(self, other: object) -> bool: ... def __ne__(self, other: object) -> bool: ... -__all__ = ["ActiveUsersLimit", "anonymous_cmds", "authenticated_cmds", "invited_cmds"] +__all__ = ["ActiveUsersLimit", "anonymous_cmds", "authenticated_cmds", "invited_cmds", "tos_cmds"] diff --git a/server/parsec/_parsec_pyi/protocol/tos_cmds/__init__.pyi b/server/parsec/_parsec_pyi/protocol/tos_cmds/__init__.pyi new file mode 100644 index 00000000000..b6973ed4d68 --- /dev/null +++ b/server/parsec/_parsec_pyi/protocol/tos_cmds/__init__.pyi @@ -0,0 +1,10 @@ +# Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS + +# /!\ Autogenerated by misc/gen_protocol_typings.py, any modification will be lost ! + +from __future__ import annotations + +from . import v4 +from . import v4 as latest + +__all__ = ["latest", "v4"] diff --git a/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/__init__.pyi b/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/__init__.pyi new file mode 100644 index 00000000000..5b0da64f7a6 --- /dev/null +++ b/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/__init__.pyi @@ -0,0 +1,13 @@ +# Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS + +# /!\ Autogenerated by misc/gen_protocol_typings.py, any modification will be lost ! + +from __future__ import annotations + +from . import tos_accept, tos_get + +class AnyCmdReq: + @classmethod + def load(cls, raw: bytes) -> tos_accept.Req | tos_get.Req: ... + +__all__ = ["AnyCmdReq", "tos_accept", "tos_get"] diff --git a/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/tos_accept.pyi b/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/tos_accept.pyi new file mode 100644 index 00000000000..3f51caf0505 --- /dev/null +++ b/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/tos_accept.pyi @@ -0,0 +1,40 @@ +# Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS + +# /!\ Autogenerated by misc/gen_protocol_typings.py, any modification will be lost ! + +from __future__ import annotations + +from parsec._parsec import DateTime + +class Req: + def __init__(self, tos_updated_on: DateTime) -> None: ... + def dump(self) -> bytes: ... + @property + def tos_updated_on(self) -> DateTime: ... + +class Rep: + @staticmethod + def load(raw: bytes) -> Rep: ... + def dump(self) -> bytes: ... + +class RepUnknownStatus(Rep): + def __init__(self, status: str, reason: str | None) -> None: ... + @property + def status(self) -> str: ... + @property + def reason(self) -> str | None: ... + +class RepOk(Rep): + def __init__( + self, + ) -> None: ... + +class RepNoTos(Rep): + def __init__( + self, + ) -> None: ... + +class RepTosMismatch(Rep): + def __init__( + self, + ) -> None: ... diff --git a/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/tos_get.pyi b/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/tos_get.pyi new file mode 100644 index 00000000000..02e663e0045 --- /dev/null +++ b/server/parsec/_parsec_pyi/protocol/tos_cmds/v4/tos_get.pyi @@ -0,0 +1,37 @@ +# Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS + +# /!\ Autogenerated by misc/gen_protocol_typings.py, any modification will be lost ! + +from __future__ import annotations + +from parsec._parsec import DateTime + +class Req: + def __init__( + self, + ) -> None: ... + def dump(self) -> bytes: ... + +class Rep: + @staticmethod + def load(raw: bytes) -> Rep: ... + def dump(self) -> bytes: ... + +class RepUnknownStatus(Rep): + def __init__(self, status: str, reason: str | None) -> None: ... + @property + def status(self) -> str: ... + @property + def reason(self) -> str | None: ... + +class RepOk(Rep): + def __init__(self, per_locale_urls: dict[str, str], updated_on: DateTime) -> None: ... + @property + def per_locale_urls(self) -> dict[str, str]: ... + @property + def updated_on(self) -> DateTime: ... + +class RepNoTos(Rep): + def __init__( + self, + ) -> None: ... diff --git a/server/tests/common/rpc.py b/server/tests/common/rpc.py index af6eec450a6..019f5145807 100644 --- a/server/tests/common/rpc.py +++ b/server/tests/common/rpc.py @@ -19,11 +19,12 @@ anonymous_cmds, authenticated_cmds, invited_cmds, + tos_cmds, ) class BaseAnonymousRpcClient: - async def _do_request(self, req: bytes) -> bytes: + async def _do_request(self, req: bytes, family: str) -> bytes: raise NotImplementedError async def organization_bootstrap( @@ -45,19 +46,19 @@ async def organization_bootstrap( redacted_device_certificate=redacted_device_certificate, sequester_authority_certificate=sequester_authority_certificate, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "anonymous") return anonymous_cmds.latest.organization_bootstrap.Rep.load(raw_rep) async def ping(self, ping: str) -> anonymous_cmds.latest.ping.Rep: req = anonymous_cmds.latest.ping.Req(ping=ping) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "anonymous") return anonymous_cmds.latest.ping.Rep.load(raw_rep) async def pki_enrollment_info( self, enrollment_id: EnrollmentID ) -> anonymous_cmds.latest.pki_enrollment_info.Rep: req = anonymous_cmds.latest.pki_enrollment_info.Req(enrollment_id=enrollment_id) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "anonymous") return anonymous_cmds.latest.pki_enrollment_info.Rep.load(raw_rep) async def pki_enrollment_submit( @@ -77,12 +78,12 @@ async def pki_enrollment_submit( submit_payload_signature=submit_payload_signature, submit_payload=submit_payload, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "anonymous") return anonymous_cmds.latest.pki_enrollment_submit.Rep.load(raw_rep) class BaseAuthenticatedRpcClient: - async def _do_request(self, req: bytes) -> bytes: + async def _do_request(self, req: bytes, family: str) -> bytes: raise NotImplementedError async def block_create( @@ -91,12 +92,12 @@ async def block_create( req = authenticated_cmds.latest.block_create.Req( block_id=block_id, realm_id=realm_id, key_index=key_index, block=block ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.block_create.Rep.load(raw_rep) async def block_read(self, block_id: BlockID) -> authenticated_cmds.latest.block_read.Rep: req = authenticated_cmds.latest.block_read.Req(block_id=block_id) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.block_read.Rep.load(raw_rep) async def certificate_get( @@ -112,7 +113,7 @@ async def certificate_get( shamir_recovery_after=shamir_recovery_after, realm_after=realm_after, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.certificate_get.Rep.load(raw_rep) async def device_create( @@ -122,28 +123,28 @@ async def device_create( device_certificate=device_certificate, redacted_device_certificate=redacted_device_certificate, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.device_create.Rep.load(raw_rep) async def events_listen( self, ) -> authenticated_cmds.latest.events_listen.Rep: req = authenticated_cmds.latest.events_listen.Req() - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.events_listen.Rep.load(raw_rep) async def invite_cancel( self, token: InvitationToken ) -> authenticated_cmds.latest.invite_cancel.Rep: req = authenticated_cmds.latest.invite_cancel.Req(token=token) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_cancel.Rep.load(raw_rep) async def invite_complete( self, token: InvitationToken ) -> authenticated_cmds.latest.invite_complete.Rep: req = authenticated_cmds.latest.invite_complete.Req(token=token) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_complete.Rep.load(raw_rep) async def invite_greeter_cancel_greeting_attempt( @@ -152,14 +153,14 @@ async def invite_greeter_cancel_greeting_attempt( req = authenticated_cmds.latest.invite_greeter_cancel_greeting_attempt.Req( greeting_attempt=greeting_attempt, reason=reason ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_greeter_cancel_greeting_attempt.Rep.load(raw_rep) async def invite_greeter_start_greeting_attempt( self, token: InvitationToken ) -> authenticated_cmds.latest.invite_greeter_start_greeting_attempt.Rep: req = authenticated_cmds.latest.invite_greeter_start_greeting_attempt.Req(token=token) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_greeter_start_greeting_attempt.Rep.load(raw_rep) async def invite_greeter_step( @@ -170,21 +171,21 @@ async def invite_greeter_step( req = authenticated_cmds.latest.invite_greeter_step.Req( greeting_attempt=greeting_attempt, greeter_step=greeter_step ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_greeter_step.Rep.load(raw_rep) async def invite_list( self, ) -> authenticated_cmds.latest.invite_list.Rep: req = authenticated_cmds.latest.invite_list.Req() - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_list.Rep.load(raw_rep) async def invite_new_device( self, send_email: bool ) -> authenticated_cmds.latest.invite_new_device.Rep: req = authenticated_cmds.latest.invite_new_device.Req(send_email=send_email) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_new_device.Rep.load(raw_rep) async def invite_new_user( @@ -193,12 +194,12 @@ async def invite_new_user( req = authenticated_cmds.latest.invite_new_user.Req( claimer_email=claimer_email, send_email=send_email ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.invite_new_user.Rep.load(raw_rep) async def ping(self, ping: str) -> authenticated_cmds.latest.ping.Rep: req = authenticated_cmds.latest.ping.Req(ping=ping) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.ping.Rep.load(raw_rep) async def pki_enrollment_accept( @@ -222,21 +223,21 @@ async def pki_enrollment_accept( redacted_device_certificate=redacted_device_certificate, redacted_user_certificate=redacted_user_certificate, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.pki_enrollment_accept.Rep.load(raw_rep) async def pki_enrollment_list( self, ) -> authenticated_cmds.latest.pki_enrollment_list.Rep: req = authenticated_cmds.latest.pki_enrollment_list.Req() - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.pki_enrollment_list.Rep.load(raw_rep) async def pki_enrollment_reject( self, enrollment_id: EnrollmentID ) -> authenticated_cmds.latest.pki_enrollment_reject.Rep: req = authenticated_cmds.latest.pki_enrollment_reject.Req(enrollment_id=enrollment_id) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.pki_enrollment_reject.Rep.load(raw_rep) async def realm_create( @@ -245,7 +246,7 @@ async def realm_create( req = authenticated_cmds.latest.realm_create.Req( realm_role_certificate=realm_role_certificate ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.realm_create.Rep.load(raw_rep) async def realm_get_keys_bundle( @@ -254,7 +255,7 @@ async def realm_get_keys_bundle( req = authenticated_cmds.latest.realm_get_keys_bundle.Req( realm_id=realm_id, key_index=key_index ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.realm_get_keys_bundle.Rep.load(raw_rep) async def realm_rename( @@ -263,7 +264,7 @@ async def realm_rename( req = authenticated_cmds.latest.realm_rename.Req( realm_name_certificate=realm_name_certificate, initial_name_or_fail=initial_name_or_fail ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.realm_rename.Rep.load(raw_rep) async def realm_rotate_key( @@ -277,7 +278,7 @@ async def realm_rotate_key( per_participant_keys_bundle_access=per_participant_keys_bundle_access, keys_bundle=keys_bundle, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.realm_rotate_key.Rep.load(raw_rep) async def realm_share( @@ -288,7 +289,7 @@ async def realm_share( recipient_keys_bundle_access=recipient_keys_bundle_access, key_index=key_index, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.realm_share.Rep.load(raw_rep) async def realm_unshare( @@ -297,14 +298,14 @@ async def realm_unshare( req = authenticated_cmds.latest.realm_unshare.Req( realm_role_certificate=realm_role_certificate ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.realm_unshare.Rep.load(raw_rep) async def shamir_recovery_setup( self, setup: authenticated_cmds.latest.shamir_recovery_setup.ShamirRecoverySetup | None ) -> authenticated_cmds.latest.shamir_recovery_setup.Rep: req = authenticated_cmds.latest.shamir_recovery_setup.Req(setup=setup) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.shamir_recovery_setup.Rep.load(raw_rep) async def user_create( @@ -320,7 +321,7 @@ async def user_create( redacted_user_certificate=redacted_user_certificate, redacted_device_certificate=redacted_device_certificate, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.user_create.Rep.load(raw_rep) async def user_revoke( @@ -329,7 +330,7 @@ async def user_revoke( req = authenticated_cmds.latest.user_revoke.Req( revoked_user_certificate=revoked_user_certificate ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.user_revoke.Rep.load(raw_rep) async def user_update( @@ -338,7 +339,7 @@ async def user_update( req = authenticated_cmds.latest.user_update.Req( user_update_certificate=user_update_certificate ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.user_update.Rep.load(raw_rep) async def vlob_create( @@ -358,7 +359,7 @@ async def vlob_create( blob=blob, sequester_blob=sequester_blob, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.vlob_create.Rep.load(raw_rep) async def vlob_poll_changes( @@ -367,21 +368,21 @@ async def vlob_poll_changes( req = authenticated_cmds.latest.vlob_poll_changes.Req( realm_id=realm_id, last_checkpoint=last_checkpoint ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.vlob_poll_changes.Rep.load(raw_rep) async def vlob_read_batch( self, realm_id: VlobID, vlobs: list[VlobID], at: DateTime | None ) -> authenticated_cmds.latest.vlob_read_batch.Rep: req = authenticated_cmds.latest.vlob_read_batch.Req(realm_id=realm_id, vlobs=vlobs, at=at) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.vlob_read_batch.Rep.load(raw_rep) async def vlob_read_versions( self, realm_id: VlobID, items: list[tuple[VlobID, int]] ) -> authenticated_cmds.latest.vlob_read_versions.Rep: req = authenticated_cmds.latest.vlob_read_versions.Req(realm_id=realm_id, items=items) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.vlob_read_versions.Rep.load(raw_rep) async def vlob_update( @@ -401,12 +402,12 @@ async def vlob_update( blob=blob, sequester_blob=sequester_blob, ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "authenticated") return authenticated_cmds.latest.vlob_update.Rep.load(raw_rep) class BaseInvitedRpcClient: - async def _do_request(self, req: bytes) -> bytes: + async def _do_request(self, req: bytes, family: str) -> bytes: raise NotImplementedError async def invite_claimer_cancel_greeting_attempt( @@ -415,14 +416,14 @@ async def invite_claimer_cancel_greeting_attempt( req = invited_cmds.latest.invite_claimer_cancel_greeting_attempt.Req( greeting_attempt=greeting_attempt, reason=reason ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "invited") return invited_cmds.latest.invite_claimer_cancel_greeting_attempt.Rep.load(raw_rep) async def invite_claimer_start_greeting_attempt( self, greeter: UserID ) -> invited_cmds.latest.invite_claimer_start_greeting_attempt.Rep: req = invited_cmds.latest.invite_claimer_start_greeting_attempt.Req(greeter=greeter) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "invited") return invited_cmds.latest.invite_claimer_start_greeting_attempt.Rep.load(raw_rep) async def invite_claimer_step( @@ -433,17 +434,34 @@ async def invite_claimer_step( req = invited_cmds.latest.invite_claimer_step.Req( greeting_attempt=greeting_attempt, claimer_step=claimer_step ) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "invited") return invited_cmds.latest.invite_claimer_step.Rep.load(raw_rep) async def invite_info( self, ) -> invited_cmds.latest.invite_info.Rep: req = invited_cmds.latest.invite_info.Req() - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "invited") return invited_cmds.latest.invite_info.Rep.load(raw_rep) async def ping(self, ping: str) -> invited_cmds.latest.ping.Rep: req = invited_cmds.latest.ping.Req(ping=ping) - raw_rep = await self._do_request(req.dump()) + raw_rep = await self._do_request(req.dump(), "invited") return invited_cmds.latest.ping.Rep.load(raw_rep) + + +class BaseTosRpcClient: + async def _do_request(self, req: bytes, family: str) -> bytes: + raise NotImplementedError + + async def tos_accept(self, tos_updated_on: DateTime) -> tos_cmds.latest.tos_accept.Rep: + req = tos_cmds.latest.tos_accept.Req(tos_updated_on=tos_updated_on) + raw_rep = await self._do_request(req.dump(), "tos") + return tos_cmds.latest.tos_accept.Rep.load(raw_rep) + + async def tos_get( + self, + ) -> tos_cmds.latest.tos_get.Rep: + req = tos_cmds.latest.tos_get.Req() + raw_rep = await self._do_request(req.dump(), "tos") + return tos_cmds.latest.tos_get.Rep.load(raw_rep)