예제 #1
0
파일: device.py 프로젝트: mjattiot/synapse
def _update_device_from_client_ips(
        device: JsonDict, client_ips: Dict[Tuple[str, str], JsonDict]) -> None:
    ip = client_ips.get((device["user_id"], device["device_id"]), {})
    device.update({
        "last_seen_ts": ip.get("last_seen"),
        "last_seen_ip": ip.get("ip")
    })
예제 #2
0
    async def invite_to_group(
        self, group_id: str, user_id: str, requester_user_id: str, content: JsonDict
    ) -> JsonDict:
        """Invite user to group"""

        group = await self.check_group_is_ours(
            group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id
        )
        if not group:
            raise SynapseError(400, "Group does not exist", errcode=Codes.BAD_STATE)

        # TODO: Check if user knocked

        invited_users = await self.store.get_invited_users_in_group(group_id)
        if user_id in invited_users:
            raise SynapseError(
                400, "User already invited to group", errcode=Codes.BAD_STATE
            )

        user_results = await self.store.get_users_in_group(
            group_id, include_private=True
        )
        if user_id in (user_result["user_id"] for user_result in user_results):
            raise SynapseError(400, "User already in group")

        content = {
            "profile": {"name": group["name"], "avatar_url": group["avatar_url"]},
            "inviter": requester_user_id,
        }

        if self.hs.is_mine_id(user_id):
            groups_local = self.hs.get_groups_local_handler()
            assert isinstance(
                groups_local, GroupsLocalHandler
            ), "Workers cannot invites users to groups."
            res = await groups_local.on_invite(group_id, user_id, content)
            local_attestation = None
        else:
            local_attestation = self.attestations.create_attestation(group_id, user_id)
            content.update({"attestation": local_attestation})

            res = await self.transport_client.invite_to_group_notification(
                get_domain_from_id(user_id), group_id, user_id, content
            )

            user_profile = res.get("user_profile", {})
            await self.store.add_remote_profile_cache(
                user_id,
                displayname=user_profile.get("displayname"),
                avatar_url=user_profile.get("avatar_url"),
            )

        if res["state"] == "join":
            if not self.hs.is_mine_id(user_id):
                remote_attestation = res["attestation"]

                await self.attestations.verify_attestation(
                    remote_attestation, user_id=user_id, group_id=group_id
                )
            else:
                remote_attestation = None

            await self.store.add_user_to_group(
                group_id,
                user_id,
                is_admin=False,
                is_public=False,  # TODO
                local_attestation=local_attestation,
                remote_attestation=remote_attestation,
            )
            return {"state": "join"}
        elif res["state"] == "invite":
            await self.store.add_group_invite(group_id, user_id)
            return {"state": "invite"}
        elif res["state"] == "reject":
            return {"state": "reject"}
        else:
            raise SynapseError(502, "Unknown state returned by HS")
예제 #3
0
    async def _send_events_for_new_room(
        self,
        creator: Requester,
        room_id: str,
        preset_config: str,
        invite_list: List[str],
        initial_state: StateMap,
        creation_content: JsonDict,
        room_alias: Optional[RoomAlias] = None,
        power_level_content_override: Optional[JsonDict] = None,
        creator_join_profile: Optional[JsonDict] = None,
    ) -> int:
        """Sends the initial events into a new room.

        `power_level_content_override` doesn't apply when initial state has
        power level state event content.

        Returns:
            The stream_id of the last event persisted.
        """

        creator_id = creator.user.to_string()

        event_keys = {
            "room_id": room_id,
            "sender": creator_id,
            "state_key": ""
        }

        def create(etype: str, content: JsonDict, **kwargs) -> JsonDict:
            e = {"type": etype, "content": content}

            e.update(event_keys)
            e.update(kwargs)

            return e

        async def send(etype: str, content: JsonDict, **kwargs) -> int:
            event = create(etype, content, **kwargs)
            logger.debug("Sending %s in new room", etype)
            (
                _,
                last_stream_id,
            ) = await self.event_creation_handler.create_and_send_nonmember_event(
                creator, event, ratelimit=False)
            return last_stream_id

        config = self._presets_dict[preset_config]

        creation_content.update({"creator": creator_id})
        await send(etype=EventTypes.Create, content=creation_content)

        logger.debug("Sending %s in new room", EventTypes.Member)
        await self.room_member_handler.update_membership(
            creator,
            creator.user,
            room_id,
            "join",
            ratelimit=False,
            content=creator_join_profile,
        )

        # We treat the power levels override specially as this needs to be one
        # of the first events that get sent into a room.
        pl_content = initial_state.pop((EventTypes.PowerLevels, ""), None)
        if pl_content is not None:
            last_sent_stream_id = await send(etype=EventTypes.PowerLevels,
                                             content=pl_content)
        else:
            power_level_content = {
                "users": {
                    creator_id: 100
                },
                "users_default": 0,
                "events": {
                    EventTypes.Name: 50,
                    EventTypes.PowerLevels: 100,
                    EventTypes.RoomHistoryVisibility: 100,
                    EventTypes.CanonicalAlias: 50,
                    EventTypes.RoomAvatar: 50,
                    EventTypes.Tombstone: 100,
                    EventTypes.ServerACL: 100,
                    EventTypes.RoomEncryption: 100,
                },
                "events_default": 0,
                "state_default": 50,
                "ban": 50,
                "kick": 50,
                "redact": 50,
                "invite": 50,
            }  # type: JsonDict

            if config["original_invitees_have_ops"]:
                for invitee in invite_list:
                    power_level_content["users"][invitee] = 100

            # Power levels overrides are defined per chat preset
            power_level_content.update(config["power_level_content_override"])

            if power_level_content_override:
                power_level_content.update(power_level_content_override)

            last_sent_stream_id = await send(etype=EventTypes.PowerLevels,
                                             content=power_level_content)

        if room_alias and (EventTypes.CanonicalAlias, "") not in initial_state:
            last_sent_stream_id = await send(
                etype=EventTypes.CanonicalAlias,
                content={"alias": room_alias.to_string()},
            )

        if (EventTypes.JoinRules, "") not in initial_state:
            last_sent_stream_id = await send(
                etype=EventTypes.JoinRules,
                content={"join_rule": config["join_rules"]})

        if (EventTypes.RoomHistoryVisibility, "") not in initial_state:
            last_sent_stream_id = await send(
                etype=EventTypes.RoomHistoryVisibility,
                content={"history_visibility": config["history_visibility"]},
            )

        if config["guest_can_join"]:
            if (EventTypes.GuestAccess, "") not in initial_state:
                last_sent_stream_id = await send(
                    etype=EventTypes.GuestAccess,
                    content={"guest_access": "can_join"})

        for (etype, state_key), content in initial_state.items():
            last_sent_stream_id = await send(etype=etype,
                                             state_key=state_key,
                                             content=content)

        if config["encrypted"]:
            last_sent_stream_id = await send(
                etype=EventTypes.RoomEncryption,
                state_key="",
                content={"algorithm": RoomEncryptionAlgorithms.DEFAULT},
            )

        return last_sent_stream_id