class FakeEvent: event_id = attr.ib() room_id = attr.ib() auth_events = attr.ib() type = "foo" state_key = "foo" internal_metadata = _EventInternalMetadata({}) def auth_event_ids(self): return self.auth_events def is_state(self): return True
class EventBuilder: """A format independent event builder used to build up the event content before signing the event. (Note that while objects of this class are frozen, the content/unsigned/internal_metadata fields are still mutable) Attributes: room_version: Version of the target room room_id type sender content unsigned internal_metadata _state _auth _store _clock _hostname: The hostname of the server creating the event _signing_key: The signing key to use to sign the event as the server """ _state = attr.ib(type=StateHandler) _auth = attr.ib(type=Auth) _store = attr.ib(type=DataStore) _clock = attr.ib(type=Clock) _hostname = attr.ib(type=str) _signing_key = attr.ib(type=SigningKey) room_version = attr.ib(type=RoomVersion) room_id = attr.ib(type=str) type = attr.ib(type=str) sender = attr.ib(type=str) content = attr.ib(default=attr.Factory(dict), type=JsonDict) unsigned = attr.ib(default=attr.Factory(dict), type=JsonDict) # These only exist on a subset of events, so they raise AttributeError if # someone tries to get them when they don't exist. _state_key = attr.ib(default=None, type=Optional[str]) _redacts = attr.ib(default=None, type=Optional[str]) _origin_server_ts = attr.ib(default=None, type=Optional[int]) internal_metadata = attr.ib( default=attr.Factory(lambda: _EventInternalMetadata({})), type=_EventInternalMetadata, ) @property def state_key(self): if self._state_key is not None: return self._state_key raise AttributeError("state_key") def is_state(self): return self._state_key is not None async def build( self, prev_event_ids: List[str], auth_event_ids: Optional[List[str]], ) -> EventBase: """Transform into a fully signed and hashed event Args: prev_event_ids: The event IDs to use as the prev events auth_event_ids: The event IDs to use as the auth events. Should normally be set to None, which will cause them to be calculated based on the room state at the prev_events. Returns: The signed and hashed event. """ if auth_event_ids is None: state_ids = await self._state.get_current_state_ids( self.room_id, prev_event_ids ) auth_event_ids = self._auth.compute_auth_events(self, state_ids) format_version = self.room_version.event_format if format_version == EventFormatVersions.V1: # The types of auth/prev events changes between event versions. auth_events = await self._store.add_event_hashes( auth_event_ids ) # type: Union[List[str], List[Tuple[str, Dict[str, str]]]] prev_events = await self._store.add_event_hashes( prev_event_ids ) # type: Union[List[str], List[Tuple[str, Dict[str, str]]]] else: auth_events = auth_event_ids prev_events = prev_event_ids old_depth = await self._store.get_max_depth_of(prev_event_ids) depth = old_depth + 1 # we cap depth of generated events, to ensure that they are not # rejected by other servers (and so that they can be persisted in # the db) depth = min(depth, MAX_DEPTH) event_dict = { "auth_events": auth_events, "prev_events": prev_events, "type": self.type, "room_id": self.room_id, "sender": self.sender, "content": self.content, "unsigned": self.unsigned, "depth": depth, "prev_state": [], } # type: Dict[str, Any] if self.is_state(): event_dict["state_key"] = self._state_key if self._redacts is not None: event_dict["redacts"] = self._redacts if self._origin_server_ts is not None: event_dict["origin_server_ts"] = self._origin_server_ts return create_local_event_from_event_dict( clock=self._clock, hostname=self._hostname, signing_key=self._signing_key, room_version=self.room_version, event_dict=event_dict, internal_metadata_dict=self.internal_metadata.get_dict(), )
class EventBuilder(object): """A format independent event builder used to build up the event content before signing the event. (Note that while objects of this class are frozen, the content/unsigned/internal_metadata fields are still mutable) Attributes: room_version: Version of the target room room_id (str) type (str) sender (str) content (dict) unsigned (dict) internal_metadata (_EventInternalMetadata) _state (StateHandler) _auth (synapse.api.Auth) _store (DataStore) _clock (Clock) _hostname (str): The hostname of the server creating the event _signing_key: The signing key to use to sign the event as the server """ _state = attr.ib() _auth = attr.ib() _store = attr.ib() _clock = attr.ib() _hostname = attr.ib() _signing_key = attr.ib() room_version = attr.ib(type=RoomVersion) room_id = attr.ib() type = attr.ib() sender = attr.ib() content = attr.ib(default=attr.Factory(dict)) unsigned = attr.ib(default=attr.Factory(dict)) # These only exist on a subset of events, so they raise AttributeError if # someone tries to get them when they don't exist. _state_key = attr.ib(default=None) _redacts = attr.ib(default=None) _origin_server_ts = attr.ib(default=None) internal_metadata = attr.ib( default=attr.Factory(lambda: _EventInternalMetadata({}))) @property def state_key(self): if self._state_key is not None: return self._state_key raise AttributeError("state_key") def is_state(self): return self._state_key is not None @defer.inlineCallbacks def build(self, prev_event_ids): """Transform into a fully signed and hashed event Args: prev_event_ids (list[str]): The event IDs to use as the prev events Returns: Deferred[FrozenEvent] """ state_ids = yield self._state.get_current_state_ids( self.room_id, prev_event_ids) auth_ids = yield self._auth.compute_auth_events(self, state_ids) format_version = self.room_version.event_format if format_version == EventFormatVersions.V1: auth_events = yield self._store.add_event_hashes(auth_ids) prev_events = yield self._store.add_event_hashes(prev_event_ids) else: auth_events = auth_ids prev_events = prev_event_ids old_depth = yield self._store.get_max_depth_of(prev_event_ids) depth = old_depth + 1 # we cap depth of generated events, to ensure that they are not # rejected by other servers (and so that they can be persisted in # the db) depth = min(depth, MAX_DEPTH) event_dict = { "auth_events": auth_events, "prev_events": prev_events, "type": self.type, "room_id": self.room_id, "sender": self.sender, "content": self.content, "unsigned": self.unsigned, "depth": depth, "prev_state": [], } if self.is_state(): event_dict["state_key"] = self._state_key if self._redacts is not None: event_dict["redacts"] = self._redacts if self._origin_server_ts is not None: event_dict["origin_server_ts"] = self._origin_server_ts return create_local_event_from_event_dict( clock=self._clock, hostname=self._hostname, signing_key=self._signing_key, room_version=self.room_version, event_dict=event_dict, internal_metadata_dict=self.internal_metadata.get_dict(), )
class EventBuilder: """A format independent event builder used to build up the event content before signing the event. (Note that while objects of this class are frozen, the content/unsigned/internal_metadata fields are still mutable) Attributes: room_version: Version of the target room room_id type sender content unsigned internal_metadata _state _auth _store _clock _hostname: The hostname of the server creating the event _signing_key: The signing key to use to sign the event as the server """ _state: StateHandler _event_auth_handler: "EventAuthHandler" _store: DataStore _clock: Clock _hostname: str _signing_key: SigningKey room_version: RoomVersion room_id: str type: str sender: str content: JsonDict = attr.Factory(dict) unsigned: JsonDict = attr.Factory(dict) # These only exist on a subset of events, so they raise AttributeError if # someone tries to get them when they don't exist. _state_key: Optional[str] = None _redacts: Optional[str] = None _origin_server_ts: Optional[int] = None internal_metadata: _EventInternalMetadata = attr.Factory( lambda: _EventInternalMetadata({})) @property def state_key(self) -> str: if self._state_key is not None: return self._state_key raise AttributeError("state_key") def is_state(self) -> bool: return self._state_key is not None async def build( self, prev_event_ids: List[str], auth_event_ids: Optional[List[str]], depth: Optional[int] = None, ) -> EventBase: """Transform into a fully signed and hashed event Args: prev_event_ids: The event IDs to use as the prev events auth_event_ids: The event IDs to use as the auth events. Should normally be set to None, which will cause them to be calculated based on the room state at the prev_events. depth: Override the depth used to order the event in the DAG. Should normally be set to None, which will cause the depth to be calculated based on the prev_events. Returns: The signed and hashed event. """ if auth_event_ids is None: state_ids = await self._state.get_current_state_ids( self.room_id, prev_event_ids) auth_event_ids = self._event_auth_handler.compute_auth_events( self, state_ids) format_version = self.room_version.event_format # The types of auth/prev events changes between event versions. prev_events: Union[List[str], List[Tuple[str, Dict[str, str]]]] auth_events: Union[List[str], List[Tuple[str, Dict[str, str]]]] if format_version == EventFormatVersions.V1: auth_events = await self._store.add_event_hashes(auth_event_ids) prev_events = await self._store.add_event_hashes(prev_event_ids) else: auth_events = auth_event_ids prev_events = prev_event_ids # Otherwise, progress the depth as normal if depth is None: ( _, most_recent_prev_event_depth, ) = await self._store.get_max_depth_of(prev_event_ids) depth = most_recent_prev_event_depth + 1 # we cap depth of generated events, to ensure that they are not # rejected by other servers (and so that they can be persisted in # the db) depth = min(depth, MAX_DEPTH) event_dict: Dict[str, Any] = { "auth_events": auth_events, "prev_events": prev_events, "type": self.type, "room_id": self.room_id, "sender": self.sender, "content": self.content, "unsigned": self.unsigned, "depth": depth, "prev_state": [], } if self.is_state(): event_dict["state_key"] = self._state_key if self._redacts is not None: event_dict["redacts"] = self._redacts if self._origin_server_ts is not None: event_dict["origin_server_ts"] = self._origin_server_ts return create_local_event_from_event_dict( clock=self._clock, hostname=self._hostname, signing_key=self._signing_key, room_version=self.room_version, event_dict=event_dict, internal_metadata_dict=self.internal_metadata.get_dict(), )