def build_action_generator(self): return ActionGenerator(self)
def get_action_generator(self) -> ActionGenerator: return ActionGenerator(self)
def handle_new_client_event(self, event, context, extra_users=[]): # We now need to go and hit out to wherever we need to hit out to. self.auth.check(event, auth_events=context.current_state) yield self.maybe_kick_guest_users(event, context.current_state.values()) if event.type == EventTypes.CanonicalAlias: # Check the alias is acually valid (at this time at least) room_alias_str = event.content.get("alias", None) if room_alias_str: room_alias = RoomAlias.from_string(room_alias_str) directory_handler = self.hs.get_handlers().directory_handler mapping = yield directory_handler.get_association(room_alias) if mapping["room_id"] != event.room_id: raise SynapseError( 400, "Room alias %s does not point to the room" % ( room_alias_str, ) ) federation_handler = self.hs.get_handlers().federation_handler if event.type == EventTypes.Member: if event.content["membership"] == Membership.INVITE: event.unsigned["invite_room_state"] = [ { "type": e.type, "state_key": e.state_key, "content": e.content, "sender": e.sender, } for k, e in context.current_state.items() if e.type in ( EventTypes.JoinRules, EventTypes.CanonicalAlias, EventTypes.RoomAvatar, EventTypes.Name, ) ] invitee = UserID.from_string(event.state_key) if not self.hs.is_mine(invitee): # TODO: Can we add signature from remote server in a nicer # way? If we have been invited by a remote server, we need # to get them to sign the event. returned_invite = yield federation_handler.send_invite( invitee.domain, event, ) event.unsigned.pop("room_state", None) # TODO: Make sure the signatures actually are correct. event.signatures.update( returned_invite.signatures ) if event.type == EventTypes.Redaction: if self.auth.check_redaction(event, auth_events=context.current_state): original_event = yield self.store.get_event( event.redacts, check_redacted=False, get_prev_content=False, allow_rejected=False, allow_none=False ) if event.user_id != original_event.user_id: raise AuthError( 403, "You don't have permission to redact events" ) action_generator = ActionGenerator(self.hs) yield action_generator.handle_push_actions_for_event( event, context, self ) (event_stream_id, max_stream_id) = yield self.store.persist_event( event, context=context ) destinations = set() for k, s in context.current_state.items(): try: if k[0] == EventTypes.Member: if s.content["membership"] == Membership.JOIN: destinations.add( UserID.from_string(s.state_key).domain ) except SynapseError: logger.warn( "Failed to get destination from event %s", s.event_id ) with PreserveLoggingContext(): # Don't block waiting on waking up all the listeners. self.notifier.on_new_room_event( event, event_stream_id, max_stream_id, extra_users=extra_users ) # If invite, remove room_state from unsigned before sending. event.unsigned.pop("invite_room_state", None) federation_handler.handle_new_event( event, destinations=destinations, )
def handle_new_client_event(self, requester, event, context, ratelimit=True, extra_users=[]): # We now need to go and hit out to wherever we need to hit out to. if ratelimit: self.ratelimit(requester) try: yield self.auth.check_from_context(event, context) except AuthError as err: logger.warn("Denying new event %r because %s", event, err) raise err yield self.maybe_kick_guest_users(event, context) if event.type == EventTypes.CanonicalAlias: # Check the alias is acually valid (at this time at least) room_alias_str = event.content.get("alias", None) if room_alias_str: room_alias = RoomAlias.from_string(room_alias_str) directory_handler = self.hs.get_handlers().directory_handler mapping = yield directory_handler.get_association(room_alias) if mapping["room_id"] != event.room_id: raise SynapseError( 400, "Room alias %s does not point to the room" % (room_alias_str, )) federation_handler = self.hs.get_handlers().federation_handler if event.type == EventTypes.Member: if event.content["membership"] == Membership.INVITE: def is_inviter_member_event(e): return (e.type == EventTypes.Member and e.sender == event.sender) state_to_include_ids = [ e_id for k, e_id in context.current_state_ids.items() if k[0] in self.hs.config.room_invite_state_types or k[0] == EventTypes.Member and k[1] == event.sender ] state_to_include = yield self.store.get_events( state_to_include_ids) event.unsigned["invite_room_state"] = [{ "type": e.type, "state_key": e.state_key, "content": e.content, "sender": e.sender, } for e in state_to_include.values()] invitee = UserID.from_string(event.state_key) if not self.hs.is_mine(invitee): # TODO: Can we add signature from remote server in a nicer # way? If we have been invited by a remote server, we need # to get them to sign the event. returned_invite = yield federation_handler.send_invite( invitee.domain, event, ) event.unsigned.pop("room_state", None) # TODO: Make sure the signatures actually are correct. event.signatures.update(returned_invite.signatures) if event.type == EventTypes.Redaction: auth_events_ids = yield self.auth.compute_auth_events( event, context.prev_state_ids, for_verification=True, ) auth_events = yield self.store.get_events(auth_events_ids) auth_events = {(e.type, e.state_key): e for e in auth_events.values()} if self.auth.check_redaction(event, auth_events=auth_events): original_event = yield self.store.get_event( event.redacts, check_redacted=False, get_prev_content=False, allow_rejected=False, allow_none=False) if event.user_id != original_event.user_id: raise AuthError( 403, "You don't have permission to redact events") if event.type == EventTypes.Create and context.prev_state_ids: raise AuthError( 403, "Changing the room create event is forbidden", ) action_generator = ActionGenerator(self.hs) yield action_generator.handle_push_actions_for_event(event, context) (event_stream_id, max_stream_id) = yield self.store.persist_event(event, context=context) # this intentionally does not yield: we don't care about the result # and don't need to wait for it. preserve_fn(self.hs.get_pusherpool().on_new_notifications)( event_stream_id, max_stream_id) @defer.inlineCallbacks def _notify(): yield run_on_reactor() yield self.notifier.on_new_room_event(event, event_stream_id, max_stream_id, extra_users=extra_users) preserve_fn(_notify)() # If invite, remove room_state from unsigned before sending. event.unsigned.pop("invite_room_state", None)
def handle_new_client_event( self, requester, event, context, ratelimit=True, extra_users=[] ): # We now need to go and hit out to wherever we need to hit out to. if ratelimit: self.ratelimit(requester) try: self.auth.check(event, auth_events=context.current_state) except AuthError as err: logger.warn("Denying new event %r because %s", event, err) raise err yield self.maybe_kick_guest_users(event, context.current_state.values()) if event.type == EventTypes.CanonicalAlias: # Check the alias is acually valid (at this time at least) room_alias_str = event.content.get("alias", None) if room_alias_str: room_alias = RoomAlias.from_string(room_alias_str) directory_handler = self.hs.get_handlers().directory_handler mapping = yield directory_handler.get_association(room_alias) if mapping["room_id"] != event.room_id: raise SynapseError( 400, "Room alias %s does not point to the room" % ( room_alias_str, ) ) federation_handler = self.hs.get_handlers().federation_handler if event.type == EventTypes.Member: if event.content["membership"] == Membership.INVITE: def is_inviter_member_event(e): return ( e.type == EventTypes.Member and e.sender == event.sender ) event.unsigned["invite_room_state"] = [ { "type": e.type, "state_key": e.state_key, "content": e.content, "sender": e.sender, } for k, e in context.current_state.items() if e.type in self.hs.config.room_invite_state_types or is_inviter_member_event(e) ] invitee = UserID.from_string(event.state_key) if not self.hs.is_mine(invitee): # TODO: Can we add signature from remote server in a nicer # way? If we have been invited by a remote server, we need # to get them to sign the event. returned_invite = yield federation_handler.send_invite( invitee.domain, event, ) event.unsigned.pop("room_state", None) # TODO: Make sure the signatures actually are correct. event.signatures.update( returned_invite.signatures ) if event.type == EventTypes.Redaction: if self.auth.check_redaction(event, auth_events=context.current_state): original_event = yield self.store.get_event( event.redacts, check_redacted=False, get_prev_content=False, allow_rejected=False, allow_none=False ) if event.user_id != original_event.user_id: raise AuthError( 403, "You don't have permission to redact events" ) if event.type == EventTypes.Create and context.current_state: raise AuthError( 403, "Changing the room create event is forbidden", ) action_generator = ActionGenerator(self.hs) yield action_generator.handle_push_actions_for_event( event, context ) (event_stream_id, max_stream_id) = yield self.store.persist_event( event, context=context ) # this intentionally does not yield: we don't care about the result # and don't need to wait for it. preserve_fn(self.hs.get_pusherpool().on_new_notifications)( event_stream_id, max_stream_id ) destinations = set() for k, s in context.current_state.items(): try: if k[0] == EventTypes.Member: if s.content["membership"] == Membership.JOIN: destinations.add(get_domain_from_id(s.state_key)) except SynapseError: logger.warn( "Failed to get destination from event %s", s.event_id ) @defer.inlineCallbacks def _notify(): yield run_on_reactor() self.notifier.on_new_room_event( event, event_stream_id, max_stream_id, extra_users=extra_users ) preserve_fn(_notify)() # If invite, remove room_state from unsigned before sending. event.unsigned.pop("invite_room_state", None) federation_handler.handle_new_event( event, destinations=destinations, )
def handle_new_client_event(self, requester, event, context, ratelimit=True, extra_users=[]): # We now need to go and hit out to wherever we need to hit out to. if ratelimit: self.ratelimit(requester) self.auth.check(event, auth_events=context.current_state) yield self.maybe_kick_guest_users(event, context.current_state.values()) if event.type == EventTypes.CanonicalAlias: # Check the alias is acually valid (at this time at least) room_alias_str = event.content.get("alias", None) if room_alias_str: room_alias = RoomAlias.from_string(room_alias_str) directory_handler = self.hs.get_handlers().directory_handler mapping = yield directory_handler.get_association(room_alias) if mapping["room_id"] != event.room_id: raise SynapseError( 400, "Room alias %s does not point to the room" % (room_alias_str, )) federation_handler = self.hs.get_handlers().federation_handler if event.type == EventTypes.Member: if event.content["membership"] == Membership.INVITE: def is_inviter_member_event(e): return (e.type == EventTypes.Member and e.sender == event.sender) event.unsigned["invite_room_state"] = [ { "type": e.type, "state_key": e.state_key, "content": e.content, "sender": e.sender, } for k, e in context.current_state.items() if e.type in self.hs.config.room_invite_state_types or is_inviter_member_event(e) ] invitee = UserID.from_string(event.state_key) if not self.hs.is_mine(invitee): # TODO: Can we add signature from remote server in a nicer # way? If we have been invited by a remote server, we need # to get them to sign the event. returned_invite = yield federation_handler.send_invite( invitee.domain, event, ) event.unsigned.pop("room_state", None) # TODO: Make sure the signatures actually are correct. event.signatures.update(returned_invite.signatures) if event.type == EventTypes.Redaction: if self.auth.check_redaction(event, auth_events=context.current_state): original_event = yield self.store.get_event( event.redacts, check_redacted=False, get_prev_content=False, allow_rejected=False, allow_none=False) if event.user_id != original_event.user_id: raise AuthError( 403, "You don't have permission to redact events") if event.type == EventTypes.Create and context.current_state: raise AuthError( 403, "Changing the room create event is forbidden", ) action_generator = ActionGenerator(self.hs) yield action_generator.handle_push_actions_for_event( event, context, self) (event_stream_id, max_stream_id) = yield self.store.persist_event(event, context=context) destinations = set() for k, s in context.current_state.items(): try: if k[0] == EventTypes.Member: if s.content["membership"] == Membership.JOIN: destinations.add( UserID.from_string(s.state_key).domain) except SynapseError: logger.warn("Failed to get destination from event %s", s.event_id) with PreserveLoggingContext(): # Don't block waiting on waking up all the listeners. self.notifier.on_new_room_event(event, event_stream_id, max_stream_id, extra_users=extra_users) # If invite, remove room_state from unsigned before sending. event.unsigned.pop("invite_room_state", None) federation_handler.handle_new_event( event, destinations=destinations, )