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>
This commit is contained in:
Timo Kösters 2020-07-30 08:20:31 +02:00
commit c824652de6
8 changed files with 506 additions and 377 deletions

View file

@ -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()

View file

@ -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();

View file

@ -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)
} }

View file

@ -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();

View file

@ -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 {

View file

@ -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(

View file

@ -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};

View file

@ -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>,
}