Merge pull request 'Fix clippy warnings and run rustfmt' (#163) from DevinR528/conduit:clippy-fix2 into master
Reviewed-on: https://git.koesters.xyz/timo/conduit/pulls/163 Reviewed-by: Timo Kösters <timo@koesters.xyz>next
commit
c824652de6
|
@ -4,7 +4,9 @@ use std::{
|
||||||
time::{Duration, SystemTime},
|
time::{Duration, SystemTime},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{utils, ConduitResult, Database, Error, Ruma};
|
use crate::{
|
||||||
|
database::media::FileMeta, pdu::PduBuilder, utils, ConduitResult, Database, Error, Ruma,
|
||||||
|
};
|
||||||
use keys::{upload_signatures, upload_signing_keys};
|
use keys::{upload_signatures, upload_signing_keys};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
|
||||||
|
@ -230,7 +232,7 @@ pub fn register_route(
|
||||||
Ok(register::Response {
|
Ok(register::Response {
|
||||||
access_token: Some(token),
|
access_token: Some(token),
|
||||||
user_id,
|
user_id,
|
||||||
device_id: Some(device_id.into()),
|
device_id: Some(device_id),
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
@ -257,11 +259,22 @@ pub fn login_route(
|
||||||
if let (login::UserInfo::MatrixId(username), login::LoginInfo::Password { password }) =
|
if let (login::UserInfo::MatrixId(username), login::LoginInfo::Password { password }) =
|
||||||
(body.user.clone(), body.login_info.clone())
|
(body.user.clone(), body.login_info.clone())
|
||||||
{
|
{
|
||||||
let user_id = UserId::parse_with_server_name(username, db.globals.server_name()).map_err(|_| Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."))?;
|
let user_id = UserId::parse_with_server_name(username, db.globals.server_name())
|
||||||
let hash = db.users.password_hash(&user_id)?.ok_or(Error::BadRequest(ErrorKind::Forbidden, "Wrong username or password."))?;
|
.map_err(|_| Error::BadRequest(
|
||||||
|
ErrorKind::InvalidUsername,
|
||||||
|
"Username is invalid."
|
||||||
|
))?;
|
||||||
|
let hash = db.users.password_hash(&user_id)?
|
||||||
|
.ok_or(Error::BadRequest(
|
||||||
|
ErrorKind::Forbidden,
|
||||||
|
"Wrong username or password."
|
||||||
|
))?;
|
||||||
|
|
||||||
if hash.is_empty() {
|
if hash.is_empty() {
|
||||||
return Err(Error::BadRequest(ErrorKind::UserDeactivated, "The user has been deactivated"));
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::UserDeactivated,
|
||||||
|
"The user has been deactivated"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash_matches =
|
let hash_matches =
|
||||||
|
@ -298,7 +311,7 @@ pub fn login_route(
|
||||||
user_id,
|
user_id,
|
||||||
access_token: token,
|
access_token: token,
|
||||||
home_server: Some(db.globals.server_name().to_owned()),
|
home_server: Some(db.globals.server_name().to_owned()),
|
||||||
device_id: device_id.into(),
|
device_id,
|
||||||
well_known: None,
|
well_known: None,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
@ -464,13 +477,15 @@ pub fn deactivate_route(
|
||||||
};
|
};
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(event).expect("event is valid, we just created it"),
|
event_type: EventType::RoomMember,
|
||||||
None,
|
content: serde_json::to_value(event).expect("event is valid, we just created it"),
|
||||||
Some(sender_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(sender_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -649,30 +664,32 @@ pub fn set_displayname_route(
|
||||||
for room_id in db.rooms.rooms_joined(&sender_id) {
|
for room_id in db.rooms.rooms_joined(&sender_id) {
|
||||||
let room_id = room_id?;
|
let room_id = room_id?;
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(ruma::events::room::member::MemberEventContent {
|
event_type: EventType::RoomMember,
|
||||||
displayname: body.displayname.clone(),
|
content: serde_json::to_value(ruma::events::room::member::MemberEventContent {
|
||||||
..serde_json::from_value::<Raw<_>>(
|
displayname: body.displayname.clone(),
|
||||||
db.rooms
|
..serde_json::from_value::<Raw<_>>(
|
||||||
.room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())?
|
db.rooms
|
||||||
.ok_or_else(|| {
|
.room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())?
|
||||||
Error::bad_database(
|
.ok_or_else(|| {
|
||||||
"Tried to send displayname update for user not in the room.",
|
Error::bad_database(
|
||||||
)
|
"Tried to send displayname update for user not in the room.",
|
||||||
})?
|
)
|
||||||
.content
|
})?
|
||||||
.clone(),
|
.content
|
||||||
)
|
.clone(),
|
||||||
.map_err(|_| Error::bad_database("Database contains invalid PDU."))?
|
)
|
||||||
.deserialize()
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.map_err(|_| Error::bad_database("Database contains invalid PDU."))?
|
.deserialize()
|
||||||
})
|
.map_err(|_| Error::bad_database("Database contains invalid PDU."))?
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some(sender_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(sender_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -745,30 +762,32 @@ pub fn set_avatar_url_route(
|
||||||
for room_id in db.rooms.rooms_joined(&sender_id) {
|
for room_id in db.rooms.rooms_joined(&sender_id) {
|
||||||
let room_id = room_id?;
|
let room_id = room_id?;
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(ruma::events::room::member::MemberEventContent {
|
event_type: EventType::RoomMember,
|
||||||
avatar_url: body.avatar_url.clone(),
|
content: serde_json::to_value(ruma::events::room::member::MemberEventContent {
|
||||||
..serde_json::from_value::<Raw<_>>(
|
avatar_url: body.avatar_url.clone(),
|
||||||
db.rooms
|
..serde_json::from_value::<Raw<_>>(
|
||||||
.room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())?
|
db.rooms
|
||||||
.ok_or_else(|| {
|
.room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())?
|
||||||
Error::bad_database(
|
.ok_or_else(|| {
|
||||||
"Tried to send avatar url update for user not in the room.",
|
Error::bad_database(
|
||||||
)
|
"Tried to send avatar url update for user not in the room.",
|
||||||
})?
|
)
|
||||||
.content
|
})?
|
||||||
.clone(),
|
.content
|
||||||
)
|
.clone(),
|
||||||
.map_err(|_| Error::bad_database("Database contains invalid PDU."))?
|
)
|
||||||
.deserialize()
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.map_err(|_| Error::bad_database("Database contains invalid PDU."))?
|
.deserialize()
|
||||||
})
|
.map_err(|_| Error::bad_database("Database contains invalid PDU."))?
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some(sender_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(sender_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1281,32 +1300,36 @@ pub fn create_room_route(
|
||||||
|
|
||||||
// 1. The room create event
|
// 1. The room create event
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomCreate,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(content).expect("event is valid, we just created it"),
|
event_type: EventType::RoomCreate,
|
||||||
None,
|
content: serde_json::to_value(content).expect("event is valid, we just created it"),
|
||||||
Some("".to_owned()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// 2. Let the room creator join
|
// 2. Let the room creator join
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(member::MemberEventContent {
|
event_type: EventType::RoomMember,
|
||||||
membership: member::MembershipState::Join,
|
content: serde_json::to_value(member::MemberEventContent {
|
||||||
displayname: db.users.displayname(&sender_id)?,
|
membership: member::MembershipState::Join,
|
||||||
avatar_url: db.users.avatar_url(&sender_id)?,
|
displayname: db.users.displayname(&sender_id)?,
|
||||||
is_direct: body.is_direct,
|
avatar_url: db.users.avatar_url(&sender_id)?,
|
||||||
third_party_invite: None,
|
is_direct: body.is_direct,
|
||||||
})
|
third_party_invite: None,
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some(sender_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(sender_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1346,72 +1369,82 @@ pub fn create_room_route(
|
||||||
.expect("event is valid, we just created it")
|
.expect("event is valid, we just created it")
|
||||||
};
|
};
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomPowerLevels,
|
sender: sender_id.clone(),
|
||||||
power_levels_content,
|
event_type: EventType::RoomPowerLevels,
|
||||||
None,
|
content: power_levels_content,
|
||||||
Some("".to_owned()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// 4. Events set by preset
|
// 4. Events set by preset
|
||||||
// 4.1 Join Rules
|
// 4.1 Join Rules
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomJoinRules,
|
sender: sender_id.clone(),
|
||||||
match preset {
|
event_type: EventType::RoomJoinRules,
|
||||||
create_room::RoomPreset::PublicChat => serde_json::to_value(
|
content: match preset {
|
||||||
join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public),
|
create_room::RoomPreset::PublicChat => serde_json::to_value(
|
||||||
)
|
join_rules::JoinRulesEventContent::new(join_rules::JoinRule::Public),
|
||||||
.expect("event is valid, we just created it"),
|
)
|
||||||
// according to spec "invite" is the default
|
.expect("event is valid, we just created it"),
|
||||||
_ => serde_json::to_value(join_rules::JoinRulesEventContent::new(
|
// according to spec "invite" is the default
|
||||||
join_rules::JoinRule::Invite,
|
_ => serde_json::to_value(join_rules::JoinRulesEventContent::new(
|
||||||
))
|
join_rules::JoinRule::Invite,
|
||||||
.expect("event is valid, we just created it"),
|
))
|
||||||
|
.expect("event is valid, we just created it"),
|
||||||
|
},
|
||||||
|
unsigned: None,
|
||||||
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
},
|
},
|
||||||
None,
|
|
||||||
Some("".to_owned()),
|
|
||||||
None,
|
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// 4.2 History Visibility
|
// 4.2 History Visibility
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomHistoryVisibility,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(history_visibility::HistoryVisibilityEventContent::new(
|
event_type: EventType::RoomHistoryVisibility,
|
||||||
history_visibility::HistoryVisibility::Shared,
|
content: serde_json::to_value(history_visibility::HistoryVisibilityEventContent::new(
|
||||||
))
|
history_visibility::HistoryVisibility::Shared,
|
||||||
.expect("event is valid, we just created it"),
|
))
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some("".to_owned()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// 4.3 Guest Access
|
// 4.3 Guest Access
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomGuestAccess,
|
sender: sender_id.clone(),
|
||||||
match preset {
|
event_type: EventType::RoomGuestAccess,
|
||||||
create_room::RoomPreset::PublicChat => serde_json::to_value(
|
content: match preset {
|
||||||
guest_access::GuestAccessEventContent::new(guest_access::GuestAccess::Forbidden),
|
create_room::RoomPreset::PublicChat => {
|
||||||
)
|
serde_json::to_value(guest_access::GuestAccessEventContent::new(
|
||||||
.expect("event is valid, we just created it"),
|
guest_access::GuestAccess::Forbidden,
|
||||||
_ => serde_json::to_value(guest_access::GuestAccessEventContent::new(
|
))
|
||||||
guest_access::GuestAccess::CanJoin,
|
.expect("event is valid, we just created it")
|
||||||
))
|
}
|
||||||
.expect("event is valid, we just created it"),
|
_ => serde_json::to_value(guest_access::GuestAccessEventContent::new(
|
||||||
|
guest_access::GuestAccess::CanJoin,
|
||||||
|
))
|
||||||
|
.expect("event is valid, we just created it"),
|
||||||
|
},
|
||||||
|
unsigned: None,
|
||||||
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
},
|
},
|
||||||
None,
|
|
||||||
Some("".to_owned()),
|
|
||||||
None,
|
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1428,15 +1461,17 @@ pub fn create_room_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
event_type.clone(),
|
sender: sender_id.clone(),
|
||||||
serde_json::from_str(content.get()).map_err(|_| {
|
event_type: event_type.clone(),
|
||||||
Error::BadRequest(ErrorKind::BadJson, "Invalid initial_state content.")
|
content: serde_json::from_str(content.get()).map_err(|_| {
|
||||||
})?,
|
Error::BadRequest(ErrorKind::BadJson, "Invalid initial_state content.")
|
||||||
None,
|
})?,
|
||||||
state_key.clone(),
|
unsigned: None,
|
||||||
None,
|
state_key: state_key.clone(),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -1444,33 +1479,38 @@ pub fn create_room_route(
|
||||||
// 6. Events implied by name and topic
|
// 6. Events implied by name and topic
|
||||||
if let Some(name) = &body.name {
|
if let Some(name) = &body.name {
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomName,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(
|
event_type: EventType::RoomName,
|
||||||
name::NameEventContent::new(name.clone())
|
content: serde_json::to_value(
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid."))?,
|
name::NameEventContent::new(name.clone()).map_err(|_| {
|
||||||
)
|
Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.")
|
||||||
.expect("event is valid, we just created it"),
|
})?,
|
||||||
None,
|
)
|
||||||
Some("".to_owned()),
|
.expect("event is valid, we just created it"),
|
||||||
None,
|
unsigned: None,
|
||||||
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(topic) = &body.topic {
|
if let Some(topic) = &body.topic {
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomTopic,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(topic::TopicEventContent {
|
event_type: EventType::RoomTopic,
|
||||||
topic: topic.clone(),
|
content: serde_json::to_value(topic::TopicEventContent {
|
||||||
})
|
topic: topic.clone(),
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some("".to_owned()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some("".to_owned()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -1478,20 +1518,22 @@ pub fn create_room_route(
|
||||||
// 7. Events implied by invite (and TODO: invite_3pid)
|
// 7. Events implied by invite (and TODO: invite_3pid)
|
||||||
for user in &body.invite {
|
for user in &body.invite {
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(member::MemberEventContent {
|
event_type: EventType::RoomMember,
|
||||||
membership: member::MembershipState::Invite,
|
content: serde_json::to_value(member::MemberEventContent {
|
||||||
displayname: db.users.displayname(&user)?,
|
membership: member::MembershipState::Invite,
|
||||||
avatar_url: db.users.avatar_url(&user)?,
|
displayname: db.users.displayname(&user)?,
|
||||||
is_direct: body.is_direct,
|
avatar_url: db.users.avatar_url(&user)?,
|
||||||
third_party_invite: None,
|
is_direct: body.is_direct,
|
||||||
})
|
third_party_invite: None,
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some(user.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(user.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -1539,16 +1581,18 @@ pub fn redact_event_route(
|
||||||
let sender_id = body.sender_id.as_ref().expect("user is authenticated");
|
let sender_id = body.sender_id.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
let event_id = db.rooms.append_pdu(
|
let event_id = db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomRedaction,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(redaction::RedactionEventContent {
|
event_type: EventType::RoomRedaction,
|
||||||
reason: body.reason.clone(),
|
content: serde_json::to_value(redaction::RedactionEventContent {
|
||||||
})
|
reason: body.reason.clone(),
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
None,
|
unsigned: None,
|
||||||
Some(body.event_id.clone()),
|
state_key: None,
|
||||||
|
redacts: Some(body.event_id.clone()),
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1634,13 +1678,15 @@ pub fn join_room_by_id_route(
|
||||||
};
|
};
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(event).expect("event is valid, we just created it"),
|
event_type: EventType::RoomMember,
|
||||||
None,
|
content: serde_json::to_value(event).expect("event is valid, we just created it"),
|
||||||
Some(sender_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(sender_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1702,23 +1748,24 @@ pub fn leave_room_route(
|
||||||
ErrorKind::BadState,
|
ErrorKind::BadState,
|
||||||
"Cannot leave a room you are not a member of.",
|
"Cannot leave a room you are not a member of.",
|
||||||
))?
|
))?
|
||||||
.content
|
.content,
|
||||||
.clone(),
|
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Invalid member event in database."))?
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.map_err(|_| Error::bad_database("Invalid member event in database."))?;
|
.map_err(|_| Error::bad_database("Invalid member event in database."))?;
|
||||||
|
|
||||||
event.membership = member::MembershipState::Leave;
|
event.membership = member::MembershipState::Leave;
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(event).expect("event is valid, we just created it"),
|
event_type: EventType::RoomMember,
|
||||||
None,
|
content: serde_json::to_value(event).expect("event is valid, we just created it"),
|
||||||
Some(sender_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(sender_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1746,8 +1793,7 @@ pub fn kick_user_route(
|
||||||
ErrorKind::BadState,
|
ErrorKind::BadState,
|
||||||
"Cannot kick member that's not in the room.",
|
"Cannot kick member that's not in the room.",
|
||||||
))?
|
))?
|
||||||
.content
|
.content,
|
||||||
.clone(),
|
|
||||||
)
|
)
|
||||||
.expect("Raw::from_value always works")
|
.expect("Raw::from_value always works")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
|
@ -1757,13 +1803,15 @@ pub fn kick_user_route(
|
||||||
// TODO: reason
|
// TODO: reason
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(event).expect("event is valid, we just created it"),
|
event_type: EventType::RoomMember,
|
||||||
None,
|
content: serde_json::to_value(event).expect("event is valid, we just created it"),
|
||||||
Some(body.user_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(body.user_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1837,7 +1885,7 @@ pub fn ban_user_route(
|
||||||
}),
|
}),
|
||||||
|event| {
|
|event| {
|
||||||
let mut event = serde_json::from_value::<Raw<member::MemberEventContent>>(
|
let mut event = serde_json::from_value::<Raw<member::MemberEventContent>>(
|
||||||
event.content.clone(),
|
event.content,
|
||||||
)
|
)
|
||||||
.expect("Raw::from_value always works")
|
.expect("Raw::from_value always works")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
|
@ -1848,13 +1896,15 @@ pub fn ban_user_route(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(event).expect("event is valid, we just created it"),
|
event_type: EventType::RoomMember,
|
||||||
None,
|
content: serde_json::to_value(event).expect("event is valid, we just created it"),
|
||||||
Some(body.user_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(body.user_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1882,23 +1932,24 @@ pub fn unban_user_route(
|
||||||
ErrorKind::BadState,
|
ErrorKind::BadState,
|
||||||
"Cannot unban a user who is not banned.",
|
"Cannot unban a user who is not banned.",
|
||||||
))?
|
))?
|
||||||
.content
|
.content,
|
||||||
.clone(),
|
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Invalid member event in database."))?
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.map_err(|_| Error::bad_database("Invalid member event in database."))?;
|
.map_err(|_| Error::bad_database("Invalid member event in database."))?;
|
||||||
|
|
||||||
event.membership = ruma::events::room::member::MembershipState::Leave;
|
event.membership = ruma::events::room::member::MembershipState::Leave;
|
||||||
|
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(event).expect("event is valid, we just created it"),
|
event_type: EventType::RoomMember,
|
||||||
None,
|
content: serde_json::to_value(event).expect("event is valid, we just created it"),
|
||||||
Some(body.user_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(body.user_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -1932,20 +1983,22 @@ pub fn invite_user_route(
|
||||||
|
|
||||||
if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient {
|
if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient {
|
||||||
db.rooms.append_pdu(
|
db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
EventType::RoomMember,
|
sender: sender_id.clone(),
|
||||||
serde_json::to_value(member::MemberEventContent {
|
event_type: EventType::RoomMember,
|
||||||
membership: member::MembershipState::Invite,
|
content: serde_json::to_value(member::MemberEventContent {
|
||||||
displayname: db.users.displayname(&user_id)?,
|
membership: member::MembershipState::Invite,
|
||||||
avatar_url: db.users.avatar_url(&user_id)?,
|
displayname: db.users.displayname(&user_id)?,
|
||||||
is_direct: None,
|
avatar_url: db.users.avatar_url(&user_id)?,
|
||||||
third_party_invite: None,
|
is_direct: None,
|
||||||
})
|
third_party_invite: None,
|
||||||
.expect("event is valid, we just created it"),
|
})
|
||||||
None,
|
.expect("event is valid, we just created it"),
|
||||||
Some(user_id.to_string()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(user_id.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2049,6 +2102,8 @@ pub async fn get_public_rooms_filtered_route(
|
||||||
db: State<'_, Database>,
|
db: State<'_, Database>,
|
||||||
_body: Ruma<get_public_rooms_filtered::Request>,
|
_body: Ruma<get_public_rooms_filtered::Request>,
|
||||||
) -> ConduitResult<get_public_rooms_filtered::Response> {
|
) -> ConduitResult<get_public_rooms_filtered::Response> {
|
||||||
|
use ruma::events::room;
|
||||||
|
|
||||||
let mut chunk = db
|
let mut chunk = db
|
||||||
.rooms
|
.rooms
|
||||||
.public_rooms()
|
.public_rooms()
|
||||||
|
@ -2060,63 +2115,98 @@ pub async fn get_public_rooms_filtered_route(
|
||||||
|
|
||||||
let chunk = directory::PublicRoomsChunk {
|
let chunk = directory::PublicRoomsChunk {
|
||||||
aliases: Vec::new(),
|
aliases: Vec::new(),
|
||||||
canonical_alias: state.get(&(EventType::RoomCanonicalAlias, "".to_owned())).map_or(Ok::<_, Error>(None), |s| {
|
canonical_alias: state
|
||||||
Ok(serde_json::from_value::<
|
.get(&(EventType::RoomCanonicalAlias, "".to_owned()))
|
||||||
Raw<ruma::events::room::canonical_alias::CanonicalAliasEventContent>,
|
.map_or(Ok::<_, Error>(None), |s| {
|
||||||
|
Ok(serde_json::from_value::<
|
||||||
|
Raw<room::canonical_alias::CanonicalAliasEventContent>,
|
||||||
>(s.content.clone())
|
>(s.content.clone())
|
||||||
.map_err(|_| Error::bad_database("Invalid canonical alias event in database."))?
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.map_err(|_| Error::bad_database("Invalid canonical alias event in database."))?
|
.map_err(|_| {
|
||||||
|
Error::bad_database("Invalid canonical alias event in database.")
|
||||||
|
})?
|
||||||
.alias)
|
.alias)
|
||||||
})?,
|
})?,
|
||||||
name: state.get(&(EventType::RoomName, "".to_owned())).map_or(Ok::<_, Error>(None), |s| {
|
name: state.get(&(EventType::RoomName, "".to_owned())).map_or(
|
||||||
Ok(serde_json::from_value::<Raw<ruma::events::room::name::NameEventContent>>(
|
Ok::<_, Error>(None),
|
||||||
s.content.clone(),
|
|s| {
|
||||||
)
|
Ok(serde_json::from_value::<Raw<room::name::NameEventContent>>(
|
||||||
.map_err(|_| Error::bad_database("Invalid room name event in database."))?
|
s.content.clone(),
|
||||||
.deserialize()
|
)
|
||||||
.map_err(|_| Error::bad_database("Invalid room name event in database."))?
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.name()
|
.deserialize()
|
||||||
.map(|n| n.to_owned()))
|
.map_err(|_| Error::bad_database("Invalid room name event in database."))?
|
||||||
})?,
|
.name()
|
||||||
|
.map(|n| n.to_owned()))
|
||||||
|
},
|
||||||
|
)?,
|
||||||
num_joined_members: (db.rooms.room_members(&room_id).count() as u32).into(),
|
num_joined_members: (db.rooms.room_members(&room_id).count() as u32).into(),
|
||||||
room_id,
|
room_id,
|
||||||
topic: state.get(&(EventType::RoomTopic, "".to_owned())).map_or(Ok::<_, Error>(None), |s| {
|
topic: state.get(&(EventType::RoomTopic, "".to_owned())).map_or(
|
||||||
Ok(Some(serde_json::from_value::<
|
Ok::<_, Error>(None),
|
||||||
Raw<ruma::events::room::topic::TopicEventContent>,
|
|s| {
|
||||||
|
Ok(Some(
|
||||||
|
serde_json::from_value::<Raw<room::topic::TopicEventContent>>(
|
||||||
|
s.content.clone(),
|
||||||
|
)
|
||||||
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
|
.deserialize()
|
||||||
|
.map_err(|_| {
|
||||||
|
Error::bad_database("Invalid room topic event in database.")
|
||||||
|
})?
|
||||||
|
.topic,
|
||||||
|
))
|
||||||
|
},
|
||||||
|
)?,
|
||||||
|
world_readable: state
|
||||||
|
.get(&(EventType::RoomHistoryVisibility, "".to_owned()))
|
||||||
|
.map_or(Ok::<_, Error>(false), |s| {
|
||||||
|
Ok(serde_json::from_value::<
|
||||||
|
Raw<room::history_visibility::HistoryVisibilityEventContent>,
|
||||||
>(s.content.clone())
|
>(s.content.clone())
|
||||||
.map_err(|_| Error::bad_database("Invalid room topic event in database."))?
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.map_err(|_| Error::bad_database("Invalid room topic event in database."))?
|
.map_err(|_| {
|
||||||
.topic))
|
Error::bad_database(
|
||||||
})?,
|
"Invalid room history visibility event in database.",
|
||||||
world_readable: state.get(&(EventType::RoomHistoryVisibility, "".to_owned())).map_or(Ok::<_, Error>(false), |s| {
|
)
|
||||||
Ok(serde_json::from_value::<
|
})?
|
||||||
Raw<ruma::events::room::history_visibility::HistoryVisibilityEventContent>,
|
.history_visibility
|
||||||
>(s.content.clone())
|
== history_visibility::HistoryVisibility::WorldReadable)
|
||||||
.map_err(|_| Error::bad_database("Invalid room history visibility event in database."))?
|
})?,
|
||||||
.deserialize()
|
guest_can_join: state
|
||||||
.map_err(|_| Error::bad_database("Invalid room history visibility event in database."))?
|
.get(&(EventType::RoomGuestAccess, "".to_owned()))
|
||||||
.history_visibility == history_visibility::HistoryVisibility::WorldReadable)
|
.map_or(Ok::<_, Error>(false), |s| {
|
||||||
})?,
|
Ok(
|
||||||
guest_can_join: state.get(&(EventType::RoomGuestAccess, "".to_owned())).map_or(Ok::<_, Error>(false), |s| {
|
serde_json::from_value::<
|
||||||
Ok(serde_json::from_value::<
|
Raw<room::guest_access::GuestAccessEventContent>,
|
||||||
Raw<ruma::events::room::guest_access::GuestAccessEventContent>,
|
>(s.content.clone())
|
||||||
>(s.content.clone())
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.map_err(|_| Error::bad_database("Invalid room guest access event in database."))?
|
.deserialize()
|
||||||
.deserialize()
|
.map_err(|_| {
|
||||||
.map_err(|_| Error::bad_database("Invalid room guest access event in database."))?
|
Error::bad_database("Invalid room guest access event in database.")
|
||||||
.guest_access == guest_access::GuestAccess::CanJoin)
|
})?
|
||||||
})?,
|
.guest_access
|
||||||
avatar_url: state.get(&(EventType::RoomAvatar, "".to_owned())).map_or( Ok::<_, Error>(None),|s| {
|
== guest_access::GuestAccess::CanJoin,
|
||||||
Ok(Some(serde_json::from_value::<
|
)
|
||||||
Raw<ruma::events::room::avatar::AvatarEventContent>,
|
})?,
|
||||||
>(s.content.clone())
|
avatar_url: state.get(&(EventType::RoomAvatar, "".to_owned())).map_or(
|
||||||
.map_err(|_| Error::bad_database("Invalid room avatar event in database."))?
|
Ok::<_, Error>(None),
|
||||||
.deserialize()
|
|s| {
|
||||||
.map_err(|_| Error::bad_database("Invalid room avatar event in database."))?
|
Ok(Some(
|
||||||
.url))
|
serde_json::from_value::<Raw<room::avatar::AvatarEventContent>>(
|
||||||
})?,
|
s.content.clone(),
|
||||||
|
)
|
||||||
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
|
.deserialize()
|
||||||
|
.map_err(|_| {
|
||||||
|
Error::bad_database("Invalid room avatar event in database.")
|
||||||
|
})?
|
||||||
|
.url,
|
||||||
|
))
|
||||||
|
},
|
||||||
|
)?,
|
||||||
};
|
};
|
||||||
Ok::<_, Error>(chunk)
|
Ok::<_, Error>(chunk)
|
||||||
})
|
})
|
||||||
|
@ -2280,18 +2370,20 @@ pub fn create_message_event_route(
|
||||||
unsigned.insert("transaction_id".to_owned(), body.txn_id.clone().into());
|
unsigned.insert("transaction_id".to_owned(), body.txn_id.clone().into());
|
||||||
|
|
||||||
let event_id = db.rooms.append_pdu(
|
let event_id = db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
body.event_type.clone(),
|
sender: sender_id.clone(),
|
||||||
serde_json::from_str(
|
event_type: body.event_type.clone(),
|
||||||
body.json_body
|
content: serde_json::from_str(
|
||||||
.ok_or(Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?
|
body.json_body
|
||||||
.get(),
|
.ok_or(Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?
|
||||||
)
|
.get(),
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
|
)
|
||||||
Some(unsigned),
|
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?,
|
||||||
None,
|
unsigned: Some(unsigned),
|
||||||
None,
|
state_key: None,
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2320,7 +2412,7 @@ pub fn create_state_event_for_key_route(
|
||||||
let canonical_alias = serde_json::from_value::<
|
let canonical_alias = serde_json::from_value::<
|
||||||
Raw<canonical_alias::CanonicalAliasEventContent>,
|
Raw<canonical_alias::CanonicalAliasEventContent>,
|
||||||
>(content.clone())
|
>(content.clone())
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid canonical alias."))?
|
.expect("from_value::<Raw<..>> can never fail")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid canonical alias."))?;
|
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid canonical alias."))?;
|
||||||
|
|
||||||
|
@ -2338,19 +2430,25 @@ pub fn create_state_event_for_key_route(
|
||||||
.filter(|room| room == &body.room_id) // Make sure it's the right room
|
.filter(|room| room == &body.room_id) // Make sure it's the right room
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
return Err(Error::BadRequest(ErrorKind::Forbidden, "You are only allowed to send canonical_alias events when it's aliases already exists"));
|
return Err(Error::BadRequest(
|
||||||
|
ErrorKind::Forbidden,
|
||||||
|
"You are only allowed to send canonical_alias \
|
||||||
|
events when it's aliases already exists",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let event_id = db.rooms.append_pdu(
|
let event_id = db.rooms.append_pdu(
|
||||||
body.room_id.clone(),
|
PduBuilder {
|
||||||
sender_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
body.event_type.clone(),
|
sender: sender_id.clone(),
|
||||||
content,
|
event_type: body.event_type.clone(),
|
||||||
None,
|
content,
|
||||||
Some(body.state_key.clone()),
|
unsigned: None,
|
||||||
None,
|
state_key: Some(body.state_key.clone()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
&db.globals,
|
&db.globals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -2645,7 +2743,7 @@ pub async fn sync_events_route(
|
||||||
// Filter for possible heroes
|
// Filter for possible heroes
|
||||||
.filter_map(|u| u)
|
.filter_map(|u| u)
|
||||||
{
|
{
|
||||||
if heroes.contains(&hero) || hero == sender_id.to_string() {
|
if heroes.contains(&hero) || hero == sender_id.as_str() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2745,7 +2843,7 @@ pub async fn sync_events_route(
|
||||||
notification_count,
|
notification_count,
|
||||||
},
|
},
|
||||||
timeline: sync_events::Timeline {
|
timeline: sync_events::Timeline {
|
||||||
limited: false || joined_since_last_sync,
|
limited: joined_since_last_sync,
|
||||||
prev_batch,
|
prev_batch,
|
||||||
events: room_events,
|
events: room_events,
|
||||||
},
|
},
|
||||||
|
@ -2933,7 +3031,7 @@ pub async fn sync_events_route(
|
||||||
{
|
{
|
||||||
// Hang a few seconds so requests are not spammed
|
// Hang a few seconds so requests are not spammed
|
||||||
// Stop hanging if new info arrives
|
// Stop hanging if new info arrives
|
||||||
let mut duration = body.timeout.unwrap_or(Duration::default());
|
let mut duration = body.timeout.unwrap_or_default();
|
||||||
if duration.as_secs() > 30 {
|
if duration.as_secs() > 30 {
|
||||||
duration = Duration::from_secs(30);
|
duration = Duration::from_secs(30);
|
||||||
}
|
}
|
||||||
|
@ -3224,7 +3322,11 @@ pub fn get_content_route(
|
||||||
_server_name: String,
|
_server_name: String,
|
||||||
_media_id: String,
|
_media_id: String,
|
||||||
) -> ConduitResult<get_content::Response> {
|
) -> ConduitResult<get_content::Response> {
|
||||||
if let Some((filename, content_type, file)) = db
|
if let Some(FileMeta {
|
||||||
|
filename,
|
||||||
|
content_type,
|
||||||
|
file,
|
||||||
|
}) = db
|
||||||
.media
|
.media
|
||||||
.get(format!("mxc://{}/{}", body.server_name, body.media_id))?
|
.get(format!("mxc://{}/{}", body.server_name, body.media_id))?
|
||||||
{
|
{
|
||||||
|
@ -3252,7 +3354,9 @@ pub fn get_content_thumbnail_route(
|
||||||
_server_name: String,
|
_server_name: String,
|
||||||
_media_id: String,
|
_media_id: String,
|
||||||
) -> ConduitResult<get_content_thumbnail::Response> {
|
) -> ConduitResult<get_content_thumbnail::Response> {
|
||||||
if let Some((_, content_type, file)) = db.media.get_thumbnail(
|
if let Some(FileMeta {
|
||||||
|
content_type, file, ..
|
||||||
|
}) = db.media.get_thumbnail(
|
||||||
format!("mxc://{}/{}", body.server_name, body.media_id),
|
format!("mxc://{}/{}", body.server_name, body.media_id),
|
||||||
body.width
|
body.width
|
||||||
.try_into()
|
.try_into()
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
pub(self) mod account_data;
|
pub mod account_data;
|
||||||
pub(self) mod globals;
|
pub mod globals;
|
||||||
pub(self) mod key_backups;
|
pub mod key_backups;
|
||||||
pub(self) mod media;
|
pub mod media;
|
||||||
pub(self) mod rooms;
|
pub mod rooms;
|
||||||
pub(self) mod uiaa;
|
pub mod uiaa;
|
||||||
pub(self) mod users;
|
pub mod users;
|
||||||
|
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
use directories::ProjectDirs;
|
use directories::ProjectDirs;
|
||||||
|
@ -125,7 +125,7 @@ impl Database {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) -> () {
|
pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) {
|
||||||
let mut userid_prefix = user_id.to_string().as_bytes().to_vec();
|
let mut userid_prefix = user_id.to_string().as_bytes().to_vec();
|
||||||
userid_prefix.push(0xff);
|
userid_prefix.push(0xff);
|
||||||
let mut userdeviceid_prefix = userid_prefix.clone();
|
let mut userdeviceid_prefix = userid_prefix.clone();
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
use crate::{utils, Error, Result};
|
use crate::{utils, Error, Result};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
pub struct FileMeta {
|
||||||
|
pub filename: Option<String>,
|
||||||
|
pub content_type: String,
|
||||||
|
pub file: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Media {
|
pub struct Media {
|
||||||
pub(super) mediaid_file: sled::Tree, // MediaId = MXC + WidthHeight + Filename + ContentType
|
pub(super) mediaid_file: sled::Tree, // MediaId = MXC + WidthHeight + Filename + ContentType
|
||||||
}
|
}
|
||||||
|
@ -29,7 +35,7 @@ impl Media {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Downloads a file.
|
/// Downloads a file.
|
||||||
pub fn get(&self, mxc: String) -> Result<Option<(Option<String>, String, Vec<u8>)>> {
|
pub fn get(&self, mxc: String) -> Result<Option<FileMeta>> {
|
||||||
let mut prefix = mxc.as_bytes().to_vec();
|
let mut prefix = mxc.as_bytes().to_vec();
|
||||||
prefix.push(0xff);
|
prefix.push(0xff);
|
||||||
prefix.extend_from_slice(&0_u32.to_be_bytes()); // Width = 0 if it's not a thumbnail
|
prefix.extend_from_slice(&0_u32.to_be_bytes()); // Width = 0 if it's not a thumbnail
|
||||||
|
@ -59,19 +65,18 @@ impl Media {
|
||||||
})?)
|
})?)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some((filename, content_type, file.to_vec())))
|
Ok(Some(FileMeta {
|
||||||
|
filename,
|
||||||
|
content_type,
|
||||||
|
file: file.to_vec(),
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Downloads a file's thumbnail.
|
/// Downloads a file's thumbnail.
|
||||||
pub fn get_thumbnail(
|
pub fn get_thumbnail(&self, mxc: String, width: u32, height: u32) -> Result<Option<FileMeta>> {
|
||||||
&self,
|
|
||||||
mxc: String,
|
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
) -> Result<Option<(Option<String>, String, Vec<u8>)>> {
|
|
||||||
let mut main_prefix = mxc.as_bytes().to_vec();
|
let mut main_prefix = mxc.as_bytes().to_vec();
|
||||||
main_prefix.push(0xff);
|
main_prefix.push(0xff);
|
||||||
|
|
||||||
|
@ -110,7 +115,11 @@ impl Media {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some((filename, content_type, file.to_vec())))
|
Ok(Some(FileMeta {
|
||||||
|
filename,
|
||||||
|
content_type,
|
||||||
|
file: file.to_vec(),
|
||||||
|
}))
|
||||||
} else if let Some(r) = self.mediaid_file.scan_prefix(&original_prefix).next() {
|
} else if let Some(r) = self.mediaid_file.scan_prefix(&original_prefix).next() {
|
||||||
// Generate a thumbnail
|
// Generate a thumbnail
|
||||||
let (key, file) = r?;
|
let (key, file) = r?;
|
||||||
|
@ -157,7 +166,11 @@ impl Media {
|
||||||
|
|
||||||
self.mediaid_file.insert(thumbnail_key, &*thumbnail_bytes)?;
|
self.mediaid_file.insert(thumbnail_key, &*thumbnail_bytes)?;
|
||||||
|
|
||||||
Ok(Some((filename, content_type, thumbnail_bytes)))
|
Ok(Some(FileMeta {
|
||||||
|
filename,
|
||||||
|
content_type,
|
||||||
|
file: thumbnail_bytes.to_vec(),
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ mod edus;
|
||||||
|
|
||||||
pub use edus::RoomEdus;
|
pub use edus::RoomEdus;
|
||||||
|
|
||||||
use crate::{utils, Error, PduEvent, Result};
|
use crate::{pdu::PduBuilder, utils, Error, PduEvent, Result};
|
||||||
use log::error;
|
use log::error;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::error::ErrorKind,
|
api::client::error::ErrorKind,
|
||||||
|
@ -250,17 +250,21 @@ impl Rooms {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new persisted data unit and adds it to a room.
|
/// Creates a new persisted data unit and adds it to a room.
|
||||||
|
#[allow(clippy::blocks_in_if_conditions)]
|
||||||
pub fn append_pdu(
|
pub fn append_pdu(
|
||||||
&self,
|
&self,
|
||||||
room_id: RoomId,
|
pdu_builder: PduBuilder,
|
||||||
sender: UserId,
|
|
||||||
event_type: EventType,
|
|
||||||
content: serde_json::Value,
|
|
||||||
unsigned: Option<serde_json::Map<String, serde_json::Value>>,
|
|
||||||
state_key: Option<String>,
|
|
||||||
redacts: Option<EventId>,
|
|
||||||
globals: &super::globals::Globals,
|
globals: &super::globals::Globals,
|
||||||
) -> Result<EventId> {
|
) -> Result<EventId> {
|
||||||
|
let PduBuilder {
|
||||||
|
room_id,
|
||||||
|
sender,
|
||||||
|
event_type,
|
||||||
|
content,
|
||||||
|
unsigned,
|
||||||
|
state_key,
|
||||||
|
redacts,
|
||||||
|
} = pdu_builder;
|
||||||
// TODO: Make sure this isn't called twice in parallel
|
// TODO: Make sure this isn't called twice in parallel
|
||||||
let prev_events = self.get_pdu_leaves(&room_id)?;
|
let prev_events = self.get_pdu_leaves(&room_id)?;
|
||||||
|
|
||||||
|
@ -288,7 +292,7 @@ impl Rooms {
|
||||||
},
|
},
|
||||||
|power_levels| {
|
|power_levels| {
|
||||||
Ok(serde_json::from_value::<Raw<PowerLevelsEventContent>>(
|
Ok(serde_json::from_value::<Raw<PowerLevelsEventContent>>(
|
||||||
power_levels.content.clone(),
|
power_levels.content,
|
||||||
)
|
)
|
||||||
.expect("Raw::from_value always works.")
|
.expect("Raw::from_value always works.")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
|
@ -298,13 +302,13 @@ impl Rooms {
|
||||||
let sender_membership = self
|
let sender_membership = self
|
||||||
.room_state_get(&room_id, &EventType::RoomMember, &sender.to_string())?
|
.room_state_get(&room_id, &EventType::RoomMember, &sender.to_string())?
|
||||||
.map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| {
|
.map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| {
|
||||||
Ok(serde_json::from_value::<Raw<member::MemberEventContent>>(
|
Ok(
|
||||||
pdu.content.clone(),
|
serde_json::from_value::<Raw<member::MemberEventContent>>(pdu.content)
|
||||||
|
.expect("Raw::from_value always works.")
|
||||||
|
.deserialize()
|
||||||
|
.map_err(|_| Error::bad_database("Invalid Member event in db."))?
|
||||||
|
.membership,
|
||||||
)
|
)
|
||||||
.expect("Raw::from_value always works.")
|
|
||||||
.deserialize()
|
|
||||||
.map_err(|_| Error::bad_database("Invalid Member event in db."))?
|
|
||||||
.membership)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let sender_power = power_levels.users.get(&sender).map_or_else(
|
let sender_power = power_levels.users.get(&sender).map_or_else(
|
||||||
|
@ -341,7 +345,7 @@ impl Rooms {
|
||||||
)?
|
)?
|
||||||
.map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| {
|
.map_or(Ok::<_, Error>(member::MembershipState::Leave), |pdu| {
|
||||||
Ok(serde_json::from_value::<Raw<member::MemberEventContent>>(
|
Ok(serde_json::from_value::<Raw<member::MemberEventContent>>(
|
||||||
pdu.content.clone(),
|
pdu.content,
|
||||||
)
|
)
|
||||||
.expect("Raw::from_value always works.")
|
.expect("Raw::from_value always works.")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
|
@ -373,7 +377,7 @@ impl Rooms {
|
||||||
.map_or(Ok::<_, Error>(join_rules::JoinRule::Public), |pdu| {
|
.map_or(Ok::<_, Error>(join_rules::JoinRule::Public), |pdu| {
|
||||||
Ok(serde_json::from_value::<
|
Ok(serde_json::from_value::<
|
||||||
Raw<join_rules::JoinRulesEventContent>,
|
Raw<join_rules::JoinRulesEventContent>,
|
||||||
>(pdu.content.clone())
|
>(pdu.content)
|
||||||
.expect("Raw::from_value always works.")
|
.expect("Raw::from_value always works.")
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
|
@ -501,7 +505,7 @@ impl Rooms {
|
||||||
let mut unsigned = unsigned.unwrap_or_default();
|
let mut unsigned = unsigned.unwrap_or_default();
|
||||||
if let Some(state_key) = &state_key {
|
if let Some(state_key) = &state_key {
|
||||||
if let Some(prev_pdu) = self.room_state_get(&room_id, &event_type, &state_key)? {
|
if let Some(prev_pdu) = self.room_state_get(&room_id, &event_type, &state_key)? {
|
||||||
unsigned.insert("prev_content".to_owned(), prev_pdu.content.clone());
|
unsigned.insert("prev_content".to_owned(), prev_pdu.content);
|
||||||
unsigned.insert(
|
unsigned.insert(
|
||||||
"prev_sender".to_owned(),
|
"prev_sender".to_owned(),
|
||||||
serde_json::to_value(prev_pdu.sender).expect("UserId::to_value always works"),
|
serde_json::to_value(prev_pdu.sender).expect("UserId::to_value always works"),
|
||||||
|
@ -575,28 +579,24 @@ impl Rooms {
|
||||||
self.roomstateid_pdu.insert(key, &*pdu_json.to_string())?;
|
self.roomstateid_pdu.insert(key, &*pdu_json.to_string())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match event_type {
|
if let EventType::RoomRedaction = event_type {
|
||||||
EventType::RoomRedaction => {
|
if let Some(redact_id) = &redacts {
|
||||||
if let Some(redact_id) = &redacts {
|
// TODO: Reason
|
||||||
// TODO: Reason
|
let _reason =
|
||||||
let _reason =
|
serde_json::from_value::<Raw<redaction::RedactionEventContent>>(content)
|
||||||
serde_json::from_value::<Raw<redaction::RedactionEventContent>>(content)
|
.expect("Raw::from_value always works.")
|
||||||
.expect("Raw::from_value always works.")
|
.deserialize()
|
||||||
.deserialize()
|
.map_err(|_| {
|
||||||
.map_err(|_| {
|
Error::BadRequest(
|
||||||
Error::BadRequest(
|
ErrorKind::InvalidParam,
|
||||||
ErrorKind::InvalidParam,
|
"Invalid redaction event content.",
|
||||||
"Invalid redaction event content.",
|
)
|
||||||
)
|
})?
|
||||||
})?
|
.reason;
|
||||||
.reason;
|
|
||||||
|
|
||||||
self.redact_pdu(&redact_id)?;
|
self.redact_pdu(&redact_id)?;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.edus.room_read_set(&room_id, &sender, index)?;
|
self.edus.room_read_set(&room_id, &sender, index)?;
|
||||||
|
|
||||||
Ok(pdu.event_id)
|
Ok(pdu.event_id)
|
||||||
|
@ -626,7 +626,7 @@ impl Rooms {
|
||||||
let mut first_pdu_id = prefix.clone();
|
let mut first_pdu_id = prefix.clone();
|
||||||
first_pdu_id.extend_from_slice(&(since + 1).to_be_bytes());
|
first_pdu_id.extend_from_slice(&(since + 1).to_be_bytes());
|
||||||
|
|
||||||
let mut last_pdu_id = prefix.clone();
|
let mut last_pdu_id = prefix;
|
||||||
last_pdu_id.extend_from_slice(&u64::MAX.to_be_bytes());
|
last_pdu_id.extend_from_slice(&u64::MAX.to_be_bytes());
|
||||||
|
|
||||||
let user_id = user_id.clone();
|
let user_id = user_id.clone();
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl Uiaa {
|
||||||
.map(|session| {
|
.map(|session| {
|
||||||
Ok::<_, Error>(self.get_uiaa_session(&user_id, &device_id, session)?)
|
Ok::<_, Error>(self.get_uiaa_session(&user_id, &device_id, session)?)
|
||||||
})
|
})
|
||||||
.unwrap_or(Ok(uiaainfo.clone()))?;
|
.unwrap_or_else(|| Ok(uiaainfo.clone()))?;
|
||||||
|
|
||||||
// Find out what the user completed
|
// Find out what the user completed
|
||||||
match &**kind {
|
match &**kind {
|
||||||
|
|
|
@ -502,7 +502,7 @@ impl Users {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut user_signing_key_key = prefix.clone();
|
let mut user_signing_key_key = prefix;
|
||||||
user_signing_key_key.extend_from_slice(user_signing_key_id.as_bytes());
|
user_signing_key_key.extend_from_slice(user_signing_key_id.as_bytes());
|
||||||
|
|
||||||
self.keyid_key.insert(
|
self.keyid_key.insert(
|
||||||
|
|
|
@ -6,7 +6,7 @@ pub mod push_rules;
|
||||||
mod ruma_wrapper;
|
mod ruma_wrapper;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
pub use database::Database;
|
pub use database::{media::FileMeta, Database};
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use pdu::PduEvent;
|
pub use pdu::PduEvent;
|
||||||
pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
|
pub use ruma_wrapper::{ConduitResult, Ruma, RumaResponse};
|
||||||
|
|
12
src/pdu.rs
12
src/pdu.rs
|
@ -175,3 +175,15 @@ impl PduEvent {
|
||||||
serde_json::from_value(json).expect("Raw::from_value always works")
|
serde_json::from_value(json).expect("Raw::from_value always works")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build the start of a PDU in order to add it to the `Database`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PduBuilder {
|
||||||
|
pub room_id: RoomId,
|
||||||
|
pub sender: UserId,
|
||||||
|
pub event_type: EventType,
|
||||||
|
pub content: serde_json::Value,
|
||||||
|
pub unsigned: Option<serde_json::Map<String, serde_json::Value>>,
|
||||||
|
pub state_key: Option<String>,
|
||||||
|
pub redacts: Option<EventId>,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue