Eliminate remaining conduit unwrap() et al.
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -984,7 +984,7 @@ unnecessary_safety_doc = "warn"
|
|||||||
unnecessary_self_imports = "warn"
|
unnecessary_self_imports = "warn"
|
||||||
unneeded_field_pattern = "warn"
|
unneeded_field_pattern = "warn"
|
||||||
unseparated_literal_suffix = "warn"
|
unseparated_literal_suffix = "warn"
|
||||||
#unwrap_used = "warn" # TODO
|
unwrap_used = "warn"
|
||||||
verbose_file_reads = "warn"
|
verbose_file_reads = "warn"
|
||||||
|
|
||||||
###################
|
###################
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ excessive-nesting-threshold = 8
|
|||||||
type-complexity-threshold = 250 # reduce me to ~200
|
type-complexity-threshold = 250 # reduce me to ~200
|
||||||
cognitive-complexity-threshold = 100 # TODO reduce me ALARA
|
cognitive-complexity-threshold = 100 # TODO reduce me ALARA
|
||||||
|
|
||||||
|
allow-unwrap-in-tests = true
|
||||||
|
|
||||||
#disallowed-macros = [
|
#disallowed-macros = [
|
||||||
# { path = "log::error", reason = "use tuwunel_core::error" },
|
# { path = "log::error", reason = "use tuwunel_core::error" },
|
||||||
# { path = "log::warn", reason = "use tuwunel_core::warn" },
|
# { path = "log::warn", reason = "use tuwunel_core::warn" },
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use tuwunel_core::{
|
|||||||
tokio_metrics::TaskMonitor,
|
tokio_metrics::TaskMonitor,
|
||||||
trace, utils,
|
trace, utils,
|
||||||
utils::{
|
utils::{
|
||||||
|
math::Expected,
|
||||||
stream::{IterStream, ReadyExt},
|
stream::{IterStream, ReadyExt},
|
||||||
string::EMPTY,
|
string::EMPTY,
|
||||||
time::now_secs,
|
time::now_secs,
|
||||||
@@ -377,7 +378,7 @@ pub(super) async fn sign_json(&self) -> Result {
|
|||||||
return Err!("Expected code block in command body. Add --help for details.");
|
return Err!("Expected code block in command body. Add --help for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let string = self.body[1..self.body.len().checked_sub(1).unwrap()].join("\n");
|
let string = self.body[1..self.body.len().expected_sub(1)].join("\n");
|
||||||
let mut value = serde_json::from_str(&string).map_err(|e| err!("Invalid json: {e}"))?;
|
let mut value = serde_json::from_str(&string).map_err(|e| err!("Invalid json: {e}"))?;
|
||||||
|
|
||||||
self.services.server_keys.sign_json(&mut value)?;
|
self.services.server_keys.sign_json(&mut value)?;
|
||||||
@@ -395,7 +396,7 @@ pub(super) async fn verify_json(&self) -> Result {
|
|||||||
return Err!("Expected code block in command body. Add --help for details.");
|
return Err!("Expected code block in command body. Add --help for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let string = self.body[1..self.body.len().checked_sub(1).unwrap()].join("\n");
|
let string = self.body[1..self.body.len().expected_sub(1)].join("\n");
|
||||||
|
|
||||||
let value = serde_json::from_str::<CanonicalJsonObject>(&string)
|
let value = serde_json::from_str::<CanonicalJsonObject>(&string)
|
||||||
.map_err(|e| err!("Invalid json: {e}"))?;
|
.map_err(|e| err!("Invalid json: {e}"))?;
|
||||||
|
|||||||
@@ -233,8 +233,8 @@ pub(crate) async fn register_route(
|
|||||||
let proposed_user_id = UserId::parse_with_server_name(
|
let proposed_user_id = UserId::parse_with_server_name(
|
||||||
utils::random_string(RANDOM_USER_ID_LENGTH).to_lowercase(),
|
utils::random_string(RANDOM_USER_ID_LENGTH).to_lowercase(),
|
||||||
services.globals.server_name(),
|
services.globals.server_name(),
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
if !services.users.exists(&proposed_user_id).await {
|
if !services.users.exists(&proposed_user_id).await {
|
||||||
break proposed_user_id;
|
break proposed_user_id;
|
||||||
}
|
}
|
||||||
@@ -295,8 +295,7 @@ pub(crate) async fn register_route(
|
|||||||
let (worked, uiaainfo) = services
|
let (worked, uiaainfo) = services
|
||||||
.uiaa
|
.uiaa
|
||||||
.try_auth(
|
.try_auth(
|
||||||
&UserId::parse_with_server_name("", services.globals.server_name())
|
&UserId::parse_with_server_name("", services.globals.server_name())?,
|
||||||
.unwrap(),
|
|
||||||
"".into(),
|
"".into(),
|
||||||
auth,
|
auth,
|
||||||
&uiaainfo,
|
&uiaainfo,
|
||||||
@@ -311,8 +310,7 @@ pub(crate) async fn register_route(
|
|||||||
| Some(ref json) => {
|
| Some(ref json) => {
|
||||||
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
|
uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH));
|
||||||
services.uiaa.create(
|
services.uiaa.create(
|
||||||
&UserId::parse_with_server_name("", services.globals.server_name())
|
&UserId::parse_with_server_name("", services.globals.server_name())?,
|
||||||
.unwrap(),
|
|
||||||
"".into(),
|
"".into(),
|
||||||
&uiaainfo,
|
&uiaainfo,
|
||||||
json,
|
json,
|
||||||
|
|||||||
@@ -35,20 +35,19 @@ pub(crate) async fn turn_server_route(
|
|||||||
)
|
)
|
||||||
.expect("time is valid");
|
.expect("time is valid");
|
||||||
|
|
||||||
let user = body.sender_user.unwrap_or_else(|| {
|
let random_user_id = || {
|
||||||
UserId::parse_with_server_name(
|
UserId::parse_with_server_name(
|
||||||
utils::random_string(RANDOM_USER_ID_LENGTH).to_lowercase(),
|
utils::random_string(RANDOM_USER_ID_LENGTH).to_lowercase(),
|
||||||
&services.server.name,
|
&services.server.name,
|
||||||
)
|
)
|
||||||
.unwrap()
|
};
|
||||||
});
|
|
||||||
|
|
||||||
|
let user = body.sender_user.map_or_else(random_user_id, Ok)?;
|
||||||
let username: String = format!("{}:{}", expiry.get(), user);
|
let username: String = format!("{}:{}", expiry.get(), user);
|
||||||
|
|
||||||
let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes())
|
let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes())
|
||||||
.expect("HMAC can take key of any size");
|
.expect("HMAC can take key of any size");
|
||||||
mac.update(username.as_bytes());
|
|
||||||
|
|
||||||
|
mac.update(username.as_bytes());
|
||||||
let password: String = general_purpose::STANDARD.encode(mac.finalize().into_bytes());
|
let password: String = general_purpose::STANDARD.encode(mac.finalize().into_bytes());
|
||||||
|
|
||||||
(username, password)
|
(username, password)
|
||||||
|
|||||||
@@ -3297,7 +3297,7 @@ fn default_jaeger_filter() -> String {
|
|||||||
fn default_tracing_flame_output_path() -> String { "./tracing.folded".to_owned() }
|
fn default_tracing_flame_output_path() -> String { "./tracing.folded".to_owned() }
|
||||||
|
|
||||||
fn default_trusted_servers() -> Vec<OwnedServerName> {
|
fn default_trusted_servers() -> Vec<OwnedServerName> {
|
||||||
vec![OwnedServerName::try_from("matrix.org").unwrap()]
|
vec![OwnedServerName::try_from("matrix.org").expect("valid ServerName")]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// do debug logging by default for debug builds
|
/// do debug logging by default for debug builds
|
||||||
@@ -3499,7 +3499,7 @@ fn default_client_sync_timeout_max() -> u64 { 90000 }
|
|||||||
fn default_access_token_ttl() -> u64 { 604_800 }
|
fn default_access_token_ttl() -> u64 { 604_800 }
|
||||||
|
|
||||||
fn default_deprioritize_joins_through_servers() -> RegexSet {
|
fn default_deprioritize_joins_through_servers() -> RegexSet {
|
||||||
RegexSet::new([r"matrix\.org"]).unwrap()
|
RegexSet::new([r"matrix\.org"]).expect("valid set of regular expressions")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_one_time_key_limit() -> usize { 256 }
|
fn default_one_time_key_limit() -> usize { 256 }
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#![cfg(test)]
|
||||||
#![allow(unused_features)] // 1.96.0-nightly 2026-03-07 bug
|
#![allow(unused_features)] // 1.96.0-nightly 2026-03-07 bug
|
||||||
|
|
||||||
use criterion::{Criterion, criterion_group, criterion_main};
|
use criterion::{Criterion, criterion_group, criterion_main};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#![cfg(test)]
|
||||||
#![allow(unused_features)] // 1.96.0-nightly 2026-03-07 bug
|
#![allow(unused_features)] // 1.96.0-nightly 2026-03-07 bug
|
||||||
|
|
||||||
use criterion::{Criterion, criterion_group, criterion_main};
|
use criterion::{Criterion, criterion_group, criterion_main};
|
||||||
|
|||||||
@@ -159,7 +159,8 @@ fn cors_layer(server: &Server) -> CorsLayer {
|
|||||||
header::AUTHORIZATION,
|
header::AUTHORIZATION,
|
||||||
header::CONTENT_TYPE,
|
header::CONTENT_TYPE,
|
||||||
header::ORIGIN,
|
header::ORIGIN,
|
||||||
HeaderName::from_lowercase(b"x-requested-with").unwrap(),
|
HeaderName::from_lowercase(b"x-requested-with")
|
||||||
|
.expect("valid HTTP HeaderName from lowercase."),
|
||||||
];
|
];
|
||||||
|
|
||||||
let allow_origin_list = server
|
let allow_origin_list = server
|
||||||
|
|||||||
@@ -14,14 +14,26 @@ pub(super) async fn serve(
|
|||||||
addrs: &[SocketAddr],
|
addrs: &[SocketAddr],
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let tls = &server.config.tls;
|
let tls = &server.config.tls;
|
||||||
let certs = tls.certs.as_ref().unwrap();
|
|
||||||
let key = tls.key.as_ref().unwrap();
|
let certs = tls
|
||||||
|
.certs
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| err!(Config("tls.certs", "Invalid or missing TLS certificates")))?;
|
||||||
|
|
||||||
|
let key = tls
|
||||||
|
.key
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| err!(Config("tls.key", "Invalid or missingTLS key")))?;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Note: It is strongly recommended that you use a reverse proxy instead of running \
|
"Note: It is strongly recommended that you use a reverse proxy instead of running \
|
||||||
tuwunel directly with TLS."
|
tuwunel directly with TLS."
|
||||||
);
|
);
|
||||||
debug!("Using direct TLS. Certificate path {certs} and certificate private key path {key}",);
|
|
||||||
|
debug!(
|
||||||
|
"Using direct TLS. Certificate path {certs:?} and certificate private key path {key:?}"
|
||||||
|
);
|
||||||
|
|
||||||
let conf = RustlsConfig::from_pem_file(certs, key)
|
let conf = RustlsConfig::from_pem_file(certs, key)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| err!(Config("tls", "Failed to load certificates or key: {e}")))?;
|
.map_err(|e| err!(Config("tls", "Failed to load certificates or key: {e}")))?;
|
||||||
@@ -29,6 +41,7 @@ pub(super) async fn serve(
|
|||||||
let app = app
|
let app = app
|
||||||
.clone()
|
.clone()
|
||||||
.into_make_service_with_connect_info::<SocketAddr>();
|
.into_make_service_with_connect_info::<SocketAddr>();
|
||||||
|
|
||||||
if tls.dual_protocol {
|
if tls.dual_protocol {
|
||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
join_set.spawn_on(
|
join_set.spawn_on(
|
||||||
|
|||||||
@@ -52,13 +52,18 @@ where
|
|||||||
.map(BytesMut::freeze);
|
.map(BytesMut::freeze);
|
||||||
|
|
||||||
let mut parts = http_request.uri().clone().into_parts();
|
let mut parts = http_request.uri().clone().into_parts();
|
||||||
let old_path_and_query = parts.path_and_query.unwrap().as_str().to_owned();
|
let old_path_and_query = parts
|
||||||
|
.path_and_query
|
||||||
|
.expect("valid request uri path and query")
|
||||||
|
.as_str()
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
let symbol = if old_path_and_query.contains('?') { "&" } else { "?" };
|
let symbol = if old_path_and_query.contains('?') { "&" } else { "?" };
|
||||||
|
|
||||||
parts.path_and_query = Some(
|
parts.path_and_query = Some(
|
||||||
(old_path_and_query + symbol + "access_token=" + hs_token)
|
(old_path_and_query + symbol + "access_token=" + hs_token)
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.expect("valid path and query"),
|
||||||
);
|
);
|
||||||
*http_request.uri_mut() = parts
|
*http_request.uri_mut() = parts
|
||||||
.try_into()
|
.try_into()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#![cfg(test)]
|
||||||
#![allow(unused_features)] // 1.96.0-nightly 2026-03-07 bug
|
#![allow(unused_features)] // 1.96.0-nightly 2026-03-07 bug
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use std::{
|
use std::{sync::Arc, time::Duration};
|
||||||
sync::Arc,
|
|
||||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use ruma::{CanonicalJsonObject, EventId};
|
use ruma::{CanonicalJsonObject, EventId};
|
||||||
use tuwunel_core::{
|
use tuwunel_core::{
|
||||||
Result, debug_info, expected, implement, matrix::pdu::PduEvent, utils::TryReadyExt,
|
Result, debug_info, expected, implement,
|
||||||
|
matrix::pdu::PduEvent,
|
||||||
|
utils::{TryReadyExt, time::now},
|
||||||
};
|
};
|
||||||
use tuwunel_database::{Deserialized, Json, Map};
|
use tuwunel_database::{Deserialized, Json, Map};
|
||||||
|
|
||||||
@@ -35,11 +34,7 @@ impl crate::Service for Service {
|
|||||||
if retention_seconds != 0 {
|
if retention_seconds != 0 {
|
||||||
debug_info!("Cleaning up retained events");
|
debug_info!("Cleaning up retained events");
|
||||||
|
|
||||||
let now = SystemTime::now()
|
let now = now().as_secs();
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
let count = self
|
let count = self
|
||||||
.timeredacted_eventid
|
.timeredacted_eventid
|
||||||
.keys::<(u64, &EventId)>()
|
.keys::<(u64, &EventId)>()
|
||||||
@@ -104,10 +99,7 @@ pub async fn save_original_pdu(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let now = SystemTime::now()
|
let now = now().as_secs();
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
self.eventid_originalpdu
|
self.eventid_originalpdu
|
||||||
.raw_put(event_id, Json(pdu));
|
.raw_put(event_id, Json(pdu));
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ pub async fn redact_pdu<Pdu: Event + Send + Sync>(
|
|||||||
|
|
||||||
let body = pdu["content"]
|
let body = pdu["content"]
|
||||||
.as_object()
|
.as_object()
|
||||||
.unwrap()
|
.and_then(|obj| obj.get("body"))
|
||||||
.get("body")
|
|
||||||
.and_then(|body| body.as_str());
|
.and_then(|body| body.as_str());
|
||||||
|
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
@@ -46,7 +45,7 @@ pub async fn redact_pdu<Pdu: Event + Send + Sync>(
|
|||||||
.deindex_pdu(shortroomid, &pdu_id, body);
|
.deindex_pdu(shortroomid, &pdu_id, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
let room_id = RoomId::parse(pdu["room_id"].as_str().unwrap()).unwrap();
|
let room_id: &RoomId = pdu.get("room_id").try_into()?;
|
||||||
|
|
||||||
let room_version_id = self
|
let room_version_id = self
|
||||||
.services
|
.services
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ use ruma::{
|
|||||||
};
|
};
|
||||||
use tuwunel_core::{
|
use tuwunel_core::{
|
||||||
Err, Error, Result, debug_error, err, implement,
|
Err, Error, Result, debug_error, err, implement,
|
||||||
utils::{ReadyExt, stream::TryIgnore, string::Unquoted},
|
utils::{
|
||||||
|
ReadyExt,
|
||||||
|
stream::{TryExpect, TryIgnore, TryReadyExt},
|
||||||
|
string::Unquoted,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use tuwunel_database::{Deserialized, Ignore, Json};
|
use tuwunel_database::{Deserialized, Ignore, Json};
|
||||||
|
|
||||||
@@ -117,26 +121,23 @@ pub async fn take_one_time_key(
|
|||||||
.db
|
.db
|
||||||
.onetimekeyid_onetimekeys
|
.onetimekeyid_onetimekeys
|
||||||
.raw_stream_prefix(&prefix)
|
.raw_stream_prefix(&prefix)
|
||||||
.ignore_err()
|
.ready_and_then(|(key, val)| {
|
||||||
.map(|(key, val)| {
|
|
||||||
self.db.onetimekeyid_onetimekeys.remove(key);
|
self.db.onetimekeyid_onetimekeys.remove(key);
|
||||||
|
|
||||||
let key = key
|
let key = key
|
||||||
.rsplit(|&b| b == 0xFF)
|
.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| err!(Database("OneTimeKeyId in db is invalid.")))
|
.ok_or_else(|| err!(Database("OneTimeKeyId in db is invalid.")))?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let key = serde_json::from_slice(key)
|
let key = serde_json::from_slice(key)
|
||||||
.map_err(|e| err!(Database("OneTimeKeyId in db is invalid. {e}")))
|
.map_err(|e| err!(Database("OneTimeKeyId in db is invalid. {e}")))?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let val = serde_json::from_slice(val)
|
let val = serde_json::from_slice(val)
|
||||||
.map_err(|e| err!(Database("OneTimeKeys in db are invalid. {e}")))
|
.map_err(|e| err!(Database("OneTimeKeys in db are invalid. {e}")))?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
(key, val)
|
Ok((key, val))
|
||||||
});
|
})
|
||||||
|
.expect_ok();
|
||||||
|
|
||||||
pin_mut!(one_time_keys);
|
pin_mut!(one_time_keys);
|
||||||
one_time_keys
|
one_time_keys
|
||||||
|
|||||||
Reference in New Issue
Block a user