pub struct MembersV1 {
pub members: Vec<AuthorizedMember>,
}Fields§
§members: Vec<AuthorizedMember>Implementations§
Source§impl MembersV1
impl MembersV1
Sourcepub fn is_inviter_of(
&self,
member_id: MemberId,
target_id: MemberId,
params: &ChatRoomParametersV1,
) -> bool
pub fn is_inviter_of( &self, member_id: MemberId, target_id: MemberId, params: &ChatRoomParametersV1, ) -> bool
Returns true if the given member_id invited the target_id, properly handling both regular members and the room owner. Use this instead of checking the members list directly.
Sourcepub fn members_by_member_id(&self) -> HashMap<MemberId, &AuthorizedMember>
pub fn members_by_member_id(&self) -> HashMap<MemberId, &AuthorizedMember>
Note: doesn’t include owner
Sourcepub fn has_banned_members(
&self,
bans_v1: &BansV1,
parameters: &ChatRoomParametersV1,
) -> bool
pub fn has_banned_members( &self, bans_v1: &BansV1, parameters: &ChatRoomParametersV1, ) -> bool
Checks if there are any banned members or members downstream of banned members in the invite chain
Sourcepub fn banned_member_ids(
&self,
bans_v1: &BansV1,
member_info: &MemberInfoV1,
parameters: &ChatRoomParametersV1,
) -> HashSet<MemberId>
pub fn banned_member_ids( &self, bans_v1: &BansV1, member_info: &MemberInfoV1, parameters: &ChatRoomParametersV1, ) -> HashSet<MemberId>
The set of member ids that must be removed because they are the target of (or downstream of the target of) a currently-authorized ban.
This is the deputy-aware member cascade (#410). It is a pure function
of the converged (members + member_info deputies + bans) state, so
every peer computes the same removal set regardless of the order deltas
arrived in — which is why enforcement lives here / in
ChatRoomStateV1::post_apply_cleanup, NOT in verify (flipping ban
validity inside verify would make it non-stable across deputy-state
changes and break convergence). Bans themselves are never pruned by this
(they remain an add-only CRDT tombstone set); revoking a deputy simply
makes their bans stop being authorized, so the previously-removed
members are no longer in this set and can rejoin.
Whether banner is currently authorized to ban target (#410).
Grants are checked in priority order. The ABSOLUTE grants come FIRST so
they cannot be stripped by the target “self-immunizing” (a spammer
listing the moderator in their OWN deputies to make the mod’s ban go
inert):
banneris the room owner — absolute.banneris a STRICT ancestor oftargetin the invite tree (“you can ban your own subtree”) — absolute.banneris an owner-appointed global moderator (owner’sdeputieslistbanner) — absolute (the owner’s subtree is everyone).
Only then the deputy-derived branch (authority via a NON-owner ancestor),
which the guardrail applies to:
4. Guardrail (“cannot ban the member who deputized you”): if target
currently lists banner in target.deputies, DENY — a deputy cannot
ban a fellow deputizer. Checked AFTER the absolute grants, so a genuine
ancestor / owner-appointed mod keeps authority even if the target
deputizes them.
5. Some strict NON-owner ancestor A of target lists banner in
A.deputies — deputy authority scoped to A’s subtree.
There is no transitive re-deputization: a deputy’s own deputies only
grant authority over the deputy’s OWN subtree (where the deputy is a
genuine ancestor), never over a subtree they merely hold as a deputy.
Sourcepub fn get_invite_chain(
&self,
member: &AuthorizedMember,
parameters: &ChatRoomParametersV1,
) -> Result<Vec<AuthorizedMember>, String>
pub fn get_invite_chain( &self, member: &AuthorizedMember, parameters: &ChatRoomParametersV1, ) -> Result<Vec<AuthorizedMember>, String>
Get the full invite chain with Ed25519 signature verification at each link.
This is the authoritative verification used by verify().
Trait Implementations§
Source§impl ComposableState for MembersV1
impl ComposableState for MembersV1
type ParentState = ChatRoomStateV1
type Summary = BTreeSet<MemberId>
type Delta = MembersDelta
type Parameters = ChatRoomParametersV1
fn verify( &self, parent_state: &Self::ParentState, parameters: &Self::Parameters, ) -> Result<(), String>
fn summarize( &self, _parent_state: &Self::ParentState, _parameters: &Self::Parameters, ) -> Self::Summary
fn delta( &self, _parent_state: &Self::ParentState, _parameters: &Self::Parameters, old_state_summary: &Self::Summary, ) -> Option<Self::Delta>
Source§fn apply_delta(
&mut self,
parent_state: &Self::ParentState,
parameters: &Self::Parameters,
delta: &Option<Self::Delta>,
) -> Result<(), String>
fn apply_delta( &mut self, parent_state: &Self::ParentState, parameters: &Self::Parameters, delta: &Option<Self::Delta>, ) -> Result<(), String>
delta to the current state. Read more