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") })
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")
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