async def query_start_reencryption_maintenance( conn, organization_id: OrganizationID, author: DeviceID, realm_id: RealmID, encryption_revision: int, per_participant_message: Dict[UserID, bytes], timestamp: pendulum.DateTime, ) -> None: # Retrieve realm and make sure it is not under maintenance status = await get_realm_status(conn, organization_id, realm_id) if status.in_maintenance: raise RealmInMaintenanceError( f"Realm `{realm_id}` alrealy in maintenance") if encryption_revision != status.encryption_revision + 1: raise RealmEncryptionRevisionError("Invalid encryption revision") roles = await _get_realm_role_for_not_revoked(conn, organization_id, realm_id) if roles.get(author.user_id) != RealmRole.OWNER: raise RealmAccessError() if per_participant_message.keys() ^ roles.keys(): raise RealmParticipantsMismatchError( "Realm participants and message recipients mismatch") await conn.execute(*_q_query_start_reencryption_maintenance_update_realm( organization_id=organization_id.str, realm_id=realm_id.uuid, maintenance_started_by=author.str, maintenance_started_on=timestamp, maintenance_type="REENCRYPTION", encryption_revision=encryption_revision, )) await conn.execute( * _q_query_start_reencryption_maintenance_update_vlob_encryption_revision( organization_id=organization_id.str, realm_id=realm_id.uuid, encryption_revision=encryption_revision, )) await send_signal( conn, BackendEvent.REALM_MAINTENANCE_STARTED, organization_id=organization_id, author=author, realm_id=realm_id, encryption_revision=encryption_revision, ) for recipient, body in per_participant_message.items(): await send_message(conn, organization_id, author, recipient, timestamp, body)
async def start_reencryption_maintenance( self, organization_id: OrganizationID, author: DeviceID, realm_id: RealmID, encryption_revision: int, per_participant_message: Dict[UserID, bytes], timestamp: pendulum.DateTime, ) -> None: realm = self._get_realm(organization_id, realm_id) if realm.roles.get(author.user_id) != RealmRole.OWNER: raise RealmAccessError() if realm.status.in_maintenance: raise RealmInMaintenanceError( f"Realm `{realm_id}` alrealy in maintenance") if encryption_revision != realm.status.encryption_revision + 1: raise RealmEncryptionRevisionError("Invalid encryption revision") now = pendulum.now() not_revoked_roles = set() for user_id in realm.roles.keys(): user = await self._user_component.get_user(organization_id, user_id) if not user.revoked_on or user.revoked_on > now: not_revoked_roles.add(user_id) if per_participant_message.keys() ^ not_revoked_roles: raise RealmParticipantsMismatchError( "Realm participants and message recipients mismatch") realm.status = RealmStatus( maintenance_type=MaintenanceType.REENCRYPTION, maintenance_started_on=timestamp, maintenance_started_by=author, encryption_revision=encryption_revision, ) self._vlob_component._maintenance_reencryption_start_hook( organization_id, realm_id, encryption_revision) # Should first send maintenance event, then message to each participant await self._send_event( BackendEvent.REALM_MAINTENANCE_STARTED, organization_id=organization_id, author=author, realm_id=realm_id, encryption_revision=encryption_revision, ) for recipient, msg in per_participant_message.items(): await self._message_component.send(organization_id, author, recipient, timestamp, msg)
async def query_start_reencryption_maintenance( conn, organization_id: OrganizationID, author: DeviceID, realm_id: UUID, encryption_revision: int, per_participant_message: Dict[UserID, bytes], timestamp: pendulum.Pendulum, ) -> None: # Retrieve realm and make sure it is not under maintenance rep = await get_realm_status(conn, organization_id, realm_id) if rep["maintenance_type"]: raise RealmInMaintenanceError( f"Realm `{realm_id}` alrealy in maintenance") if encryption_revision != rep["encryption_revision"] + 1: raise RealmEncryptionRevisionError("Invalid encryption revision") roles = await get_realm_role_for_not_revoked(conn, organization_id, realm_id) if per_participant_message.keys() ^ roles.keys(): raise RealmParticipantsMismatchError( "Realm participants and message recipients mismatch") if roles.get(author.user_id) != RealmRole.OWNER: raise RealmAccessError() query = """ UPDATE realm SET encryption_revision=$6, maintenance_started_by=({}), maintenance_started_on=$4, maintenance_type=$5 WHERE _id = ({}) """.format( q_device_internal_id(organization_id=Parameter("$1"), device_id=Parameter("$3")), q_realm_internal_id(organization_id=Parameter("$1"), realm_id=Parameter("$2")), ) await conn.execute(query, organization_id, realm_id, author, timestamp, "REENCRYPTION", encryption_revision) query = """ INSERT INTO vlob_encryption_revision( realm, encryption_revision ) SELECT ({}), $3 """.format( q_realm_internal_id(organization_id=Parameter("$1"), realm_id=Parameter("$2"))) await conn.execute(query, organization_id, realm_id, encryption_revision) await send_signal( conn, "realm.maintenance_started", organization_id=organization_id, author=author, realm_id=realm_id, encryption_revision=encryption_revision, ) for recipient, body in per_participant_message.items(): await send_message(conn, organization_id, author, recipient, timestamp, body)