示例#1
0
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)
示例#2
0
    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)
示例#3
0
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)