Continue to update to keep compatibility with conduit
This commit is contained in:
parent
484f48dc41
commit
6e0edce35a
@ -10,7 +10,11 @@ use ruma::{
|
|||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::{room_version::RoomVersion, state_event::StateEvent, StateMap};
|
use crate::{
|
||||||
|
room_version::RoomVersion,
|
||||||
|
state_event::{Requester, StateEvent},
|
||||||
|
StateMap,
|
||||||
|
};
|
||||||
|
|
||||||
/// Represents the 3 event redaction outcomes.
|
/// Represents the 3 event redaction outcomes.
|
||||||
pub enum RedactAllowed {
|
pub enum RedactAllowed {
|
||||||
@ -178,7 +182,7 @@ pub fn auth_check(
|
|||||||
if event.kind() == EventType::RoomMember {
|
if event.kind() == EventType::RoomMember {
|
||||||
tracing::info!("starting m.room.member check");
|
tracing::info!("starting m.room.member check");
|
||||||
|
|
||||||
if !is_membership_change_allowed(event, &auth_events)? {
|
if !is_membership_change_allowed(event.to_requester(), &auth_events)? {
|
||||||
return Some(false);
|
return Some(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,21 +253,21 @@ pub fn can_federate(auth_events: &StateMap<StateEvent>) -> bool {
|
|||||||
|
|
||||||
/// Dose the user who sent this member event have required power levels to do so.
|
/// Dose the user who sent this member event have required power levels to do so.
|
||||||
pub fn is_membership_change_allowed(
|
pub fn is_membership_change_allowed(
|
||||||
event: &StateEvent,
|
user: Requester<'_>,
|
||||||
auth_events: &StateMap<StateEvent>,
|
auth_events: &StateMap<StateEvent>,
|
||||||
) -> Option<bool> {
|
) -> Option<bool> {
|
||||||
let content = event
|
let content =
|
||||||
.deserialize_content::<room::member::MemberEventContent>()
|
// TODO return error
|
||||||
.ok()
|
serde_json::from_str::<room::member::MemberEventContent>(&user.content.to_string()).ok()?;
|
||||||
.unwrap();
|
|
||||||
let membership = content.membership;
|
let membership = content.membership;
|
||||||
|
|
||||||
// check if this is the room creator joining
|
// check if this is the room creator joining
|
||||||
if event.prev_event_ids().len() == 1 && membership == MembershipState::Join {
|
if user.prev_event_ids.len() == 1 && membership == MembershipState::Join {
|
||||||
if let Some(create) = auth_events.get(&(EventType::RoomCreate, Some("".into()))) {
|
if let Some(create) = auth_events.get(&(EventType::RoomCreate, Some("".into()))) {
|
||||||
if let Ok(create_ev) = create.deserialize_content::<room::create::CreateEventContent>()
|
if let Ok(create_ev) = create.deserialize_content::<room::create::CreateEventContent>()
|
||||||
{
|
{
|
||||||
if event.state_key() == Some(create_ev.creator.to_string()) {
|
if user.state_key == Some(create_ev.creator.to_string()) {
|
||||||
tracing::debug!("m.room.member event allowed via m.room.create");
|
tracing::debug!("m.room.member event allowed via m.room.create");
|
||||||
return Some(true);
|
return Some(true);
|
||||||
}
|
}
|
||||||
@ -271,16 +275,16 @@ pub fn is_membership_change_allowed(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_user_id = UserId::try_from(event.state_key().unwrap()).ok().unwrap();
|
let target_user_id = UserId::try_from(user.state_key.as_deref().unwrap())
|
||||||
|
.ok()
|
||||||
|
.unwrap();
|
||||||
// if the server_names are different and federation is NOT allowed
|
// if the server_names are different and federation is NOT allowed
|
||||||
if event.room_id().unwrap().server_name() != target_user_id.server_name()
|
if user.room_id.server_name() != target_user_id.server_name() && !can_federate(auth_events) {
|
||||||
&& !can_federate(auth_events)
|
|
||||||
{
|
|
||||||
tracing::warn!("server cannot federate");
|
tracing::warn!("server cannot federate");
|
||||||
return Some(false);
|
return Some(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = (EventType::RoomMember, Some(event.sender().to_string()));
|
let key = (EventType::RoomMember, Some(user.sender.to_string()));
|
||||||
let caller = auth_events.get(&key);
|
let caller = auth_events.get(&key);
|
||||||
|
|
||||||
let caller_in_room = caller.is_some() && check_membership(caller, MembershipState::Join);
|
let caller_in_room = caller.is_some() && check_membership(caller, MembershipState::Join);
|
||||||
@ -299,12 +303,11 @@ pub fn is_membership_change_allowed(
|
|||||||
if let Some(jr) = join_rules_event {
|
if let Some(jr) = join_rules_event {
|
||||||
join_rule = jr
|
join_rule = jr
|
||||||
.deserialize_content::<room::join_rules::JoinRulesEventContent>()
|
.deserialize_content::<room::join_rules::JoinRulesEventContent>()
|
||||||
.ok()
|
.ok()? // TODO these are errors? and should be treated as a DB failure?
|
||||||
.unwrap() // TODO these are errors? and should be treated as a DB failure?
|
|
||||||
.join_rule;
|
.join_rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
let user_level = get_user_power_level(event.sender(), auth_events);
|
let user_level = get_user_power_level(user.sender, auth_events);
|
||||||
let target_level = get_user_power_level(&target_user_id, auth_events);
|
let target_level = get_user_power_level(&target_user_id, auth_events);
|
||||||
|
|
||||||
// synapse has a not "what to do for default here 50"
|
// synapse has a not "what to do for default here 50"
|
||||||
@ -321,14 +324,14 @@ pub fn is_membership_change_allowed(
|
|||||||
"membership": membership,
|
"membership": membership,
|
||||||
"join_rule": join_rule,
|
"join_rule": join_rule,
|
||||||
"target_user_id": target_user_id,
|
"target_user_id": target_user_id,
|
||||||
"event.user_id": event.sender(),
|
"event.user_id": user.sender,
|
||||||
}))
|
}))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if membership == MembershipState::Invite && content.third_party_invite.is_some() {
|
if membership == MembershipState::Invite && content.third_party_invite.is_some() {
|
||||||
// TODO this is unimpled
|
// TODO this is unimpled
|
||||||
if !verify_third_party_invite(event, auth_events) {
|
if !verify_third_party_invite(&user, auth_events) {
|
||||||
tracing::warn!("not invited to this room",);
|
tracing::warn!("not invited to this room",);
|
||||||
return Some(false);
|
return Some(false);
|
||||||
}
|
}
|
||||||
@ -341,19 +344,14 @@ pub fn is_membership_change_allowed(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if membership != MembershipState::Join {
|
if membership != MembershipState::Join {
|
||||||
if caller_invited
|
if caller_invited && membership == MembershipState::Leave && &target_user_id == user.sender
|
||||||
&& membership == MembershipState::Leave
|
|
||||||
&& &target_user_id == event.sender()
|
|
||||||
{
|
{
|
||||||
tracing::warn!("join event succeded");
|
tracing::warn!("join event succeded");
|
||||||
return Some(true);
|
return Some(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !caller_in_room {
|
if !caller_in_room {
|
||||||
tracing::warn!(
|
tracing::warn!("user is not in this room {}", user.room_id.as_str(),);
|
||||||
"user is not in this room {}",
|
|
||||||
event.room_id().unwrap().as_str(),
|
|
||||||
);
|
|
||||||
return Some(false); // caller is not joined
|
return Some(false); // caller is not joined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -372,7 +370,7 @@ pub fn is_membership_change_allowed(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if membership == MembershipState::Join {
|
} else if membership == MembershipState::Join {
|
||||||
if event.sender() != &target_user_id {
|
if user.sender != &target_user_id {
|
||||||
tracing::warn!("cannot force another user to join");
|
tracing::warn!("cannot force another user to join");
|
||||||
return Some(false); // cannot force another user to join
|
return Some(false); // cannot force another user to join
|
||||||
} else if target_banned {
|
} else if target_banned {
|
||||||
@ -397,7 +395,7 @@ pub fn is_membership_change_allowed(
|
|||||||
if target_banned && user_level < ban_level {
|
if target_banned && user_level < ban_level {
|
||||||
tracing::warn!("not enough power to unban");
|
tracing::warn!("not enough power to unban");
|
||||||
return Some(false); // you cannot unban this user
|
return Some(false); // you cannot unban this user
|
||||||
} else if &target_user_id != event.sender() {
|
} else if &target_user_id != user.sender {
|
||||||
let kick_level = get_named_level(auth_events, "kick", 50);
|
let kick_level = get_named_level(auth_events, "kick", 50);
|
||||||
|
|
||||||
if user_level < kick_level || user_level <= target_level {
|
if user_level < kick_level || user_level <= target_level {
|
||||||
@ -734,6 +732,9 @@ pub fn get_send_level(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TODO this is unimplemented
|
/// TODO this is unimplemented
|
||||||
pub fn verify_third_party_invite(_event: &StateEvent, _auth_events: &StateMap<StateEvent>) -> bool {
|
pub fn verify_third_party_invite(
|
||||||
|
_event: &Requester<'_>,
|
||||||
|
_auth_events: &StateMap<StateEvent>,
|
||||||
|
) -> bool {
|
||||||
unimplemented!("impl third party invites")
|
unimplemented!("impl third party invites")
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ mod state_store;
|
|||||||
|
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use event_auth::{auth_check, auth_types_for_event};
|
pub use event_auth::{auth_check, auth_types_for_event};
|
||||||
pub use state_event::StateEvent;
|
pub use state_event::{Requester, StateEvent};
|
||||||
pub use state_store::StateStore;
|
pub use state_store::StateStore;
|
||||||
|
|
||||||
// We want to yield to the reactor occasionally during state res when dealing
|
// We want to yield to the reactor occasionally during state res when dealing
|
||||||
|
@ -13,6 +13,14 @@ use serde::{de, Serialize};
|
|||||||
use serde_json::value::RawValue as RawJsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
pub struct Requester<'a> {
|
||||||
|
pub prev_event_ids: Vec<EventId>,
|
||||||
|
pub room_id: &'a RoomId,
|
||||||
|
pub content: &'a serde_json::Value,
|
||||||
|
pub state_key: Option<String>,
|
||||||
|
pub sender: &'a UserId,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum StateEvent {
|
pub enum StateEvent {
|
||||||
@ -21,6 +29,16 @@ pub enum StateEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StateEvent {
|
impl StateEvent {
|
||||||
|
pub fn to_requester(&self) -> Requester<'_> {
|
||||||
|
Requester {
|
||||||
|
prev_event_ids: self.prev_event_ids(),
|
||||||
|
room_id: self.room_id().unwrap(),
|
||||||
|
content: self.content(),
|
||||||
|
state_key: self.state_key(),
|
||||||
|
sender: self.sender(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_power_event(&self) -> bool {
|
pub fn is_power_event(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Full(any_event) => match any_event {
|
Self::Full(any_event) => match any_event {
|
||||||
|
@ -28,7 +28,7 @@ static LOGGER: Once = Once::new();
|
|||||||
static mut SERVER_TIMESTAMP: i32 = 0;
|
static mut SERVER_TIMESTAMP: i32 = 0;
|
||||||
|
|
||||||
fn do_check(events: &[StateEvent], edges: Vec<Vec<EventId>>, expected_state_ids: Vec<EventId>) {
|
fn do_check(events: &[StateEvent], edges: Vec<Vec<EventId>>, expected_state_ids: Vec<EventId>) {
|
||||||
// to activate logging use `RUST_LOG=debug cargo t one_test_only`
|
// to activate logging use `RUST_LOG=debug cargo t`
|
||||||
let _ = LOGGER.call_once(|| {
|
let _ = LOGGER.call_once(|| {
|
||||||
tracer::fmt()
|
tracer::fmt()
|
||||||
.with_env_filter(tracer::EnvFilter::from_default_env())
|
.with_env_filter(tracer::EnvFilter::from_default_env())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user