resolve and add even more pedantic clippy lints
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
0bb5115bd1
commit
3bc2af7d26
32 changed files with 167 additions and 167 deletions
16
Cargo.toml
16
Cargo.toml
|
@ -419,7 +419,7 @@ unit_bindings = "warn"
|
||||||
unused_braces = "allow"
|
unused_braces = "allow"
|
||||||
|
|
||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
pedantic = "warn"
|
# pedantic = "warn"
|
||||||
|
|
||||||
suspicious = "warn" # assume deny in practice
|
suspicious = "warn" # assume deny in practice
|
||||||
perf = "warn" # assume deny in practice
|
perf = "warn" # assume deny in practice
|
||||||
|
@ -497,6 +497,20 @@ redundant_closure_for_method_calls = "warn"
|
||||||
large_futures = "warn"
|
large_futures = "warn"
|
||||||
semicolon_if_nothing_returned = "warn"
|
semicolon_if_nothing_returned = "warn"
|
||||||
match_bool = "warn"
|
match_bool = "warn"
|
||||||
|
struct_excessive_bools = "warn"
|
||||||
|
must_use_candidate = "warn"
|
||||||
|
collapsible_else_if = "warn"
|
||||||
|
inconsistent_struct_constructor = "warn"
|
||||||
|
manual_string_new = "warn"
|
||||||
|
zero_sized_map_values = "warn"
|
||||||
|
unnecessary_box_returns = "warn"
|
||||||
|
map_unwrap_or = "warn"
|
||||||
|
implicit_clone = "warn"
|
||||||
|
match_wildcard_for_single_variants = "warn"
|
||||||
|
unnecessary_wraps = "warn"
|
||||||
|
match_same_arms = "warn"
|
||||||
|
ignored_unit_patterns = "warn"
|
||||||
|
redundant_else = "warn"
|
||||||
|
|
||||||
# not in rust 1.75.0 (breaks CI)
|
# not in rust 1.75.0 (breaks CI)
|
||||||
# infinite_loop = "warn"
|
# infinite_loop = "warn"
|
||||||
|
|
|
@ -76,6 +76,7 @@ pub async fn get_register_available_route(
|
||||||
/// - Creates a new account and populates it with default account data
|
/// - Creates a new account and populates it with default account data
|
||||||
/// - If `inhibit_login` is false: Creates a device and returns device id and
|
/// - If `inhibit_login` is false: Creates a device and returns device id and
|
||||||
/// access_token
|
/// access_token
|
||||||
|
#[allow(clippy::doc_markdown)]
|
||||||
pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<register::v3::Response> {
|
pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<register::v3::Response> {
|
||||||
if !services().globals.allow_registration() && !body.from_appservice {
|
if !services().globals.allow_registration() && !body.from_appservice {
|
||||||
info!(
|
info!(
|
||||||
|
@ -390,7 +391,7 @@ pub async fn change_password_route(body: Ruma<change_password::v3::Request>) ->
|
||||||
|
|
||||||
/// # `GET _matrix/client/r0/account/whoami`
|
/// # `GET _matrix/client/r0/account/whoami`
|
||||||
///
|
///
|
||||||
/// Get user_id of the sender user.
|
/// Get `user_id` of the sender user.
|
||||||
///
|
///
|
||||||
/// Note: Also works for Application Services
|
/// Note: Also works for Application Services
|
||||||
pub async fn whoami_route(body: Ruma<whoami::v3::Request>) -> Result<whoami::v3::Response> {
|
pub async fn whoami_route(body: Ruma<whoami::v3::Request>) -> Result<whoami::v3::Response> {
|
||||||
|
|
|
@ -91,8 +91,7 @@ pub async fn get_context_route(body: Ruma<get_context::v3::Request>) -> Result<g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let start_token =
|
let start_token = events_before.last().map_or_else(|| base_token.stringify(), |(count, _)| count.stringify());
|
||||||
events_before.last().map(|(count, _)| count.stringify()).unwrap_or_else(|| base_token.stringify());
|
|
||||||
|
|
||||||
let events_before: Vec<_> = events_before.into_iter().map(|(_, pdu)| pdu.to_room_event()).collect();
|
let events_before: Vec<_> = events_before.into_iter().map(|(_, pdu)| pdu.to_room_event()).collect();
|
||||||
|
|
||||||
|
@ -134,7 +133,7 @@ pub async fn get_context_route(body: Ruma<get_context::v3::Request>) -> Result<g
|
||||||
|
|
||||||
let state_ids = services().rooms.state_accessor.state_full_ids(shortstatehash).await?;
|
let state_ids = services().rooms.state_accessor.state_full_ids(shortstatehash).await?;
|
||||||
|
|
||||||
let end_token = events_after.last().map(|(count, _)| count.stringify()).unwrap_or_else(|| base_token.stringify());
|
let end_token = events_after.last().map_or_else(|| base_token.stringify(), |(count, _)| count.stringify());
|
||||||
|
|
||||||
let events_after: Vec<_> = events_after.into_iter().map(|(_, pdu)| pdu.to_room_event()).collect();
|
let events_after: Vec<_> = events_after.into_iter().map(|(_, pdu)| pdu.to_room_event()).collect();
|
||||||
|
|
||||||
|
|
|
@ -363,11 +363,11 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(get_keys::v3::Response {
|
Ok(get_keys::v3::Response {
|
||||||
|
failures,
|
||||||
|
device_keys,
|
||||||
master_keys,
|
master_keys,
|
||||||
self_signing_keys,
|
self_signing_keys,
|
||||||
user_signing_keys,
|
user_signing_keys,
|
||||||
device_keys,
|
|
||||||
failures,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ pub async fn send_message_event_route(
|
||||||
///
|
///
|
||||||
/// - Only works if the user is joined (TODO: always allow, but only show events
|
/// - Only works if the user is joined (TODO: always allow, but only show events
|
||||||
/// where the user was
|
/// where the user was
|
||||||
/// joined, depending on history_visibility)
|
/// joined, depending on `history_visibility`)
|
||||||
pub async fn get_message_events_route(
|
pub async fn get_message_events_route(
|
||||||
body: Ruma<get_message_events::v3::Request>,
|
body: Ruma<get_message_events::v3::Request>,
|
||||||
) -> Result<get_message_events::v3::Response> {
|
) -> Result<get_message_events::v3::Response> {
|
||||||
|
|
|
@ -126,9 +126,9 @@ pub async fn get_displayname_route(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # `PUT /_matrix/client/r0/profile/{userId}/avatar_url`
|
/// # `PUT /_matrix/client/v3/profile/{userId}/avatar_url`
|
||||||
///
|
///
|
||||||
/// Updates the avatar_url and blurhash.
|
/// Updates the `avatar_url` and `blurhash`.
|
||||||
///
|
///
|
||||||
/// - Also makes sure other users receive the update using presence EDUs
|
/// - Also makes sure other users receive the update using presence EDUs
|
||||||
pub async fn set_avatar_url_route(body: Ruma<set_avatar_url::v3::Request>) -> Result<set_avatar_url::v3::Response> {
|
pub async fn set_avatar_url_route(body: Ruma<set_avatar_url::v3::Request>) -> Result<set_avatar_url::v3::Response> {
|
||||||
|
@ -192,10 +192,10 @@ pub async fn set_avatar_url_route(body: Ruma<set_avatar_url::v3::Request>) -> Re
|
||||||
|
|
||||||
/// # `GET /_matrix/client/v3/profile/{userId}/avatar_url`
|
/// # `GET /_matrix/client/v3/profile/{userId}/avatar_url`
|
||||||
///
|
///
|
||||||
/// Returns the avatar_url and blurhash of the user.
|
/// Returns the `avatar_url` and `blurhash` of the user.
|
||||||
///
|
///
|
||||||
/// - If user is on another server and we do not have a local copy already
|
/// - If user is on another server and we do not have a local copy already
|
||||||
/// fetch avatar_url and blurhash over federation
|
/// fetch `avatar_url` and blurhash over federation
|
||||||
pub async fn get_avatar_url_route(body: Ruma<get_avatar_url::v3::Request>) -> Result<get_avatar_url::v3::Response> {
|
pub async fn get_avatar_url_route(body: Ruma<get_avatar_url::v3::Request>) -> Result<get_avatar_url::v3::Response> {
|
||||||
if body.user_id.server_name() != services().globals.server_name() {
|
if body.user_id.server_name() != services().globals.server_name() {
|
||||||
// Create and update our local copy of the user
|
// Create and update our local copy of the user
|
||||||
|
|
|
@ -34,7 +34,7 @@ use crate::{api::client_server::invite_helper, service::pdu::PduBuilder, service
|
||||||
/// Creates a new room.
|
/// Creates a new room.
|
||||||
///
|
///
|
||||||
/// - Room ID is randomly generated
|
/// - Room ID is randomly generated
|
||||||
/// - Create alias if room_alias_name is set
|
/// - Create alias if `room_alias_name` is set
|
||||||
/// - Send create event
|
/// - Send create event
|
||||||
/// - Join sender user
|
/// - Join sender user
|
||||||
/// - Send power levels event
|
/// - Send power levels event
|
||||||
|
@ -273,7 +273,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
event_type: TimelineEventType::RoomCreate,
|
event_type: TimelineEventType::RoomCreate,
|
||||||
content: to_raw_value(&content).expect("event is valid, we just created it"),
|
content: to_raw_value(&content).expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -350,7 +350,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
event_type: TimelineEventType::RoomPowerLevels,
|
event_type: TimelineEventType::RoomPowerLevels,
|
||||||
content: to_raw_value(&power_levels_content).expect("to_raw_value always works on serde_json::Value"),
|
content: to_raw_value(&power_levels_content).expect("to_raw_value always works on serde_json::Value"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -373,7 +373,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
})
|
})
|
||||||
.expect("We checked that alias earlier, it must be fine"),
|
.expect("We checked that alias earlier, it must be fine"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -399,7 +399,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
}))
|
}))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -418,7 +418,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
content: to_raw_value(&RoomHistoryVisibilityEventContent::new(HistoryVisibility::Shared))
|
content: to_raw_value(&RoomHistoryVisibilityEventContent::new(HistoryVisibility::Shared))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -440,7 +440,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
}))
|
}))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -457,7 +457,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Implicit state key defaults to ""
|
// Implicit state key defaults to ""
|
||||||
pdu_builder.state_key.get_or_insert_with(|| "".to_owned());
|
pdu_builder.state_key.get_or_insert_with(String::new);
|
||||||
|
|
||||||
// Silently skip encryption events if they are not allowed
|
// Silently skip encryption events if they are not allowed
|
||||||
if pdu_builder.event_type == TimelineEventType::RoomEncryption && !services().globals.allow_encryption() {
|
if pdu_builder.event_type == TimelineEventType::RoomEncryption && !services().globals.allow_encryption() {
|
||||||
|
@ -478,7 +478,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
content: to_raw_value(&RoomNameEventContent::new(name.clone()))
|
content: to_raw_value(&RoomNameEventContent::new(name.clone()))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -500,7 +500,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -564,7 +564,7 @@ pub async fn get_room_event_route(body: Ruma<get_room_event::v3::Request>) -> Re
|
||||||
/// Lists all aliases of the room.
|
/// Lists all aliases of the room.
|
||||||
///
|
///
|
||||||
/// - Only users joined to the room are allowed to call this TODO: Allow any
|
/// - Only users joined to the room are allowed to call this TODO: Allow any
|
||||||
/// user to call it if history_visibility is world readable
|
/// user to call it if `history_visibility` is world readable
|
||||||
pub async fn get_room_aliases_route(body: Ruma<aliases::v3::Request>) -> Result<aliases::v3::Response> {
|
pub async fn get_room_aliases_route(body: Ruma<aliases::v3::Request>) -> Result<aliases::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
|
|
||||||
|
@ -623,7 +623,7 @@ pub async fn upgrade_room_route(body: Ruma<upgrade_room::v3::Request>) -> Result
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -720,7 +720,7 @@ pub async fn upgrade_room_route(body: Ruma<upgrade_room::v3::Request>) -> Result
|
||||||
event_type: TimelineEventType::RoomCreate,
|
event_type: TimelineEventType::RoomCreate,
|
||||||
content: to_raw_value(&create_event_content).expect("event is valid, we just created it"),
|
content: to_raw_value(&create_event_content).expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -785,7 +785,7 @@ pub async fn upgrade_room_route(body: Ruma<upgrade_room::v3::Request>) -> Result
|
||||||
event_type: event_type.to_string().into(),
|
event_type: event_type.to_string().into(),
|
||||||
content: event_content,
|
content: event_content,
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -827,7 +827,7 @@ pub async fn upgrade_room_route(body: Ruma<upgrade_room::v3::Request>) -> Result
|
||||||
event_type: TimelineEventType::RoomPowerLevels,
|
event_type: TimelineEventType::RoomPowerLevels,
|
||||||
content: to_raw_value(&power_levels_event_content).expect("event is valid, we just created it"),
|
content: to_raw_value(&power_levels_event_content).expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
|
|
|
@ -192,7 +192,7 @@ pub async fn login_route(body: Ruma<login::v3::Request>) -> Result<login::v3::Re
|
||||||
|
|
||||||
// send client well-known if specified so the client knows to reconfigure itself
|
// send client well-known if specified so the client knows to reconfigure itself
|
||||||
let client_discovery_info = DiscoveryInfo::new(HomeserverInfo::new(
|
let client_discovery_info = DiscoveryInfo::new(HomeserverInfo::new(
|
||||||
services().globals.well_known_client().to_owned().unwrap_or_else(|| "".to_owned()),
|
services().globals.well_known_client().to_owned().unwrap_or_default(),
|
||||||
));
|
));
|
||||||
|
|
||||||
info!("{} logged in", user_id);
|
info!("{} logged in", user_id);
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{service::pdu::PduBuilder, services, Error, Result, Ruma, RumaRespons
|
||||||
/// - The only requirement for the content is that it has to be valid json
|
/// - The only requirement for the content is that it has to be valid json
|
||||||
/// - Tries to send the event into the room, auth rules will determine if it is
|
/// - Tries to send the event into the room, auth rules will determine if it is
|
||||||
/// allowed
|
/// allowed
|
||||||
/// - If event is new canonical_alias: Rejects if alias is incorrect
|
/// - If event is new `canonical_alias`: Rejects if alias is incorrect
|
||||||
pub async fn send_state_event_for_key_route(
|
pub async fn send_state_event_for_key_route(
|
||||||
body: Ruma<send_state_event::v3::Request>,
|
body: Ruma<send_state_event::v3::Request>,
|
||||||
) -> Result<send_state_event::v3::Response> {
|
) -> Result<send_state_event::v3::Response> {
|
||||||
|
@ -48,7 +48,7 @@ pub async fn send_state_event_for_key_route(
|
||||||
/// - The only requirement for the content is that it has to be valid json
|
/// - The only requirement for the content is that it has to be valid json
|
||||||
/// - Tries to send the event into the room, auth rules will determine if it is
|
/// - Tries to send the event into the room, auth rules will determine if it is
|
||||||
/// allowed
|
/// allowed
|
||||||
/// - If event is new canonical_alias: Rejects if alias is incorrect
|
/// - If event is new `canonical_alias`: Rejects if alias is incorrect
|
||||||
pub async fn send_state_event_for_empty_key_route(
|
pub async fn send_state_event_for_empty_key_route(
|
||||||
body: Ruma<send_state_event::v3::Request>,
|
body: Ruma<send_state_event::v3::Request>,
|
||||||
) -> Result<RumaResponse<send_state_event::v3::Response>> {
|
) -> Result<RumaResponse<send_state_event::v3::Response>> {
|
||||||
|
|
|
@ -68,7 +68,7 @@ use crate::{service::rooms::timeline::PduCount, services, Error, PduEvent, Resul
|
||||||
/// at the point of the invite
|
/// at the point of the invite
|
||||||
///
|
///
|
||||||
/// For left rooms:
|
/// For left rooms:
|
||||||
/// - If the user left after `since`: prev_batch token, empty state (TODO:
|
/// - If the user left after `since`: `prev_batch` token, empty state (TODO:
|
||||||
/// subset of the state at the point of the leave)
|
/// subset of the state at the point of the leave)
|
||||||
///
|
///
|
||||||
/// - Sync is handled in an async task, multiple requests from the same device
|
/// - Sync is handled in an async task, multiple requests from the same device
|
||||||
|
|
|
@ -20,15 +20,16 @@ pub async fn update_tag_route(body: Ruma<create_tag::v3::Request>) -> Result<cre
|
||||||
|
|
||||||
let event = services().account_data.get(Some(&body.room_id), sender_user, RoomAccountDataEventType::Tag)?;
|
let event = services().account_data.get(Some(&body.room_id), sender_user, RoomAccountDataEventType::Tag)?;
|
||||||
|
|
||||||
let mut tags_event = event
|
let mut tags_event = event.map_or_else(
|
||||||
.map(|e| serde_json::from_str(e.get()).map_err(|_| Error::bad_database("Invalid account data event in db.")))
|
|| {
|
||||||
.unwrap_or_else(|| {
|
|
||||||
Ok(TagEvent {
|
Ok(TagEvent {
|
||||||
content: TagEventContent {
|
content: TagEventContent {
|
||||||
tags: BTreeMap::new(),
|
tags: BTreeMap::new(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})?;
|
},
|
||||||
|
|e| serde_json::from_str(e.get()).map_err(|_| Error::bad_database("Invalid account data event in db.")),
|
||||||
|
)?;
|
||||||
|
|
||||||
tags_event.content.tags.insert(body.tag.clone().into(), body.tag_info.clone());
|
tags_event.content.tags.insert(body.tag.clone().into(), body.tag_info.clone());
|
||||||
|
|
||||||
|
@ -52,15 +53,16 @@ pub async fn delete_tag_route(body: Ruma<delete_tag::v3::Request>) -> Result<del
|
||||||
|
|
||||||
let event = services().account_data.get(Some(&body.room_id), sender_user, RoomAccountDataEventType::Tag)?;
|
let event = services().account_data.get(Some(&body.room_id), sender_user, RoomAccountDataEventType::Tag)?;
|
||||||
|
|
||||||
let mut tags_event = event
|
let mut tags_event = event.map_or_else(
|
||||||
.map(|e| serde_json::from_str(e.get()).map_err(|_| Error::bad_database("Invalid account data event in db.")))
|
|| {
|
||||||
.unwrap_or_else(|| {
|
|
||||||
Ok(TagEvent {
|
Ok(TagEvent {
|
||||||
content: TagEventContent {
|
content: TagEventContent {
|
||||||
tags: BTreeMap::new(),
|
tags: BTreeMap::new(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})?;
|
},
|
||||||
|
|e| serde_json::from_str(e.get()).map_err(|_| Error::bad_database("Invalid account data event in db.")),
|
||||||
|
)?;
|
||||||
|
|
||||||
tags_event.content.tags.remove(&body.tag.clone().into());
|
tags_event.content.tags.remove(&body.tag.clone().into());
|
||||||
|
|
||||||
|
@ -84,15 +86,16 @@ pub async fn get_tags_route(body: Ruma<get_tags::v3::Request>) -> Result<get_tag
|
||||||
|
|
||||||
let event = services().account_data.get(Some(&body.room_id), sender_user, RoomAccountDataEventType::Tag)?;
|
let event = services().account_data.get(Some(&body.room_id), sender_user, RoomAccountDataEventType::Tag)?;
|
||||||
|
|
||||||
let tags_event = event
|
let tags_event = event.map_or_else(
|
||||||
.map(|e| serde_json::from_str(e.get()).map_err(|_| Error::bad_database("Invalid account data event in db.")))
|
|| {
|
||||||
.unwrap_or_else(|| {
|
|
||||||
Ok(TagEvent {
|
Ok(TagEvent {
|
||||||
content: TagEventContent {
|
content: TagEventContent {
|
||||||
tags: BTreeMap::new(),
|
tags: BTreeMap::new(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})?;
|
},
|
||||||
|
|e| serde_json::from_str(e.get()).map_err(|_| Error::bad_database("Invalid account data event in db.")),
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(get_tags::v3::Response {
|
Ok(get_tags::v3::Response {
|
||||||
tags: tags_event.content.tags,
|
tags: tags_event.content.tags,
|
||||||
|
|
|
@ -128,8 +128,7 @@ where
|
||||||
(Some(user_id), None, None, true)
|
(Some(user_id), None, None, true)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AuthScheme::ServerSignatures => (None, None, None, true),
|
AuthScheme::ServerSignatures | AuthScheme::None => (None, None, None, true),
|
||||||
AuthScheme::None => (None, None, None, true),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match metadata.authentication {
|
match metadata.authentication {
|
||||||
|
@ -341,8 +340,8 @@ where
|
||||||
sender_user,
|
sender_user,
|
||||||
sender_device,
|
sender_device,
|
||||||
sender_servername,
|
sender_servername,
|
||||||
from_appservice,
|
|
||||||
json_body,
|
json_body,
|
||||||
|
from_appservice,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ use crate::{
|
||||||
/// (colon-plus-port if it was specified).
|
/// (colon-plus-port if it was specified).
|
||||||
///
|
///
|
||||||
/// Note: A `FedDest::Named` might contain an IP address in string form if there
|
/// Note: A `FedDest::Named` might contain an IP address in string form if there
|
||||||
/// was no port specified to construct a SocketAddr with.
|
/// was no port specified to construct a `SocketAddr` with.
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -73,9 +73,9 @@ use crate::{
|
||||||
/// # fn main() -> Result<(), std::net::AddrParseError> {
|
/// # fn main() -> Result<(), std::net::AddrParseError> {
|
||||||
/// FedDest::Literal("198.51.100.3:8448".parse()?);
|
/// FedDest::Literal("198.51.100.3:8448".parse()?);
|
||||||
/// FedDest::Literal("[2001:db8::4:5]:443".parse()?);
|
/// FedDest::Literal("[2001:db8::4:5]:443".parse()?);
|
||||||
/// FedDest::Named("matrix.example.org".to_owned(), "".to_owned());
|
/// FedDest::Named("matrix.example.org".to_owned(), String::new());
|
||||||
/// FedDest::Named("matrix.example.org".to_owned(), ":8448".to_owned());
|
/// FedDest::Named("matrix.example.org".to_owned(), ":8448".to_owned());
|
||||||
/// FedDest::Named("198.51.100.5".to_owned(), "".to_owned());
|
/// FedDest::Named("198.51.100.5".to_owned(), String::new());
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -309,24 +309,21 @@ where
|
||||||
debug!(
|
debug!(
|
||||||
"Timed out sending request to {} at {}: {}",
|
"Timed out sending request to {} at {}: {}",
|
||||||
destination, actual_destination_str, e
|
destination, actual_destination_str, e
|
||||||
)
|
);
|
||||||
|
} else if e.is_connect() {
|
||||||
|
debug!("Failed to connect to {} at {}: {}", destination, actual_destination_str, e);
|
||||||
|
} else if e.is_redirect() {
|
||||||
|
debug!(
|
||||||
|
"Redirect loop sending request to {} at {}: {}\nFinal URL: {:?}",
|
||||||
|
destination,
|
||||||
|
actual_destination_str,
|
||||||
|
e,
|
||||||
|
e.url()
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if e.is_connect() {
|
info!("Could not send request to {} at {}: {}", destination, actual_destination_str, e);
|
||||||
debug!("Failed to connect to {} at {}: {}", destination, actual_destination_str, e)
|
|
||||||
} else {
|
|
||||||
if e.is_redirect() {
|
|
||||||
debug!(
|
|
||||||
"Redirect loop sending request to {} at {}: {}\nFinal URL: {:?}",
|
|
||||||
destination,
|
|
||||||
actual_destination_str,
|
|
||||||
e,
|
|
||||||
e.url()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
info!("Could not send request to {} at {}: {}", destination, actual_destination_str, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(e.into())
|
Err(e.into())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -350,7 +347,7 @@ fn add_port_to_hostname(destination_str: &str) -> FedDest {
|
||||||
FedDest::Named(host.to_owned(), port.to_owned())
|
FedDest::Named(host.to_owned(), port.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns: actual_destination, host header
|
/// Returns: `actual_destination`, host header
|
||||||
/// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
|
/// Implemented according to the specification at <https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names>
|
||||||
/// Numbers in comments below refer to bullet points in linked section of
|
/// Numbers in comments below refer to bullet points in linked section of
|
||||||
/// specification
|
/// specification
|
||||||
|
@ -1690,9 +1687,9 @@ pub async fn get_profile_information_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(get_profile_information::v1::Response {
|
Ok(get_profile_information::v1::Response {
|
||||||
blurhash,
|
|
||||||
displayname,
|
displayname,
|
||||||
avatar_url,
|
avatar_url,
|
||||||
|
blurhash,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use clap::Parser;
|
||||||
/// Set the environment variable `CONDUIT_VERSION_EXTRA` to any UTF-8 string to
|
/// Set the environment variable `CONDUIT_VERSION_EXTRA` to any UTF-8 string to
|
||||||
/// include it in parenthesis after the SemVer version. A common value are git
|
/// include it in parenthesis after the SemVer version. A common value are git
|
||||||
/// commit hashes.
|
/// commit hashes.
|
||||||
|
#[allow(clippy::doc_markdown)]
|
||||||
fn version() -> String {
|
fn version() -> String {
|
||||||
let cargo_pkg_version = env!("CARGO_PKG_VERSION");
|
let cargo_pkg_version = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
@ -28,4 +29,5 @@ pub struct Args {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse commandline arguments into structured data
|
/// Parse commandline arguments into structured data
|
||||||
|
#[must_use]
|
||||||
pub fn parse() -> Args { Args::parse() }
|
pub fn parse() -> Args { Args::parse() }
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeSet,
|
||||||
fmt,
|
fmt::{self, Write as _},
|
||||||
fmt::Write as _,
|
|
||||||
net::{IpAddr, Ipv4Addr},
|
net::{IpAddr, Ipv4Addr},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
@ -11,7 +10,7 @@ use figment::Figment;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use regex::RegexSet;
|
use regex::RegexSet;
|
||||||
use ruma::{OwnedRoomId, OwnedServerName, RoomVersionId};
|
use ruma::{OwnedRoomId, OwnedServerName, RoomVersionId};
|
||||||
use serde::{de::IgnoredAny, Deserialize};
|
use serde::Deserialize;
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
|
||||||
use self::proxy::ProxyConfig;
|
use self::proxy::ProxyConfig;
|
||||||
|
@ -27,6 +26,7 @@ pub struct ListeningPort {
|
||||||
|
|
||||||
/// all the config options for conduwuit
|
/// all the config options for conduwuit
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// [`IpAddr`] conduwuit will listen on (can be IPv4 or IPv6)
|
/// [`IpAddr`] conduwuit will listen on (can be IPv4 or IPv6)
|
||||||
#[serde(default = "default_address")]
|
#[serde(default = "default_address")]
|
||||||
|
@ -216,7 +216,7 @@ pub struct Config {
|
||||||
pub block_non_admin_invites: bool,
|
pub block_non_admin_invites: bool,
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub catchall: BTreeMap<String, IgnoredAny>,
|
pub catchall: BTreeSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
@ -238,7 +238,7 @@ impl Config {
|
||||||
pub fn warn_deprecated(&self) {
|
pub fn warn_deprecated(&self) {
|
||||||
debug!("Checking for deprecated config keys");
|
debug!("Checking for deprecated config keys");
|
||||||
let mut was_deprecated = false;
|
let mut was_deprecated = false;
|
||||||
for key in self.catchall.keys().filter(|key| DEPRECATED_KEYS.iter().any(|s| s == key)) {
|
for key in self.catchall.iter().filter(|key| DEPRECATED_KEYS.iter().any(|s| s == key)) {
|
||||||
warn!("Config parameter \"{}\" is deprecated, ignoring.", key);
|
warn!("Config parameter \"{}\" is deprecated, ignoring.", key);
|
||||||
was_deprecated = true;
|
was_deprecated = true;
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ impl Config {
|
||||||
pub fn warn_unknown_key(&self) {
|
pub fn warn_unknown_key(&self) {
|
||||||
debug!("Checking for unknown config keys");
|
debug!("Checking for unknown config keys");
|
||||||
for key in
|
for key in
|
||||||
self.catchall.keys().filter(|key| "config".to_owned().ne(key.to_owned()) /* "config" is expected */)
|
self.catchall.iter().filter(|key| "config".to_owned().ne(key.to_owned()) /* "config" is expected */)
|
||||||
{
|
{
|
||||||
warn!("Config parameter \"{}\" is unknown to conduwuit, ignoring.", key);
|
warn!("Config parameter \"{}\" is unknown to conduwuit, ignoring.", key);
|
||||||
}
|
}
|
||||||
|
@ -589,11 +589,13 @@ fn default_rocksdb_compression_algo() -> String { "zstd".to_owned() }
|
||||||
/// Default RocksDB compression level is 32767, which is internally read by
|
/// Default RocksDB compression level is 32767, which is internally read by
|
||||||
/// RocksDB as the default magic number and translated to the library's default
|
/// RocksDB as the default magic number and translated to the library's default
|
||||||
/// compression level as they all differ. See their `kDefaultCompressionLevel`.
|
/// compression level as they all differ. See their `kDefaultCompressionLevel`.
|
||||||
|
#[allow(clippy::doc_markdown)]
|
||||||
fn default_rocksdb_compression_level() -> i32 { 32767 }
|
fn default_rocksdb_compression_level() -> i32 { 32767 }
|
||||||
|
|
||||||
/// Default RocksDB compression level is 32767, which is internally read by
|
/// Default RocksDB compression level is 32767, which is internally read by
|
||||||
/// RocksDB as the default magic number and translated to the library's default
|
/// RocksDB as the default magic number and translated to the library's default
|
||||||
/// compression level as they all differ. See their `kDefaultCompressionLevel`.
|
/// compression level as they all differ. See their `kDefaultCompressionLevel`.
|
||||||
|
#[allow(clippy::doc_markdown)]
|
||||||
fn default_rocksdb_bottommost_compression_level() -> i32 { 32767 }
|
fn default_rocksdb_bottommost_compression_level() -> i32 { 32767 }
|
||||||
|
|
||||||
// I know, it's a great name
|
// I know, it's a great name
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl std::str::FromStr for WildCardedDomain {
|
||||||
Ok(if s.starts_with("*.") {
|
Ok(if s.starts_with("*.") {
|
||||||
WildCardedDomain::WildCarded(s[1..].to_owned())
|
WildCardedDomain::WildCarded(s[1..].to_owned())
|
||||||
} else if s == "*" {
|
} else if s == "*" {
|
||||||
WildCardedDomain::WildCarded("".to_owned())
|
WildCardedDomain::WildCarded(String::new())
|
||||||
} else {
|
} else {
|
||||||
WildCardedDomain::Exact(s.to_owned())
|
WildCardedDomain::Exact(s.to_owned())
|
||||||
})
|
})
|
||||||
|
|
|
@ -95,7 +95,6 @@ fn db_options(
|
||||||
|
|
||||||
// Compression
|
// Compression
|
||||||
let rocksdb_compression_algo = match config.rocksdb_compression_algo.as_ref() {
|
let rocksdb_compression_algo = match config.rocksdb_compression_algo.as_ref() {
|
||||||
"zstd" => rust_rocksdb::DBCompressionType::Zstd,
|
|
||||||
"zlib" => rust_rocksdb::DBCompressionType::Zlib,
|
"zlib" => rust_rocksdb::DBCompressionType::Zlib,
|
||||||
"lz4" => rust_rocksdb::DBCompressionType::Lz4,
|
"lz4" => rust_rocksdb::DBCompressionType::Lz4,
|
||||||
"bz2" => rust_rocksdb::DBCompressionType::Bz2,
|
"bz2" => rust_rocksdb::DBCompressionType::Bz2,
|
||||||
|
@ -247,7 +246,7 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
|
||||||
let ret = if self.config.database_backups_to_keep > 0 {
|
let ret = if self.config.database_backups_to_keep > 0 {
|
||||||
match engine.create_new_backup_flush(&self.rocks, true) {
|
match engine.create_new_backup_flush(&self.rocks, true) {
|
||||||
Err(e) => return Err(Box::new(e)),
|
Err(e) => return Err(Box::new(e)),
|
||||||
Ok(_) => {
|
Ok(()) => {
|
||||||
let _info = engine.get_backup_info();
|
let _info = engine.get_backup_info();
|
||||||
let info = &_info.last().unwrap();
|
let info = &_info.last().unwrap();
|
||||||
info!(
|
info!(
|
||||||
|
@ -435,7 +434,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
||||||
let lock = self.write_lock.write().unwrap();
|
let lock = self.write_lock.write().unwrap();
|
||||||
|
|
||||||
let old = self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?;
|
let old = self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?;
|
||||||
let new = utils::increment(old.as_deref()).unwrap();
|
let new = utils::increment(old.as_deref());
|
||||||
self.db.rocks.put_cf_opt(&self.cf(), key, &new, &writeoptions)?;
|
self.db.rocks.put_cf_opt(&self.cf(), key, &new, &writeoptions)?;
|
||||||
|
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
@ -458,7 +457,7 @@ impl KvTree for RocksDbEngineTree<'_> {
|
||||||
|
|
||||||
for key in iter {
|
for key in iter {
|
||||||
let old = self.db.rocks.get_cf_opt(&self.cf(), &key, &readoptions)?;
|
let old = self.db.rocks.get_cf_opt(&self.cf(), &key, &readoptions)?;
|
||||||
let new = utils::increment(old.as_deref()).unwrap();
|
let new = utils::increment(old.as_deref());
|
||||||
batch.put_cf(&self.cf(), key, new);
|
batch.put_cf(&self.cf(), key, new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,12 +263,11 @@ lasttimelinecount_cache: {lasttimelinecount_cache}\n"
|
||||||
.server_signingkeys
|
.server_signingkeys
|
||||||
.get(origin.as_bytes())?
|
.get(origin.as_bytes())?
|
||||||
.and_then(|bytes| serde_json::from_slice(&bytes).ok())
|
.and_then(|bytes| serde_json::from_slice(&bytes).ok())
|
||||||
.map(|keys: ServerSigningKeys| {
|
.map_or_else(BTreeMap::new, |keys: ServerSigningKeys| {
|
||||||
let mut tree = keys.verify_keys;
|
let mut tree = keys.verify_keys;
|
||||||
tree.extend(keys.old_verify_keys.into_iter().map(|old| (old.0, VerifyKey::new(old.1.key))));
|
tree.extend(keys.old_verify_keys.into_iter().map(|old| (old.0, VerifyKey::new(old.1.key))));
|
||||||
tree
|
tree
|
||||||
})
|
});
|
||||||
.unwrap_or_else(BTreeMap::new);
|
|
||||||
|
|
||||||
Ok(signingkeys)
|
Ok(signingkeys)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl service::pusher::Data for KeyValueDatabase {
|
||||||
let mut key = sender.as_bytes().to_vec();
|
let mut key = sender.as_bytes().to_vec();
|
||||||
key.push(0xFF);
|
key.push(0xFF);
|
||||||
key.extend_from_slice(ids.pushkey.as_bytes());
|
key.extend_from_slice(ids.pushkey.as_bytes());
|
||||||
self.senderkey_pusher.remove(&key).map(|_| ()).map_err(Into::into)
|
self.senderkey_pusher.remove(&key).map_err(Into::into)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,9 @@ impl service::rooms::user::Data for KeyValueDatabase {
|
||||||
userroom_id.push(0xFF);
|
userroom_id.push(0xFF);
|
||||||
userroom_id.extend_from_slice(room_id.as_bytes());
|
userroom_id.extend_from_slice(room_id.as_bytes());
|
||||||
|
|
||||||
self.userroomid_notificationcount
|
self.userroomid_notificationcount.get(&userroom_id)?.map_or(Ok(0), |bytes| {
|
||||||
.get(&userroom_id)?
|
utils::u64_from_bytes(&bytes).map_err(|_| Error::bad_database("Invalid notification count in db."))
|
||||||
.map(|bytes| {
|
})
|
||||||
utils::u64_from_bytes(&bytes).map_err(|_| Error::bad_database("Invalid notification count in db."))
|
|
||||||
})
|
|
||||||
.unwrap_or(Ok(0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn highlight_count(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
|
fn highlight_count(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
|
||||||
|
@ -37,12 +34,9 @@ impl service::rooms::user::Data for KeyValueDatabase {
|
||||||
userroom_id.push(0xFF);
|
userroom_id.push(0xFF);
|
||||||
userroom_id.extend_from_slice(room_id.as_bytes());
|
userroom_id.extend_from_slice(room_id.as_bytes());
|
||||||
|
|
||||||
self.userroomid_highlightcount
|
self.userroomid_highlightcount.get(&userroom_id)?.map_or(Ok(0), |bytes| {
|
||||||
.get(&userroom_id)?
|
utils::u64_from_bytes(&bytes).map_err(|_| Error::bad_database("Invalid highlight count in db."))
|
||||||
.map(|bytes| {
|
})
|
||||||
utils::u64_from_bytes(&bytes).map_err(|_| Error::bad_database("Invalid highlight count in db."))
|
|
||||||
})
|
|
||||||
.unwrap_or(Ok(0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
|
fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
|
||||||
|
|
|
@ -125,7 +125,7 @@ impl service::users::Data for KeyValueDatabase {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the avatar_url of a user.
|
/// Get the `avatar_url` of a user.
|
||||||
fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>> {
|
fn avatar_url(&self, user_id: &UserId) -> Result<Option<OwnedMxcUri>> {
|
||||||
self.userid_avatarurl
|
self.userid_avatarurl
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
|
@ -324,13 +324,10 @@ impl service::users::Data for KeyValueDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_one_time_keys_update(&self, user_id: &UserId) -> Result<u64> {
|
fn last_one_time_keys_update(&self, user_id: &UserId) -> Result<u64> {
|
||||||
self.userid_lastonetimekeyupdate
|
self.userid_lastonetimekeyupdate.get(user_id.as_bytes())?.map_or(Ok(0), |bytes| {
|
||||||
.get(user_id.as_bytes())?
|
utils::u64_from_bytes(&bytes)
|
||||||
.map(|bytes| {
|
.map_err(|_| Error::bad_database("Count in roomid_lastroomactiveupdate is invalid."))
|
||||||
utils::u64_from_bytes(&bytes)
|
})
|
||||||
.map_err(|_| Error::bad_database("Count in roomid_lastroomactiveupdate is invalid."))
|
|
||||||
})
|
|
||||||
.unwrap_or(Ok(0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn take_one_time_key(
|
fn take_one_time_key(
|
||||||
|
@ -817,7 +814,7 @@ impl KeyValueDatabase {}
|
||||||
|
|
||||||
/// Will only return with Some(username) if the password was not empty and the
|
/// Will only return with Some(username) if the password was not empty and the
|
||||||
/// username could be successfully parsed.
|
/// username could be successfully parsed.
|
||||||
/// If utils::string_from_bytes(...) returns an error that username will be
|
/// If `utils::string_from_bytes`(...) returns an error that username will be
|
||||||
/// skipped and the error will be logged.
|
/// skipped and the error will be logged.
|
||||||
fn get_username_with_valid_password(username: &[u8], password: &[u8]) -> Option<String> {
|
fn get_username_with_valid_password(username: &[u8], password: &[u8]) -> Option<String> {
|
||||||
// A valid password is not empty
|
// A valid password is not empty
|
||||||
|
|
|
@ -120,8 +120,8 @@ pub struct KeyValueDatabase {
|
||||||
pub(super) roomsynctoken_shortstatehash: Arc<dyn KvTree>,
|
pub(super) roomsynctoken_shortstatehash: Arc<dyn KvTree>,
|
||||||
/// Remember the state hash at events in the past.
|
/// Remember the state hash at events in the past.
|
||||||
pub(super) shorteventid_shortstatehash: Arc<dyn KvTree>,
|
pub(super) shorteventid_shortstatehash: Arc<dyn KvTree>,
|
||||||
/// StateKey = EventType + StateKey, ShortStateKey = Count
|
pub(super) statekey_shortstatekey: Arc<dyn KvTree>, /* StateKey = EventType + StateKey, ShortStateKey =
|
||||||
pub(super) statekey_shortstatekey: Arc<dyn KvTree>,
|
* Count */
|
||||||
pub(super) shortstatekey_statekey: Arc<dyn KvTree>,
|
pub(super) shortstatekey_statekey: Arc<dyn KvTree>,
|
||||||
|
|
||||||
pub(super) roomid_shortroomid: Arc<dyn KvTree>,
|
pub(super) roomid_shortroomid: Arc<dyn KvTree>,
|
||||||
|
|
|
@ -770,8 +770,8 @@ async fn shutdown_signal(handle: ServerHandle, tx: Sender<()>) -> Result<()> {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = ctrl_c => { sig = "Ctrl+C"; },
|
() = ctrl_c => { sig = "Ctrl+C"; },
|
||||||
_ = terminate => { sig = "SIGTERM"; },
|
() = terminate => { sig = "SIGTERM"; },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
|
|
|
@ -790,12 +790,12 @@ impl Service {
|
||||||
"Deleted {} total MXCs from our database and the filesystem from event ID {event_id}.",
|
"Deleted {} total MXCs from our database and the filesystem from event ID {event_id}.",
|
||||||
mxc_deletion_count
|
mxc_deletion_count
|
||||||
)));
|
)));
|
||||||
} else {
|
|
||||||
return Ok(RoomMessageEventContent::text_plain(
|
|
||||||
"Please specify either an MXC using --mxc or an event ID using --event-id of the \
|
|
||||||
message containing an image. See --help for details.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(
|
||||||
|
"Please specify either an MXC using --mxc or an event ID using --event-id of the message \
|
||||||
|
containing an image. See --help for details.",
|
||||||
|
));
|
||||||
},
|
},
|
||||||
MediaCommand::DeleteList => {
|
MediaCommand::DeleteList => {
|
||||||
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
|
||||||
|
@ -814,11 +814,11 @@ impl Service {
|
||||||
filesystem.",
|
filesystem.",
|
||||||
mxc_deletion_count
|
mxc_deletion_count
|
||||||
)));
|
)));
|
||||||
} else {
|
|
||||||
return Ok(RoomMessageEventContent::text_plain(
|
|
||||||
"Expected code block in command body. Add --help for details.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(
|
||||||
|
"Expected code block in command body. Add --help for details.",
|
||||||
|
));
|
||||||
},
|
},
|
||||||
MediaCommand::DeletePastRemoteMedia {
|
MediaCommand::DeletePastRemoteMedia {
|
||||||
duration,
|
duration,
|
||||||
|
@ -1322,12 +1322,12 @@ impl Service {
|
||||||
ignoring error and logging here: {e}"
|
ignoring error and logging here: {e}"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
|
||||||
"{room_id} is not a valid room ID, please fix the list and try \
|
|
||||||
again: {e}"
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
|
"{room_id} is not a valid room ID, please fix the list and try again: \
|
||||||
|
{e}"
|
||||||
|
)));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1415,17 +1415,16 @@ impl Service {
|
||||||
disabled incoming federation with the room.",
|
disabled incoming federation with the room.",
|
||||||
room_ban_count
|
room_ban_count
|
||||||
)));
|
)));
|
||||||
} else {
|
|
||||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
|
||||||
"Finished bulk room ban, banned {} total rooms and evicted all users.",
|
|
||||||
room_ban_count
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
} else {
|
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||||
return Ok(RoomMessageEventContent::text_plain(
|
"Finished bulk room ban, banned {} total rooms and evicted all users.",
|
||||||
"Expected code block in command body. Add --help for details.",
|
room_ban_count
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(RoomMessageEventContent::text_plain(
|
||||||
|
"Expected code block in command body. Add --help for details.",
|
||||||
|
));
|
||||||
},
|
},
|
||||||
RoomModeration::UnbanRoom {
|
RoomModeration::UnbanRoom {
|
||||||
room,
|
room,
|
||||||
|
@ -1856,7 +1855,7 @@ impl Service {
|
||||||
|
|
||||||
let pub_key_map = pub_key_map.read().await;
|
let pub_key_map = pub_key_map.read().await;
|
||||||
match ruma::signatures::verify_json(&pub_key_map, &value) {
|
match ruma::signatures::verify_json(&pub_key_map, &value) {
|
||||||
Ok(_) => RoomMessageEventContent::text_plain("Signature correct"),
|
Ok(()) => RoomMessageEventContent::text_plain("Signature correct"),
|
||||||
Err(e) => RoomMessageEventContent::text_plain(format!(
|
Err(e) => RoomMessageEventContent::text_plain(format!(
|
||||||
"Signature verification failed: {e}"
|
"Signature verification failed: {e}"
|
||||||
)),
|
)),
|
||||||
|
@ -1913,7 +1912,7 @@ impl Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut result = tokio::task::spawn_blocking(move || match services().globals.db.backup() {
|
let mut result = tokio::task::spawn_blocking(move || match services().globals.db.backup() {
|
||||||
Ok(_) => String::new(),
|
Ok(()) => String::new(),
|
||||||
Err(e) => (*e).to_string(),
|
Err(e) => (*e).to_string(),
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
|
@ -2040,7 +2039,7 @@ impl Service {
|
||||||
.send_federation_request(
|
.send_federation_request(
|
||||||
&server,
|
&server,
|
||||||
ruma::api::federation::event::get_event::v1::Request {
|
ruma::api::federation::event::get_event::v1::Request {
|
||||||
event_id: event_id.to_owned().into(),
|
event_id: event_id.clone().into(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -2208,7 +2207,7 @@ impl Service {
|
||||||
if let Some(line_index) = text_lines.iter().position(|line| *line == "[commandbody]") {
|
if let Some(line_index) = text_lines.iter().position(|line| *line == "[commandbody]") {
|
||||||
text_lines.remove(line_index);
|
text_lines.remove(line_index);
|
||||||
|
|
||||||
while text_lines.get(line_index).map(|line| line.starts_with('#')).unwrap_or(false) {
|
while text_lines.get(line_index).is_some_and(|line| line.starts_with('#')) {
|
||||||
command_body += if text_lines[line_index].starts_with("# ") {
|
command_body += if text_lines[line_index].starts_with("# ") {
|
||||||
&text_lines[line_index][2..]
|
&text_lines[line_index][2..]
|
||||||
} else {
|
} else {
|
||||||
|
@ -2293,7 +2292,7 @@ impl Service {
|
||||||
event_type: TimelineEventType::RoomCreate,
|
event_type: TimelineEventType::RoomCreate,
|
||||||
content: to_raw_value(&content).expect("event is valid, we just created it"),
|
content: to_raw_value(&content).expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2346,7 +2345,7 @@ impl Service {
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2365,7 +2364,7 @@ impl Service {
|
||||||
content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite))
|
content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2384,7 +2383,7 @@ impl Service {
|
||||||
content: to_raw_value(&RoomHistoryVisibilityEventContent::new(HistoryVisibility::Shared))
|
content: to_raw_value(&RoomHistoryVisibilityEventContent::new(HistoryVisibility::Shared))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2403,7 +2402,7 @@ impl Service {
|
||||||
content: to_raw_value(&RoomGuestAccessEventContent::new(GuestAccess::Forbidden))
|
content: to_raw_value(&RoomGuestAccessEventContent::new(GuestAccess::Forbidden))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2423,7 +2422,7 @@ impl Service {
|
||||||
content: to_raw_value(&RoomNameEventContent::new(room_name))
|
content: to_raw_value(&RoomNameEventContent::new(room_name))
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2443,7 +2442,7 @@ impl Service {
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2469,7 +2468,7 @@ impl Service {
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
@ -2579,7 +2578,7 @@ impl Service {
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
state_key: Some("".to_owned()),
|
state_key: Some(String::new()),
|
||||||
redacts: None,
|
redacts: None,
|
||||||
},
|
},
|
||||||
&conduit_user,
|
&conduit_user,
|
||||||
|
|
|
@ -367,7 +367,7 @@ impl Service {
|
||||||
|
|
||||||
// The original create event must be in the auth events
|
// The original create event must be in the auth events
|
||||||
if !matches!(
|
if !matches!(
|
||||||
auth_events.get(&(StateEventType::RoomCreate, "".to_owned())).map(AsRef::as_ref),
|
auth_events.get(&(StateEventType::RoomCreate, String::new())).map(AsRef::as_ref),
|
||||||
Some(_) | None
|
Some(_) | None
|
||||||
) {
|
) {
|
||||||
return Err(Error::BadRequest(
|
return Err(Error::BadRequest(
|
||||||
|
|
|
@ -713,7 +713,7 @@ fn is_accessable_child_recurse(
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
Identifier::None => (),
|
||||||
} // Takes care of joinrules
|
} // Takes care of joinrules
|
||||||
Ok(match join_rule {
|
Ok(match join_rule {
|
||||||
SpaceRoomJoinRule::KnockRestricted | SpaceRoomJoinRule::Restricted => {
|
SpaceRoomJoinRule::KnockRestricted | SpaceRoomJoinRule::Restricted => {
|
||||||
|
@ -734,6 +734,7 @@ fn is_accessable_child_recurse(
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Knock => true,
|
SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Knock => true,
|
||||||
|
#[allow(clippy::match_same_arms)]
|
||||||
SpaceRoomJoinRule::Invite | SpaceRoomJoinRule::Private => false,
|
SpaceRoomJoinRule::Invite | SpaceRoomJoinRule::Private => false,
|
||||||
// Custom join rule
|
// Custom join rule
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -828,7 +829,7 @@ fn allowed_room_ids(join_rule: JoinRule) -> Vec<OwnedRoomId> {
|
||||||
room_id: membership,
|
room_id: membership,
|
||||||
}) = rule
|
}) = rule
|
||||||
{
|
{
|
||||||
room_ids.push(membership.to_owned());
|
room_ids.push(membership.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub trait Data: Send + Sync {
|
||||||
/// Returns the last state hash key added to the db for the given room.
|
/// Returns the last state hash key added to the db for the given room.
|
||||||
fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>>;
|
fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>>;
|
||||||
|
|
||||||
/// Set the state hash to a new version, but does not update state_cache.
|
/// Set the state hash to a new version, but does not update `state_cache`.
|
||||||
fn set_room_state(
|
fn set_room_state(
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
|
@ -20,7 +20,7 @@ pub trait Data: Send + Sync {
|
||||||
/// Associates a state with an event.
|
/// Associates a state with an event.
|
||||||
fn set_event_state(&self, shorteventid: u64, shortstatehash: u64) -> Result<()>;
|
fn set_event_state(&self, shorteventid: u64, shortstatehash: u64) -> Result<()>;
|
||||||
|
|
||||||
/// Returns all events we would send as the prev_events of the next event.
|
/// Returns all events we would send as the `prev_events` of the next event.
|
||||||
fn get_forward_extremities(&self, room_id: &RoomId) -> Result<HashSet<Arc<EventId>>>;
|
fn get_forward_extremities(&self, room_id: &RoomId) -> Result<HashSet<Arc<EventId>>>;
|
||||||
|
|
||||||
/// Replace the forward extremities of the room.
|
/// Replace the forward extremities of the room.
|
||||||
|
|
|
@ -230,9 +230,7 @@ impl Service {
|
||||||
|
|
||||||
pub fn get_name(&self, room_id: &RoomId) -> Result<Option<String>> {
|
pub fn get_name(&self, room_id: &RoomId) -> Result<Option<String>> {
|
||||||
services().rooms.state_accessor.room_state_get(room_id, &StateEventType::RoomName, "")?.map_or(Ok(None), |s| {
|
services().rooms.state_accessor.room_state_get(room_id, &StateEventType::RoomName, "")?.map_or(Ok(None), |s| {
|
||||||
Ok(serde_json::from_str(s.content.get())
|
Ok(serde_json::from_str(s.content.get()).map_or_else(|_| None, |c: RoomNameEventContent| Some(c.name)))
|
||||||
.map(|c: RoomNameEventContent| Some(c.name))
|
|
||||||
.unwrap_or_else(|_| None))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -680,7 +680,7 @@ impl Service {
|
||||||
&mut pdu_json,
|
&mut pdu_json,
|
||||||
&room_version_id,
|
&room_version_id,
|
||||||
) {
|
) {
|
||||||
Ok(_) => {},
|
Ok(()) => {},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return match e {
|
return match e {
|
||||||
ruma::signatures::Error::PduSize => {
|
ruma::signatures::Error::PduSize => {
|
||||||
|
|
|
@ -490,11 +490,9 @@ impl Service {
|
||||||
.to_room_event(),
|
.to_room_event(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
SendingEventType::Edu(_) => {
|
SendingEventType::Edu(_) | SendingEventType::Flush => {
|
||||||
// Appservices don't need EDUs (?)
|
// Appservices don't need EDUs (?) and flush only;
|
||||||
},
|
// no new content
|
||||||
SendingEventType::Flush => {
|
|
||||||
// flush only; no new content
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,11 +552,9 @@ impl Service {
|
||||||
})?,
|
})?,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
SendingEventType::Edu(_) => {
|
SendingEventType::Edu(_) | SendingEventType::Flush => {
|
||||||
// Push gateways don't need EDUs (?)
|
// Push gateways don't need EDUs (?) and flush only;
|
||||||
},
|
// no new content
|
||||||
SendingEventType::Flush => {
|
|
||||||
// flush only; no new content
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ impl Error {
|
||||||
| Forbidden
|
| Forbidden
|
||||||
| GuestAccessForbidden
|
| GuestAccessForbidden
|
||||||
| ThreepidAuthFailed
|
| ThreepidAuthFailed
|
||||||
|
| UserDeactivated
|
||||||
| ThreepidDenied => StatusCode::FORBIDDEN,
|
| ThreepidDenied => StatusCode::FORBIDDEN,
|
||||||
Unauthorized
|
Unauthorized
|
||||||
| UnknownToken {
|
| UnknownToken {
|
||||||
|
@ -129,7 +130,6 @@ impl Error {
|
||||||
LimitExceeded {
|
LimitExceeded {
|
||||||
..
|
..
|
||||||
} => StatusCode::TOO_MANY_REQUESTS,
|
} => StatusCode::TOO_MANY_REQUESTS,
|
||||||
UserDeactivated => StatusCode::FORBIDDEN,
|
|
||||||
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
||||||
_ => StatusCode::BAD_REQUEST,
|
_ => StatusCode::BAD_REQUEST,
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub(crate) fn millis_since_unix_epoch() -> u64 {
|
||||||
SystemTime::now().duration_since(UNIX_EPOCH).expect("time is valid").as_millis() as u64
|
SystemTime::now().duration_since(UNIX_EPOCH).expect("time is valid").as_millis() as u64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
|
pub(crate) fn increment(old: Option<&[u8]>) -> Vec<u8> {
|
||||||
let number = match old.map(TryInto::try_into) {
|
let number = match old.map(TryInto::try_into) {
|
||||||
Some(Ok(bytes)) => {
|
Some(Ok(bytes)) => {
|
||||||
let number = u64::from_be_bytes(bytes);
|
let number = u64::from_be_bytes(bytes);
|
||||||
|
@ -27,7 +27,7 @@ pub(crate) fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
|
||||||
_ => 1, // Start at one. since 0 should return the first event in the db
|
_ => 1, // Start at one. since 0 should return the first event in the db
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(number.to_be_bytes().to_vec())
|
number.to_be_bytes().to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_keypair() -> Vec<u8> {
|
pub fn generate_keypair() -> Vec<u8> {
|
||||||
|
@ -50,7 +50,7 @@ pub fn string_from_bytes(bytes: &[u8]) -> Result<String, std::string::FromUtf8Er
|
||||||
String::from_utf8(bytes.to_vec())
|
String::from_utf8(bytes.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a OwnedUserId from bytes.
|
/// Parses a `OwnedUserId` from bytes.
|
||||||
pub fn user_id_from_bytes(bytes: &[u8]) -> Result<OwnedUserId> {
|
pub fn user_id_from_bytes(bytes: &[u8]) -> Result<OwnedUserId> {
|
||||||
OwnedUserId::try_from(
|
OwnedUserId::try_from(
|
||||||
string_from_bytes(bytes).map_err(|_| Error::bad_database("Failed to parse string from bytes"))?,
|
string_from_bytes(bytes).map_err(|_| Error::bad_database("Failed to parse string from bytes"))?,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue