pub struct Service {
pub mutex_federation: MutexMap<OwnedRoomId, ()>,
services: Arc<OnceServices>,
bad_event_ratelimiter: Arc<RwLock<HashMap<OwnedEventId, (Instant, u32)>>>,
db: Data,
}Fields§
§mutex_federation: MutexMap<OwnedRoomId, ()>§services: Arc<OnceServices>§bad_event_ratelimiter: Arc<RwLock<HashMap<OwnedEventId, (Instant, u32)>>>§db: DataImplementations§
Source§impl Service
impl Service
Sourcepub(super) async fn fetch_auth<'a, Events>(
&self,
origin: &ServerName,
room_id: &RoomId,
events: Events,
room_version: &RoomVersionId,
recursion_level: usize,
) -> Vec<(PduEvent, Option<CanonicalJsonObject>)>
pub(super) async fn fetch_auth<'a, Events>( &self, origin: &ServerName, room_id: &RoomId, events: Events, room_version: &RoomVersionId, recursion_level: usize, ) -> Vec<(PduEvent, Option<CanonicalJsonObject>)>
Find the event and auth it. Once the event is validated (steps 1 - 8) it is appended to the outliers Tree.
Returns pdu and if we fetched it over federation the raw json.
a. Look in the main timeline (pduid_pdu tree) b. Look at outlier pdu tree c. Ask origin server over federation d. TODO: Ask other servers over federation?
Source§impl Service
impl Service
async fn fetch_auth_chain( &self, origin: &ServerName, _room_id: &RoomId, event_id: &EventId, room_version: &RoomVersionId, ) -> (OwnedEventId, Option<PduEvent>, Vec<(OwnedEventId, CanonicalJsonObject)>)
Source§impl Service
impl Service
pub(super) async fn fetch_prev<'a, Events>( &self, origin: &ServerName, room_id: &RoomId, initial_set: Events, room_version: &RoomVersionId, recursion_level: usize, first_ts_in_room: MilliSecondsSinceUnixEpoch, ) -> Result<(Vec<OwnedEventId>, HashMap<OwnedEventId, (PduEvent, CanonicalJsonObject)>)>
Source§impl Service
impl Service
Sourcepub(super) async fn fetch_state(
&self,
origin: &ServerName,
room_id: &RoomId,
event_id: &EventId,
room_version: &RoomVersionId,
recursion_level: usize,
create_event_id: &EventId,
) -> Result<Option<HashMap<u64, OwnedEventId>>>
pub(super) async fn fetch_state( &self, origin: &ServerName, room_id: &RoomId, event_id: &EventId, room_version: &RoomVersionId, recursion_level: usize, create_event_id: &EventId, ) -> Result<Option<HashMap<u64, OwnedEventId>>>
Call /state_ids to find out what the state at this pdu is. We trust the server’s response to some extend (sic), but we still do a lot of checks on the events
Source§impl Service
impl Service
Sourcepub async fn handle_incoming_pdu<'a>(
&'a self,
origin: &'a ServerName,
room_id: &'a RoomId,
event_id: &'a EventId,
pdu: CanonicalJsonObject,
is_timeline_event: bool,
) -> Result<Option<(RawPduId, bool)>>
pub async fn handle_incoming_pdu<'a>( &'a self, origin: &'a ServerName, room_id: &'a RoomId, event_id: &'a EventId, pdu: CanonicalJsonObject, is_timeline_event: bool, ) -> Result<Option<(RawPduId, bool)>>
When receiving an event one needs to: 0. Check the server is in the room
- Skip the PDU if we already know about it 1.1. Remove unsigned field
- Check signatures, otherwise drop
- Check content hash, redact if doesn’t match
- Fetch any missing auth events doing all checks listed here starting at 1. These are not timeline events
- Reject “due to auth events” if can’t get all the auth events or some of the auth events are also rejected “due to auth events”
- Reject “due to auth events” if the event doesn’t pass auth based on the auth events
- Persist this event as an outlier
- If not timeline event: stop
- Fetch any missing prev events doing all checks listed here starting at 1. These are timeline events
- Fetch missing state and auth chain events by calling
/state_idsat backwards extremities doing all the checks in this list starting at- These are not timeline events
- Check the auth of the event passes based on the state of the event
- Ensure that the state is derived from the previous current state (i.e. we calculated by doing state res where one of the inputs was a previously trusted set of state, don’t just trust a set of state we got from a remote)
- Use state resolution to find new room state
- Check if the event passes auth based on the “current state” of the room, if not soft fail it
Source§impl Service
impl Service
pub(super) async fn handle_prev_pdu( &self, origin: &ServerName, room_id: &RoomId, event_id: &EventId, eventid_info: Option<(PduEvent, CanonicalJsonObject)>, room_version: &RoomVersionId, recursion_level: usize, first_ts_in_room: MilliSecondsSinceUnixEpoch, prev_id: &EventId, create_event_id: &EventId, ) -> Result<Option<(RawPduId, bool)>>
Source§impl Service
impl Service
pub async fn parse_incoming_pdu( &self, pdu: &RawJsonValue, ) -> Result<(OwnedRoomId, OwnedEventId, CanonicalJsonObject)>
Source§impl Service
impl Service
fn cache_policy_refused(&self, event_id: &EventId)
Source§impl Service
impl Service
async fn cached_policy_state( &self, event_id: &EventId, ) -> Option<PolicySigState>
Source§impl Service
impl Service
Sourcepub async fn lookup_policy_server(
&self,
room_id: &RoomId,
) -> Option<RoomPolicyEventContent>
pub async fn lookup_policy_server( &self, room_id: &RoomId, ) -> Option<RoomPolicyEventContent>
Returns the room’s policy event content when a policy server is in effect:
state event present (stable m.room.policy, falling back to MSC4284’s
unstable org.matrix.msc4284.policy), parses cleanly under either the
stable public_keys map or the unstable singular public_key field, and
the via server has a joined user in the room. Any failure returns None,
signalling “no policy server configured” so the caller skips the gate
entirely.
Source§impl Service
impl Service
Sourcepub async fn sign_outgoing_pdu<E>(
&self,
pdu_json: &mut CanonicalJsonObject,
pdu: &E,
) -> Resultwhere
E: Event,
pub async fn sign_outgoing_pdu<E>(
&self,
pdu_json: &mut CanonicalJsonObject,
pdu: &E,
) -> Resultwhere
E: Event,
MSC4284: ask the room’s policy server to sign an outgoing event. The
signature is folded into pdu_json["signatures"] so it persists with the
event and federates transitively to other servers in the room. Returns
Forbidden when the policy server explicitly refuses; network errors and
timeouts fail open with a warn log.
Source§impl Service
impl Service
Sourceasync fn fetch_policy_signature(
&self,
policy: &RoomPolicyEventContent,
pdu_json: &CanonicalJsonObject,
room_version: &RoomVersionId,
) -> FetchOutcome
async fn fetch_policy_signature( &self, policy: &RoomPolicyEventContent, pdu_json: &CanonicalJsonObject, room_version: &RoomVersionId, ) -> FetchOutcome
Calls the policy server’s /sign endpoint. The classification of the
response (Signed / Refused / RateLimited / FailOpen) lets each
caller choose its own reaction.
Source§impl Service
impl Service
Sourcepub async fn verify_or_fetch_inbound_policy_signature<E>(
&self,
pdu_json: &mut CanonicalJsonObject,
pdu: &E,
) -> PolicyCheckwhere
E: Event,
pub async fn verify_or_fetch_inbound_policy_signature<E>(
&self,
pdu_json: &mut CanonicalJsonObject,
pdu: &E,
) -> PolicyCheckwhere
E: Event,
MSC4284: verify the inbound PDU’s policy server signature; if missing, ask
the policy server to sign and fold the result in. Mirrors
check_inbound_policy_signature but upgrades Missing to Pass (fetched
and verified, or fail-open on network error/timeout) or Invalid
(refused).
Source§impl Service
impl Service
Sourceasync fn fetch_inbound_policy_signature<E>(
&self,
pdu_json: &mut CanonicalJsonObject,
pdu: &E,
) -> PolicyCheckwhere
E: Event,
async fn fetch_inbound_policy_signature<E>(
&self,
pdu_json: &mut CanonicalJsonObject,
pdu: &E,
) -> PolicyCheckwhere
E: Event,
MSC4284: when an inbound PDU has no policy server signature, ask the
policy server to sign on the originator’s behalf; fold the returned
signature into pdu_json so it persists with the event and federates
onward. Cached refusals short-circuit to Invalid; cached backoffs (or
fresh 429s) fail open as Pass until the deadline. Forbidden from the
policy server maps to Invalid. Network errors and timeouts fail open
with a warn log, mapped to Pass since the next server in the room is
likely to retry.
Source§impl Service
impl Service
Sourcepub async fn check_inbound_policy_signature<E>(
&self,
pdu_json: &CanonicalJsonObject,
pdu: &E,
) -> PolicyCheckwhere
E: Event,
pub async fn check_inbound_policy_signature<E>(
&self,
pdu_json: &CanonicalJsonObject,
pdu: &E,
) -> PolicyCheckwhere
E: Event,
MSC4284: verify the policy server signature on an inbound PDU. Returns
NotApplicable for rooms without a configured policy server (the gate is
skipped); Pass when the signature verifies; Missing when no signature
is present for the configured server; Invalid when the signature is
present but cryptographic verification fails.
Source§impl Service
impl Service
pub async fn resolve_state( &self, room_id: &RoomId, room_version: &RoomVersionId, incoming_state: HashMap<u64, OwnedEventId>, ) -> Result<Arc<CompressedState>>
Source§impl Service
impl Service
pub(super) async fn state_resolution<StateSets, AuthSets>( &self, _room_id: &RoomId, room_version: &RoomVersionId, state_sets: StateSets, auth_chains: AuthSets, ) -> Result<StateMap<OwnedEventId>>
Source§impl Service
impl Service
async fn state_at_incoming_fork<Pdu>(
&self,
room_id: &RoomId,
room_version: &RoomVersionId,
sstatehash: ShortStateHash,
prev_event: Pdu,
) -> Result<(StateMap<OwnedEventId>, AuthSet<OwnedEventId>)>where
Pdu: Event,
Trait Implementations§
Source§impl Service for Service
impl Service for Service
Source§fn build(args: &Args<'_>) -> Result<Arc<Self>>
fn build(args: &Args<'_>) -> Result<Arc<Self>>
Source§fn memory_usage<'life0, 'life1, 'async_trait>(
&'life0 self,
out: &'life1 mut (dyn Write + Send),
) -> Pin<Box<dyn Future<Output = Result> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn memory_usage<'life0, 'life1, 'async_trait>(
&'life0 self,
out: &'life1 mut (dyn Write + Send),
) -> Pin<Box<dyn Future<Output = Result> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn clear_cache<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn clear_cache<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn name(&self) -> &str
fn name(&self) -> &str
crate::service::make_name(std::module_path!())Source§fn worker<'async_trait>(
self: Arc<Self>,
) -> Pin<Box<dyn Future<Output = Result> + Send + 'async_trait>>where
Self: 'async_trait,
fn worker<'async_trait>(
self: Arc<Self>,
) -> Pin<Box<dyn Future<Output = Result> + Send + 'async_trait>>where
Self: 'async_trait,
Source§fn interrupt<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn interrupt<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn unconstrained(&self) -> bool
fn unconstrained(&self) -> bool
Auto Trait Implementations§
impl Freeze for Service
impl !RefUnwindSafe for Service
impl Send for Service
impl Sync for Service
impl Unpin for Service
impl UnsafeUnpin for Service
impl !UnwindSafe for Service
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> ExpectInto for T
impl<T> ExpectInto for T
fn expect_into<Dst>(self) -> Dst
Source§impl<T> Expected for T
impl<T> Expected for T
fn expected_add(self, rhs: Self) -> Selfwhere
Self: Sized + CheckedAdd,
fn expected_sub(self, rhs: Self) -> Selfwhere
Self: Sized + CheckedSub,
fn expected_mul(self, rhs: Self) -> Selfwhere
Self: Sized + CheckedMul,
fn expected_div(self, rhs: Self) -> Selfwhere
Self: Sized + CheckedDiv,
fn expected_rem(self, rhs: Self) -> Selfwhere
Self: Sized + CheckedRem,
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling [Attribute] value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi [Quirk] value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the [Condition] value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> ServiceExt for T
impl<T> ServiceExt for T
§fn add_extension<T>(self, value: T) -> AddExtension<Self, T>where
Self: Sized,
fn add_extension<T>(self, value: T) -> AddExtension<Self, T>where
Self: Sized,
§fn compression(self) -> Compression<Self>where
Self: Sized,
fn compression(self) -> Compression<Self>where
Self: Sized,
§fn decompression(self) -> Decompression<Self>where
Self: Sized,
fn decompression(self) -> Decompression<Self>where
Self: Sized,
§fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
§fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
§fn follow_redirects(self) -> FollowRedirect<Self>where
Self: Sized,
fn follow_redirects(self) -> FollowRedirect<Self>where
Self: Sized,
§fn sensitive_headers(
self,
headers: impl IntoIterator<Item = HeaderName>,
) -> SetSensitiveRequestHeaders<SetSensitiveResponseHeaders<Self>>where
Self: Sized,
fn sensitive_headers(
self,
headers: impl IntoIterator<Item = HeaderName>,
) -> SetSensitiveRequestHeaders<SetSensitiveResponseHeaders<Self>>where
Self: Sized,
§fn sensitive_request_headers(
self,
headers: impl IntoIterator<Item = HeaderName>,
) -> SetSensitiveRequestHeaders<Self>where
Self: Sized,
fn sensitive_request_headers(
self,
headers: impl IntoIterator<Item = HeaderName>,
) -> SetSensitiveRequestHeaders<Self>where
Self: Sized,
§fn sensitive_response_headers(
self,
headers: impl IntoIterator<Item = HeaderName>,
) -> SetSensitiveResponseHeaders<Self>where
Self: Sized,
fn sensitive_response_headers(
self,
headers: impl IntoIterator<Item = HeaderName>,
) -> SetSensitiveResponseHeaders<Self>where
Self: Sized,
§fn override_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
fn override_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
§fn append_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
fn append_request_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
§fn insert_request_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
fn insert_request_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetRequestHeader<Self, M>where
Self: Sized,
§fn override_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
fn override_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
§fn append_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
fn append_response_header<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
§fn insert_response_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
fn insert_response_header_if_not_present<M>(
self,
header_name: HeaderName,
make: M,
) -> SetResponseHeader<Self, M>where
Self: Sized,
§fn catch_panic(self) -> CatchPanic<Self, DefaultResponseForPanic>where
Self: Sized,
fn catch_panic(self) -> CatchPanic<Self, DefaultResponseForPanic>where
Self: Sized,
500 Internal Server responses. Read more