Fix Clippy warnings blocking release checks
Some checks failed
Validate authentication / Validate authentication (push) Failing after 1s

This commit is contained in:
Alois 2026-10-04 21:14:35 +02:00
commit 976ffde7a8
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
42 changed files with 315 additions and 346 deletions

View file

@ -20,6 +20,8 @@ use uuid::Uuid;
// Waiting Task System // Waiting Task System
// ============================================================================ // ============================================================================
type WaitingTask = Box<dyn Fn(Arc<ClientConnection>, CommunicationValue) -> bool + Send + Sync>;
#[allow(dead_code)] #[allow(dead_code)]
pub struct ClientConnection { pub struct ClientConnection {
sender: Arc<RwLock<Option<Arc<Sender>>>>, sender: Arc<RwLock<Option<Arc<Sender>>>>,
@ -27,8 +29,7 @@ pub struct ClientConnection {
connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>, connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
pub connection_id: Uuid, pub connection_id: Uuid,
shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>, shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>,
pub waiting_tasks: pub waiting_tasks: DashMap<u32, WaitingTask>,
DashMap<u32, Box<dyn Fn(Arc<ClientConnection>, CommunicationValue) -> bool + Send + Sync>>,
shutdown: Arc<RwLock<bool>>, shutdown: Arc<RwLock<bool>>,
keyring: Arc<RwLock<Option<Arc<Keyring>>>>, keyring: Arc<RwLock<Option<Arc<Keyring>>>>,
} }
@ -40,10 +41,7 @@ impl ClientConnection {
connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>, connection_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
connection_id: Uuid, connection_id: Uuid,
shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>, shutdown_tx: Arc<Mutex<Option<watch::Sender<bool>>>>,
waiting_tasks: DashMap< waiting_tasks: DashMap<u32, WaitingTask>,
u32,
Box<dyn Fn(Arc<ClientConnection>, CommunicationValue) -> bool + Send + Sync>,
>,
shutdown: Arc<RwLock<bool>>, shutdown: Arc<RwLock<bool>>,
) -> Self { ) -> Self {
Self { Self {
@ -357,7 +355,6 @@ impl ClientConnection {
.add_typed_default(DataType::Settings, DataValue::Array(settings_json)); .add_typed_default(DataType::Settings, DataValue::Array(settings_json));
self.send_message(&response).await; self.send_message(&response).await;
return;
} }
} }
@ -374,7 +371,7 @@ impl ClientConnection {
if let Some(solved) = solved { if let Some(solved) = solved {
let response = CommunicationValue::new(CommunicationType::ChallengeResponse) let response = CommunicationValue::new(CommunicationType::ChallengeResponse)
.with_request_id(&cv) .with_request_id(cv)
.add_typed_default(DataType::Challenge, DataValue::Str(solved)); .add_typed_default(DataType::Challenge, DataValue::Str(solved));
self.send_message(&response).await; self.send_message(&response).await;

View file

@ -488,12 +488,11 @@ impl InteractableElement for ConsoleCard {
if !key if !key
.modifiers .modifiers
.intersects(KeyModifiers::CONTROL | KeyModifiers::ALT) .intersects(KeyModifiers::CONTROL | KeyModifiers::ALT)
&& let Some(c) = key.code.as_char()
{ {
if let Some(c) = key.code.as_char() { self.insert_at_cursor(c);
self.insert_at_cursor(c); self.message = None;
self.message = None; return IotaInteraction::Changed;
return IotaInteraction::Changed;
}
} }
IotaInteraction::Unhandled IotaInteraction::Unhandled
} }

View file

@ -435,7 +435,7 @@ impl JoinableElement for LogCard {
} }
fn as_element(&self) -> &(dyn Element + 'static) { fn as_element(&self) -> &(dyn Element + 'static) {
&*self self
} }
fn as_element_mut(&mut self) -> &mut (dyn Element + 'static) { fn as_element_mut(&mut self) -> &mut (dyn Element + 'static) {
@ -461,7 +461,7 @@ impl InteractableElement for LogCard {
} }
fn as_element(&self) -> &(dyn Element + 'static) { fn as_element(&self) -> &(dyn Element + 'static) {
&*self self
} }
fn as_element_mut(&mut self) -> &mut (dyn Element + 'static) { fn as_element_mut(&mut self) -> &mut (dyn Element + 'static) {

View file

@ -137,6 +137,12 @@ impl HelpOverlay {
} }
} }
impl Default for HelpOverlay {
fn default() -> Self {
Self::new()
}
}
impl IotaScreen for HelpOverlay { impl IotaScreen for HelpOverlay {
fn render_legacy(&self, f: &mut Frame, rect: Rect, theme: &ResolvedTheme, _hits: &mut HitMap) { fn render_legacy(&self, f: &mut Frame, rect: Rect, theme: &ResolvedTheme, _hits: &mut HitMap) {
let area = ratatool::layout::centered_rect( let area = ratatool::layout::centered_rect(

View file

@ -1,3 +1,8 @@
#![allow(
clippy::module_inception,
reason = "preserve existing public module paths"
)]
pub mod elements { pub mod elements {
pub mod console_card; pub mod console_card;
pub mod elements; pub mod elements;

View file

@ -334,7 +334,7 @@ fn table_to_lines(table: Vec<Vec<String>>, theme: &ResolvedTheme) -> Vec<Display
.max() .max()
.unwrap_or(h_len) .unwrap_or(h_len)
} else { } else {
let max = (3 * h_len) as usize; let max = 3 * h_len;
max.max(h_len) max.max(h_len)
} }
}) })

View file

@ -198,7 +198,7 @@ impl IotaScreen for TermsCheckerScreen {
} }
while size.height - 5 < text_lines.len() as u16 { while size.height - 5 < text_lines.len() as u16 {
if optional_lines.len() == 0 { if optional_lines.is_empty() {
break; break;
} }
text_lines.remove(optional_lines[0] as usize); text_lines.remove(optional_lines[0] as usize);
@ -232,7 +232,7 @@ impl IotaScreen for TermsCheckerScreen {
Line::from(vec![ Line::from(vec![
Span::raw("Height: "), Span::raw("Height: "),
Span::styled(format!("{}", size.height), height_style), Span::styled(format!("{}", size.height), height_style),
Span::raw(format!(" / 13")), Span::raw(" / 13".to_string()),
]), ]),
]); ]);
@ -241,7 +241,7 @@ impl IotaScreen for TermsCheckerScreen {
.block( .block(
Block::default() Block::default()
.borders(Borders::ALL) .borders(Borders::ALL)
.title(format!("UI Too Small [Q to Quit]")), .title("UI Too Small [Q to Quit]".to_string()),
); );
f.render_widget(warning, size); f.render_widget(warning, size);
return; return;
@ -249,7 +249,7 @@ impl IotaScreen for TermsCheckerScreen {
let consent_block = Paragraph::new(Text::from(text_lines)).block( let consent_block = Paragraph::new(Text::from(text_lines)).block(
Block::default() Block::default()
.title(format!(" Tensamin User Consent [Q to Quit] ",)) .title(" Tensamin User Consent [Q to Quit] ".to_string())
.borders(Borders::ALL), .borders(Borders::ALL),
); );
f.render_widget(consent_block, chunks[0]); f.render_widget(consent_block, chunks[0]);

View file

@ -513,7 +513,7 @@ impl IotaScreen for TermsUpdaterScreen {
}; };
while size.height - 5 < text_lines.len() as u16 { while size.height - 5 < text_lines.len() as u16 {
if optional_lines.len() == 0 { if optional_lines.is_empty() {
break; break;
} }
text_lines.remove(optional_lines[0] as usize); text_lines.remove(optional_lines[0] as usize);
@ -632,7 +632,7 @@ impl IotaScreen for TermsUpdaterScreen {
if let Some(sender) = self.sender.take() { if let Some(sender) = self.sender.take() {
let _ = sender.send(UserChoice::Deny); let _ = sender.send(UserChoice::Deny);
} }
return IotaInteraction::Pop; IotaInteraction::Pop
} }
KeyCode::Enter | KeyCode::Char(' ') => match self.focus { KeyCode::Enter | KeyCode::Char(' ') => match self.focus {
Focus::Eula => { Focus::Eula => {
@ -678,9 +678,7 @@ impl IotaScreen for TermsUpdaterScreen {
}; };
if let Some(terms_type) = terms_type { if let Some(terms_type) = terms_type {
return IotaInteraction::Effect(IotaEffect::LoadNewestTerms { IotaInteraction::Effect(IotaEffect::LoadNewestTerms { kind: terms_type })
kind: terms_type,
});
} else { } else {
IotaInteraction::Unhandled IotaInteraction::Unhandled
} }

View file

@ -698,7 +698,7 @@ impl IotaScreen for UsersScreen {
} }
Err(error) => self.message = Some(error), Err(error) => self.message = Some(error),
} }
return IotaInteraction::Changed; IotaInteraction::Changed
} }
UiEvent::Message(IotaMessage::Event(AppEvent::UserOperationFinished(result))) => { UiEvent::Message(IotaMessage::Event(AppEvent::UserOperationFinished(result))) => {
self.pending = false; self.pending = false;
@ -706,7 +706,7 @@ impl IotaScreen for UsersScreen {
Ok(message) => message, Ok(message) => message,
Err(error) => error, Err(error) => error,
}); });
return self.refresh(); self.refresh()
} }
UiEvent::Message(IotaMessage::Event(AppEvent::CredentialExportFinished(result))) => { UiEvent::Message(IotaMessage::Event(AppEvent::CredentialExportFinished(result))) => {
self.pending = false; self.pending = false;
@ -714,7 +714,7 @@ impl IotaScreen for UsersScreen {
Ok(message) => message, Ok(message) => message,
Err(error) => error, Err(error) => error,
}); });
return IotaInteraction::Changed; IotaInteraction::Changed
} }
UiEvent::Message(IotaMessage::Event(AppEvent::TuInspected(result))) => { UiEvent::Message(IotaMessage::Event(AppEvent::TuInspected(result))) => {
if let Some(UsersOverlay::Add(flow)) = self.overlay.as_mut() { if let Some(UsersOverlay::Add(flow)) = self.overlay.as_mut() {
@ -727,7 +727,7 @@ impl IotaScreen for UsersScreen {
} }
} }
} }
return IotaInteraction::Changed; IotaInteraction::Changed
} }
UiEvent::Paste(text) => { UiEvent::Paste(text) => {
if let Some(UsersOverlay::Add(flow)) = self.overlay.as_mut() { if let Some(UsersOverlay::Add(flow)) = self.overlay.as_mut() {
@ -753,7 +753,7 @@ impl IotaScreen for UsersScreen {
self.restore_selection(); self.restore_selection();
return IotaInteraction::Changed; return IotaInteraction::Changed;
} }
return IotaInteraction::Unhandled; IotaInteraction::Unhandled
} }
UiEvent::Key(key) => { UiEvent::Key(key) => {
if let Some(overlay) = &mut self.overlay { if let Some(overlay) = &mut self.overlay {

View file

@ -129,7 +129,7 @@ impl UiConfig {
} }
pub fn load() -> Result<Self, io::Error> { pub fn load() -> Result<Self, io::Error> {
let path = match (|| std::panic::catch_unwind(|| Self::path()))() { let path = match std::panic::catch_unwind(Self::path) {
Ok(path) => path, Ok(path) => path,
Err(_) => Self::fallback_path().ok_or_else(|| { Err(_) => Self::fallback_path().ok_or_else(|| {
io::Error::new(io::ErrorKind::NotFound, "could not determine config path") io::Error::new(io::ErrorKind::NotFound, "could not determine config path")

View file

@ -129,13 +129,11 @@ pub fn resolve_with_capabilities(
}; };
theme.name = name; theme.name = name;
theme.unicode = unicode_enabled; theme.unicode = unicode_enabled;
if !unicode_enabled { if !unicode_enabled && matches!(theme.console.cursor, CursorPresentation::Character { .. }) {
if matches!(theme.console.cursor, CursorPresentation::Character { .. }) { theme.console.cursor = CursorPresentation::Character {
theme.console.cursor = CursorPresentation::Character { glyph: "|",
glyph: "|", style: theme.console.text,
style: theme.console.text, };
};
}
} }
theme theme
} }

View file

@ -27,6 +27,7 @@ fn choice(
suffix, suffix,
} }
} }
#[expect(clippy::too_many_arguments, reason = "explicit theme styles")]
fn base( fn base(
name: ThemeName, name: ThemeName,
normal: Style, normal: Style,

View file

@ -8,6 +8,10 @@ use crate::{
util::terms_focus::Focus, util::terms_focus::Focus,
}; };
#[expect(
clippy::too_many_arguments,
reason = "explicit button layout and styling"
)]
pub fn draw_buttons( pub fn draw_buttons(
frame: &mut ratatui::Frame, frame: &mut ratatui::Frame,
area: Rect, area: Rect,

View file

@ -1,3 +1,8 @@
#![allow(
clippy::result_large_err,
reason = "return protocol error frames directly to the sender"
)]
use crate::message_common::*; use crate::message_common::*;
use iota_logger::{LogLevel, PrintType, log_event}; use iota_logger::{LogLevel, PrintType, log_event};
use iota_storage::util::call_envelopes::{self, CallEnvelope}; use iota_storage::util::call_envelopes::{self, CallEnvelope};
@ -1582,10 +1587,8 @@ pub fn handle_global_settings_save(cv: &CommunicationValue) -> CommunicationValu
.with_request_id(cv); .with_request_id(cv);
if let Some(session_id) = cv.get_data(DataType::SessionId).as_number() { if let Some(session_id) = cv.get_data(DataType::SessionId).as_number() {
response = response.add_typed_default( response =
DataType::SessionId, response.add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataValue::SignedNumber(session_id as i128),
);
} }
response response
@ -1612,10 +1615,8 @@ pub fn handle_global_settings_load(cv: &CommunicationValue) -> CommunicationValu
); );
if let Some(session_id) = cv.get_data(DataType::SessionId).as_number() { if let Some(session_id) = cv.get_data(DataType::SessionId).as_number() {
response = response.add_typed_default( response = response
DataType::SessionId, .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataValue::SignedNumber(session_id as i128),
);
} }
return response; return response;
@ -1627,10 +1628,8 @@ pub fn handle_global_settings_load(cv: &CommunicationValue) -> CommunicationValu
.add_typed_default(DataType::Payload, DataValue::Str(settings_value_str)); .add_typed_default(DataType::Payload, DataValue::Str(settings_value_str));
if let Some(session_id) = cv.get_data(DataType::SessionId).as_number() { if let Some(session_id) = cv.get_data(DataType::SessionId).as_number() {
response = response.add_typed_default( response =
DataType::SessionId, response.add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataValue::SignedNumber(session_id as i128),
);
} }
response response
@ -1664,10 +1663,7 @@ pub fn handle_settings_save(
DataType::Message, DataType::Message,
DataValue::Str("Invalid session_id".to_string()), DataValue::Str("Invalid session_id".to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
}; };
let Some(settings_name) = cv.get_data(DataType::SettingsName).as_str() else { let Some(settings_name) = cv.get_data(DataType::SettingsName).as_str() else {
return CommunicationValue::new(CommunicationType::ErrorInvalidData) return CommunicationValue::new(CommunicationType::ErrorInvalidData)
@ -1677,10 +1673,7 @@ pub fn handle_settings_save(
DataType::Message, DataType::Message,
DataValue::Str("Missing settings_name".to_string()), DataValue::Str("Missing settings_name".to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
}; };
let Some(settings_value) = cv.get_data(DataType::Payload).as_str() else { let Some(settings_value) = cv.get_data(DataType::Payload).as_str() else {
return CommunicationValue::new(CommunicationType::ErrorInvalidData) return CommunicationValue::new(CommunicationType::ErrorInvalidData)
@ -1690,10 +1683,7 @@ pub fn handle_settings_save(
DataType::Message, DataType::Message,
DataValue::Str("Missing settings payload".to_string()), DataValue::Str("Missing settings payload".to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
}; };
if !settings_name if !settings_name
@ -1712,10 +1702,7 @@ pub fn handle_settings_save(
DataType::SettingsName, DataType::SettingsName,
DataValue::Str(settings_name.to_string()), DataValue::Str(settings_name.to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
} }
let Ok(session_id_i64) = i64::try_from(session_id) else { let Ok(session_id_i64) = i64::try_from(session_id) else {
return error_response(cv, CommunicationType::ErrorInvalidData); return error_response(cv, CommunicationType::ErrorInvalidData);
@ -1732,10 +1719,7 @@ pub fn handle_settings_save(
DataType::SettingsName, DataType::SettingsName,
DataValue::Str(settings_name.to_string()), DataValue::Str(settings_name.to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id))
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
)
} }
pub fn handle_settings_load( pub fn handle_settings_load(
@ -1766,10 +1750,7 @@ pub fn handle_settings_load(
DataType::Message, DataType::Message,
DataValue::Str("Invalid session_id".to_string()), DataValue::Str("Invalid session_id".to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
} }
let Ok(session_id_i64) = i64::try_from(session_id) else { let Ok(session_id_i64) = i64::try_from(session_id) else {
return error_response(cv, CommunicationType::ErrorInvalidData); return error_response(cv, CommunicationType::ErrorInvalidData);
@ -1782,10 +1763,7 @@ pub fn handle_settings_load(
DataType::Message, DataType::Message,
DataValue::Str("Missing settings_name".to_string()), DataValue::Str("Missing settings_name".to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
}; };
if !settings_name if !settings_name
@ -1804,10 +1782,7 @@ pub fn handle_settings_load(
DataType::SettingsName, DataType::SettingsName,
DataValue::Str(settings_name.to_string()), DataValue::Str(settings_name.to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
} }
let Ok(settings_value) = settings::load(my_id_i64, session_id_i64, settings_name) else { let Ok(settings_value) = settings::load(my_id_i64, session_id_i64, settings_name) else {
@ -1821,10 +1796,7 @@ pub fn handle_settings_load(
DataType::SettingsName, DataType::SettingsName,
DataValue::Str(settings_name.to_string()), DataValue::Str(settings_name.to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
}; };
CommunicationValue::new(CommunicationType::SettingsLoad) CommunicationValue::new(CommunicationType::SettingsLoad)
@ -1835,10 +1807,7 @@ pub fn handle_settings_load(
DataType::SettingsName, DataType::SettingsName,
DataValue::Str(settings_name.to_string()), DataValue::Str(settings_name.to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id))
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
)
} }
pub fn handle_settings_list( pub fn handle_settings_list(
@ -1869,10 +1838,7 @@ pub fn handle_settings_list(
DataType::Message, DataType::Message,
DataValue::Str("Invalid session_id".to_string()), DataValue::Str("Invalid session_id".to_string()),
) )
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id));
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
);
} }
let Ok(session_id_i64) = i64::try_from(session_id) else { let Ok(session_id_i64) = i64::try_from(session_id) else {
return error_response(cv, CommunicationType::ErrorInvalidData); return error_response(cv, CommunicationType::ErrorInvalidData);
@ -1886,10 +1852,7 @@ pub fn handle_settings_list(
.with_request_id(cv) .with_request_id(cv)
.with_receiver(my_id) .with_receiver(my_id)
.add_typed_default(DataType::Settings, DataValue::Array(settings_json)) .add_typed_default(DataType::Settings, DataValue::Array(settings_json))
.add_typed_default( .add_typed_default(DataType::SessionId, DataValue::SignedNumber(session_id))
DataType::SessionId,
DataValue::SignedNumber(session_id as i128),
)
} }
fn setting_response( fn setting_response(

View file

@ -186,7 +186,7 @@ async fn get_updates() -> Option<(
{ {
let file = load_file("", "agreements"); let file = load_file("", "agreements");
let accepted_state = ConsentState::from_str(&file).sanitize(); let accepted_state = ConsentState::from_str(&file).sanitize();
save_file("", "agreements", &accepted_state.to_string()); save_file("", "agreements", &accepted_state.serialize());
let eula_update: UpdateDecision = if current_eula.equals_some(&accepted_state.eula) { let eula_update: UpdateDecision = if current_eula.equals_some(&accepted_state.eula) {
if current_eula.equals(&newest_eula) { if current_eula.equals(&newest_eula) {
@ -293,23 +293,23 @@ impl ConsentState {
.unwrap() .unwrap()
.as_secs(); .as_secs();
if let Some(future_eula) = self.future_eula.clone() { if let Some(future_eula) = self.future_eula.clone()
if future_eula.get_time() < current_secs { && future_eula.get_time() < current_secs
self.eula = Some(future_eula); {
self.future_eula = None; self.eula = Some(future_eula);
} self.future_eula = None;
} }
if let Some(future_tos) = self.future_tos.clone() { if let Some(future_tos) = self.future_tos.clone()
if future_tos.get_time() < current_secs { && future_tos.get_time() < current_secs
self.tos = Some(future_tos); {
self.future_tos = None; self.tos = Some(future_tos);
} self.future_tos = None;
} }
if let Some(future_privacy) = self.future_privacy.clone() { if let Some(future_privacy) = self.future_privacy.clone()
if future_privacy.get_time() < current_secs { && future_privacy.get_time() < current_secs
self.privacy = Some(future_privacy); {
self.future_privacy = None; self.privacy = Some(future_privacy);
} self.future_privacy = None;
} }
if !self.accepted_eula { if !self.accepted_eula {
@ -325,10 +325,10 @@ impl ConsentState {
} }
pub fn save_state(&self) { pub fn save_state(&self) {
save_file("", "agreements", &self.to_string()); save_file("", "agreements", &self.serialize());
} }
fn to_string(&self) -> String { fn serialize(&self) -> String {
let current_secs = SystemTime::now() let current_secs = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap() .unwrap()
@ -487,7 +487,8 @@ impl ConsentState {
let future_eula_time = future_eula_time.parse::<u64>().unwrap_or(0); let future_eula_time = future_eula_time.parse::<u64>().unwrap_or(0);
let future_tos_time = future_tos_time.parse::<u64>().unwrap_or(0); let future_tos_time = future_tos_time.parse::<u64>().unwrap_or(0);
let future_pp_time = future_pp_time.parse::<u64>().unwrap_or(0); let future_pp_time = future_pp_time.parse::<u64>().unwrap_or(0);
let state = Self {
Self {
accepted_eula: eula, accepted_eula: eula,
eula: Some(Doc::new(eula_version, eula_hash, Type::EULA, unix)), eula: Some(Doc::new(eula_version, eula_hash, Type::EULA, unix)),
accepted_pp: pp, accepted_pp: pp,
@ -525,9 +526,7 @@ impl ConsentState {
None None
}, },
} }
.sanitize(); .sanitize()
state
} }
} }

View file

@ -37,6 +37,7 @@ struct ClientSubscription {
metric_interval_ms: u64, metric_interval_ms: u64,
} }
#[expect(clippy::large_enum_variant, reason = "keep queued IPC messages inline")]
enum WriterCommand { enum WriterCommand {
Message(DaemonMessage), Message(DaemonMessage),
Flush { Flush {
@ -94,6 +95,7 @@ impl IpcServer {
.join("daemon.lock"); .join("daemon.lock");
let lock = File::options() let lock = File::options()
.create(true) .create(true)
.truncate(false)
.mode(0o600) .mode(0o600)
.read(true) .read(true)
.write(true) .write(true)
@ -478,15 +480,13 @@ async fn handle_client(
Ok(DaemonMessage::LogEntry(entry)) => { Ok(DaemonMessage::LogEntry(entry)) => {
// Filter by subscribed log classes // Filter by subscribed log classes
let log_classes = sub_rx.borrow().log_classes.clone(); let log_classes = sub_rx.borrow().log_classes.clone();
if log_classes.is_empty() if (log_classes.is_empty()
|| log_classes.iter().any(|c| entry.sender == *c) || log_classes.contains(&entry.sender))
{ && let Err(error) = write_client_message(&mut writer, &DaemonMessage::LogEntry(entry)).await {
if let Err(error) = write_client_message(&mut writer, &DaemonMessage::LogEntry(entry)).await {
eprintln!("IPC client writer stopped while sending log message: {error}"); eprintln!("IPC client writer stopped while sending log message: {error}");
session_cancellation.cancel(); session_cancellation.cancel();
break; break;
} }
}
} }
Ok(DaemonMessage::MetricSample(sample)) => { Ok(DaemonMessage::MetricSample(sample)) => {
// Rate-limit metric samples based on subscription interval // Rate-limit metric samples based on subscription interval

View file

@ -3,9 +3,11 @@ use std::time::Duration;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::task::JoinSet; use tokio::task::JoinSet;
type TaskOutcome = (String, Result<(), String>);
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct TaskRegistry { pub struct TaskRegistry {
tasks: Arc<Mutex<JoinSet<(String, Result<(), String>)>>>, tasks: Arc<Mutex<JoinSet<TaskOutcome>>>,
} }
impl TaskRegistry { impl TaskRegistry {

View file

@ -322,6 +322,10 @@ pub struct ResponseEnvelope {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "type", content = "data", rename_all = "snake_case")] #[serde(tag = "type", content = "data", rename_all = "snake_case")]
#[expect(
clippy::large_enum_variant,
reason = "keep IPC response payloads inline"
)]
pub enum ResponseResult { pub enum ResponseResult {
Ok(ResponsePayload), Ok(ResponsePayload),
Error(IpcErrorCode), Error(IpcErrorCode),
@ -724,9 +728,10 @@ pub enum ConnectionStatus {
Disconnected, Disconnected,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum StartupPhase { pub enum StartupPhase {
#[default]
Starting, Starting,
MigratingStorage, MigratingStorage,
LoadingUsers, LoadingUsers,
@ -793,12 +798,6 @@ pub struct ComponentHealth {
pub changed_at_ms: u128, pub changed_at_ms: u128,
} }
impl Default for StartupPhase {
fn default() -> Self {
Self::Starting
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Shared types // Shared types
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View file

@ -189,10 +189,10 @@ pub fn startup_with_log_dir_and_capacity(log_dir: Option<PathBuf>, queue_capacit
format!("{prefix}{resolved_message}") format!("{prefix}{resolved_message}")
); );
if let Some(file) = file.as_mut() { if let Some(file) = file.as_mut()
if let Err(error) = writeln!(file, "{line}") { && let Err(error) = writeln!(file, "{line}")
eprintln!("Unable to write Iota log file: {error}"); {
} eprintln!("Unable to write Iota log file: {error}");
} }
let _ = writeln!(std::io::stderr(), "{timestamp} {line}"); let _ = writeln!(std::io::stderr(), "{timestamp} {line}");
@ -313,10 +313,10 @@ fn report_dropped_logs(
let line = format!( let line = format!(
"{timestamp_ms} level=ERROR component=general direction=internal sender=- event=logger.dropped message={message:?}" "{timestamp_ms} level=ERROR component=general direction=internal sender=- event=logger.dropped message={message:?}"
); );
if let Some(file) = file { if let Some(file) = file
if let Err(error) = writeln!(file, "{line}") { && let Err(error) = writeln!(file, "{line}")
eprintln!("Unable to write Iota log file: {error}"); {
} eprintln!("Unable to write Iota log file: {error}");
} }
eprintln!("{line}"); eprintln!("{line}");
let _ = broadcaster.send(UiLogEntry { let _ = broadcaster.send(UiLogEntry {
@ -632,6 +632,36 @@ fn format_data_container(data: &[(DataTypeId, DataValue)], type_map: &TypeMap) -
.join(", ") .join(", ")
} }
#[macro_export]
macro_rules! log_cv {
($kind:expr, $cv:expr) => {
$crate::log_cv_internal("", &$cv, Some($kind))
};
($cv:expr) => {
$crate::log_cv_internal("", &$cv, None)
};
}
#[macro_export]
macro_rules! log_cv_in {
($kind:expr, $cv:expr) => {
$crate::log_cv_internal("> ", &$cv, Some($kind))
};
($cv:expr) => {
$crate::log_cv_internal("> ", $cv, None)
};
}
#[macro_export]
macro_rules! log_cv_out {
($kind:expr, $cv:expr) => {
$crate::log_cv_internal("< ", &$cv, Some($kind))
};
($cv:expr) => {
$crate::log_cv_internal("< ", $cv, None)
};
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::format_cv; use super::format_cv;
@ -662,33 +692,3 @@ mod tests {
); );
} }
} }
#[macro_export]
macro_rules! log_cv {
($kind:expr, $cv:expr) => {
$crate::log_cv_internal("", &$cv, Some($kind))
};
($cv:expr) => {
$crate::log_cv_internal("", &$cv, None)
};
}
#[macro_export]
macro_rules! log_cv_in {
($kind:expr, $cv:expr) => {
$crate::log_cv_internal("> ", &$cv, Some($kind))
};
($cv:expr) => {
$crate::log_cv_internal("> ", $cv, None)
};
}
#[macro_export]
macro_rules! log_cv_out {
($kind:expr, $cv:expr) => {
$crate::log_cv_internal("< ", &$cv, Some($kind))
};
($cv:expr) => {
$crate::log_cv_internal("< ", $cv, None)
};
}

View file

@ -319,7 +319,7 @@ mod systemd {
} }
let executor: Arc<dyn CommandExecutor> = Arc::new(RealExecutor); let executor: Arc<dyn CommandExecutor> = Arc::new(RealExecutor);
let mut manager = executor let mut manager = executor
.output("systemctl", &["--version", &COMMON[0], &COMMON[1]]) .output("systemctl", &["--version", COMMON[0], COMMON[1]])
.await .await
.ok() .ok()
.filter(|r| r.success) .filter(|r| r.success)
@ -573,10 +573,10 @@ mod systemd {
let deadline = tokio::time::Instant::now() + Duration::from_secs(2); let deadline = tokio::time::Instant::now() + Duration::from_secs(2);
let pid = loop { let pid = loop {
if let Ok(contents) = fs::read_to_string(&pid_file) { if let Ok(contents) = fs::read_to_string(&pid_file)
if let Ok(pid) = contents.parse::<libc::pid_t>() { && let Ok(pid) = contents.parse::<libc::pid_t>()
break pid; {
} break pid;
} }
assert!(tokio::time::Instant::now() < deadline); assert!(tokio::time::Instant::now() < deadline);
tokio::task::yield_now().await; tokio::task::yield_now().await;

View file

@ -215,6 +215,12 @@ impl AppState {
} }
} }
impl Default for AppState {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "legacy-globals")] #[cfg(feature = "legacy-globals")]
#[deprecated(note = "use DaemonState or ClientState")] #[deprecated(note = "use DaemonState or ClientState")]
pub static APP_STATE: LazyLock<Arc<Mutex<AppState>>> = pub static APP_STATE: LazyLock<Arc<Mutex<AppState>>> =
@ -228,7 +234,7 @@ pub static SHUTDOWN: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(false));
pub static RELOAD: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true)); pub static RELOAD: Lazy<RwLock<bool>> = Lazy::new(|| RwLock::new(true));
#[cfg(feature = "legacy-globals")] #[cfg(feature = "legacy-globals")]
#[deprecated(note = "use DaemonState")] #[deprecated(note = "use DaemonState")]
pub static ACTIVE_TASKS: Lazy<DashSet<String>> = Lazy::new(|| DashSet::new()); pub static ACTIVE_TASKS: Lazy<DashSet<String>> = Lazy::new(DashSet::new);
#[cfg(feature = "legacy-globals")] #[cfg(feature = "legacy-globals")]
pub fn setup(state: &DaemonState) { pub fn setup(state: &DaemonState) {

View file

@ -1,4 +1,4 @@
#[derive(Debug, Clone)] #[derive(Debug, Clone, Default)]
pub struct Contact { pub struct Contact {
pub user_id: i64, pub user_id: i64,
pub principal: Option<iota_identity::PrincipalHandle>, pub principal: Option<iota_identity::PrincipalHandle>,
@ -9,20 +9,6 @@ pub struct Contact {
pub notifications_read_at: i64, pub notifications_read_at: i64,
} }
impl Default for Contact {
fn default() -> Self {
Contact {
user_id: 0,
principal: None,
user_name: None,
created_at: 0,
last_message_at: None,
notifications: 0,
notifications_read_at: 0,
}
}
}
impl Contact { impl Contact {
pub fn new(user_id: i64) -> Self { pub fn new(user_id: i64) -> Self {
let created_at = std::time::SystemTime::now() let created_at = std::time::SystemTime::now()

View file

@ -682,12 +682,12 @@ pub fn load_users_sync() -> std::io::Result<()> {
if content.trim().is_empty() { if content.trim().is_empty() {
return Ok(()); return Ok(());
} }
if let Ok(parsed) = json::parse(&content) { if let Ok(parsed) = json::parse(&content)
if let json::JsonValue::Array(arr) = parsed { && let json::JsonValue::Array(arr) = parsed
for j in arr.iter() { {
if let Some(up) = UserProfile::from_json(j) { for j in arr.iter() {
try_add_user(up).map_err(|error| std::io::Error::other(error.to_string()))?; if let Some(up) = UserProfile::from_json(j) {
} try_add_user(up).map_err(|error| std::io::Error::other(error.to_string()))?;
} }
} }
} }

View file

@ -67,7 +67,7 @@ impl UserProfile {
"username" => self.username.clone(), "username" => self.username.clone(),
"public_key" => self.public_key.clone(), "public_key" => self.public_key.clone(),
"created_at" => self.created_at, "created_at" => self.created_at,
"storage" => used_dir_space(&format!("users/{}", self.user_id.to_string())), "storage" => used_dir_space(&format!("users/{}", self.user_id)),
}; };
if let Some(d) = &self.display_name { if let Some(d) = &self.display_name {
obj["display_name"] = d.clone().into(); obj["display_name"] = d.clone().into();
@ -113,7 +113,7 @@ impl UserProfile {
pub fn randomize_reset_token(&mut self) -> String { pub fn randomize_reset_token(&mut self) -> String {
let mut bytes = [0u8; 192]; let mut bytes = [0u8; 192];
OsRng.fill(bytes.as_mut()); OsRng.fill(bytes.as_mut());
let new_token = general_purpose::STANDARD.encode(&bytes); let new_token = general_purpose::STANDARD.encode(bytes);
self.reset_token = Some(new_token.clone()); self.reset_token = Some(new_token.clone());
new_token new_token
} }

View file

@ -40,6 +40,7 @@ pub struct CallEnvelope {
pub fn store(envelope: &CallEnvelope, now: i64) -> Result<bool, StorageError> { pub fn store(envelope: &CallEnvelope, now: i64) -> Result<bool, StorageError> {
db::with_immediate_transaction(|tx| { db::with_immediate_transaction(|tx| {
tx.execute("DELETE FROM call_envelopes WHERE expires_at <= ?1", [now])?; tx.execute("DELETE FROM call_envelopes WHERE expires_at <= ?1", [now])?;
#[expect(clippy::type_complexity, reason = "tuple matches the selected database columns")]
let existing: Option<(i64, i64, i64, String, i64, Vec<u8>, Vec<u8>, String)> = tx.query_row( let existing: Option<(i64, i64, i64, String, i64, Vec<u8>, Vec<u8>, String)> = tx.query_row(
"SELECT owner_omikron_id, inviter_id, created_at, secret_id, version_number, encrypted_secret, kem_ciphertext, wrapping_scheme FROM call_envelopes WHERE recipient_id = ?1 AND call_id = ?2", "SELECT owner_omikron_id, inviter_id, created_at, secret_id, version_number, encrypted_secret, kem_ciphertext, wrapping_scheme FROM call_envelopes WHERE recipient_id = ?1 AND call_id = ?2",
params![envelope.recipient_id, envelope.call_id], params![envelope.recipient_id, envelope.call_id],

View file

@ -30,6 +30,10 @@ impl MessageState {
} }
} }
#[expect(
clippy::should_implement_trait,
reason = "unknown stored states fall back rather than fail parsing"
)]
pub fn from_str(value: &str) -> Self { pub fn from_str(value: &str) -> Self {
match value.to_lowercase().as_str() { match value.to_lowercase().as_str() {
"read" => MessageState::Read, "read" => MessageState::Read,
@ -1024,6 +1028,10 @@ pub fn change_message_state_by_relay_id(
}) })
} }
#[expect(
clippy::too_many_arguments,
reason = "explicit persisted receipt fields"
)]
pub fn record_message_receipt( pub fn record_message_receipt(
storage_owner: i64, storage_owner: i64,
target_signer_id: i64, target_signer_id: i64,
@ -1232,7 +1240,7 @@ pub fn change_message_state(
tx.commit()?; tx.commit()?;
Ok(()) Ok(())
}) })
.map_err(|e: StorageError| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) .map_err(|e: StorageError| std::io::Error::other(e.to_string()))
} }
fn load_reactions( fn load_reactions(
@ -1275,10 +1283,9 @@ fn load_reactions(
if reactions if reactions
.iter() .iter()
.any(|stored: &StoredReaction| stored.reaction == row.1.reaction) .any(|stored: &StoredReaction| stored.reaction == row.1.reaction)
|| reactions.len() < MAX_UNIQUE_REACTIONS_PER_MESSAGE
{ {
reactions.push(row.1); reactions.push(row.1);
} else if reactions.len() < MAX_UNIQUE_REACTIONS_PER_MESSAGE {
reactions.push(row.1);
} }
} }
Ok(map) Ok(map)

View file

@ -127,16 +127,13 @@ pub struct RelayRouterSettings {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
#[derive(Default)]
pub enum WebMode { pub enum WebMode {
#[default]
Disabled, Disabled,
Loopback, Loopback,
Network, Network,
} }
impl Default for WebMode {
fn default() -> Self {
Self::Disabled
}
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
@ -340,14 +337,14 @@ pub fn save_config() {
pub fn save_config_to(path: &Path) { pub fn save_config_to(path: &Path) {
if let Ok(yaml) = serde_yaml::to_string(&**CONFIG.load()) { if let Ok(yaml) = serde_yaml::to_string(&**CONFIG.load()) {
if let Some(parent) = path.parent() { if let Some(parent) = path.parent()
if let Err(error) = fs::create_dir_all(parent) { && let Err(error) = fs::create_dir_all(parent)
eprintln!( {
"Cannot create configuration directory {}: {error}", eprintln!(
parent.display() "Cannot create configuration directory {}: {error}",
); parent.display()
return; );
} return;
} }
if let Err(error) = iota_util::atomic_file::replace(path, yaml.as_bytes(), 3) { if let Err(error) = iota_util::atomic_file::replace(path, yaml.as_bytes(), 3) {
eprintln!("Cannot save {}: {error}", path.display()); eprintln!("Cannot save {}: {error}", path.display());
@ -495,8 +492,10 @@ mod tests {
#[test] #[test]
fn zero_ipc_capacity_is_rejected() { fn zero_ipc_capacity_is_rejected() {
let mut config = IotaConfig::default(); let config = IotaConfig {
config.max_ipc_clients = 0; max_ipc_clients: 0,
..IotaConfig::default()
};
assert!(matches!( assert!(matches!(
validate_config(&config), validate_config(&config),
Err(ConfigError::InvalidMaxIpcClients) Err(ConfigError::InvalidMaxIpcClients)

View file

@ -2116,7 +2116,7 @@ where
let guard = shared let guard = shared
.lock() .lock()
.map_err(|e| format!("DB mutex poisoned: {:?}", e))?; .map_err(|e| format!("DB mutex poisoned: {:?}", e))?;
f(&*guard).map_err(|e| e.to_string()) f(&guard).map_err(|e| e.to_string())
}) })
} }

View file

@ -38,10 +38,10 @@ fn validate(user_id: i64, retention: MessageRetention) -> Result<(), StorageErro
"invalid message storage policy owner".into(), "invalid message storage policy owner".into(),
)); ));
} }
if let MessageRetention::Duration { duration_ms } = retention { if let MessageRetention::Duration { duration_ms } = retention
if !(MIN_RETENTION_DURATION_MS..=MAX_RETENTION_DURATION_MS).contains(&duration_ms) { && !(MIN_RETENTION_DURATION_MS..=MAX_RETENTION_DURATION_MS).contains(&duration_ms)
return Err(StorageError::Other("invalid retention duration".into())); {
} return Err(StorageError::Other("invalid retention duration".into()));
} }
Ok(()) Ok(())
} }

View file

@ -39,10 +39,10 @@ fn validate(user_id: i64, blob_id: &str, blob: Option<&[u8]>) -> Result<(), Stor
if blob_id.is_empty() || blob_id.len() > MAX_BLOB_ID_BYTES { if blob_id.is_empty() || blob_id.len() > MAX_BLOB_ID_BYTES {
return Err(StorageError::Other("invalid blob id".into())); return Err(StorageError::Other("invalid blob id".into()));
} }
if let Some(blob) = blob { if let Some(blob) = blob
if blob.len() > MAX_BLOB_BYTES { && blob.len() > MAX_BLOB_BYTES
return Err(StorageError::Other("blob exceeds size limit".into())); {
} return Err(StorageError::Other("blob exceeds size limit".into()));
} }
Ok(()) Ok(())
} }

View file

@ -16,12 +16,15 @@ impl Type {
Self::PP => "privacy-policy", Self::PP => "privacy-policy",
} }
} }
pub fn to_string(&self) -> String { }
match self {
Self::EULA => "End User License Agreement".to_string(), impl std::fmt::Display for Type {
Self::TOS => "Terms of Service".to_string(), fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Self::PP => "Privacy Policy".to_string(), f.write_str(match self {
} Self::EULA => "End User License Agreement",
Self::TOS => "Terms of Service",
Self::PP => "Privacy Policy",
})
} }
} }

View file

@ -263,10 +263,8 @@ pub fn get_children(path: &str) -> Vec<String> {
}; };
let mut children = Vec::new(); let mut children = Vec::new();
if let Ok(entries) = fs::read_dir(&dir) { if let Ok(entries) = fs::read_dir(&dir) {
for entry in entries { for entry in entries.flatten() {
if let Ok(entry) = entry { children.push(entry.file_name().to_string_lossy().to_string());
children.push(entry.file_name().to_string_lossy().to_string());
}
} }
} }
children children
@ -342,11 +340,11 @@ pub fn get_directory_size(directory: &Path) -> u64 {
let mut size = 0; let mut size = 0;
for entry in WalkDir::new(directory).into_iter().filter_map(|e| e.ok()) { for entry in WalkDir::new(directory).into_iter().filter_map(|e| e.ok()) {
let path = entry.path(); let path = entry.path();
if path.is_file() { if path.is_file()
if let Ok(metadata) = path.metadata() { && let Ok(metadata) = path.metadata()
size += path.file_name().unwrap_or(OsStr::new("")).len() as u64; {
size += metadata.len(); size += path.file_name().unwrap_or(OsStr::new("")).len() as u64;
} size += metadata.len();
} }
} }
size size
@ -427,10 +425,9 @@ fn extract_zip_contents_to_folder(
let mut file = archive.by_index(i)?; let mut file = archive.by_index(i)?;
let entry_path = staging_dir.join(file.sanitized_name()); let entry_path = staging_dir.join(file.sanitized_name());
if i == 0 { if i == 0 && (file.name().ends_with('/') || file.sanitized_name().components().count() == 1)
if file.name().ends_with('/') || file.sanitized_name().components().count() == 1 { {
first_item_name = Some(file.sanitized_name()); first_item_name = Some(file.sanitized_name());
}
} }
if file.name().ends_with('/') { if file.name().ends_with('/') {
@ -461,7 +458,7 @@ fn extract_zip_contents_to_folder(
let src = entry.path(); let src = entry.path();
let dest = target_dir.join(entry.file_name()); let dest = target_dir.join(entry.file_name());
if let Err(_) = fs::rename(&src, &dest) { if fs::rename(&src, &dest).is_err() {
if src.is_file() { if src.is_file() {
fs::copy(&src, &dest)?; fs::copy(&src, &dest)?;
} else { } else {

View file

@ -40,6 +40,10 @@ impl RequiredCommunicationFields for CommunicationValue {
} }
} }
#[allow(
clippy::wrong_self_convention,
reason = "mirror DataValue accessors on optional borrowed values"
)]
pub trait OptionalDataValueExt<'a> { pub trait OptionalDataValueExt<'a> {
fn as_bool(self) -> Option<bool>; fn as_bool(self) -> Option<bool>;
fn as_str(self) -> Option<&'a str>; fn as_str(self) -> Option<&'a str>;

View file

@ -557,8 +557,8 @@ impl CliInvocation {
let parsed = let parsed =
Cli::try_parse_from(std::iter::once("iota".to_owned()).chain(args)).map_err(|error| { Cli::try_parse_from(std::iter::once("iota".to_owned()).chain(args)).map_err(|error| {
match error.kind() { match error.kind() {
ErrorKind::DisplayHelp => return "__help__".to_owned(), ErrorKind::DisplayHelp => "__help__".to_owned(),
ErrorKind::DisplayVersion => return "__version__".to_owned(), ErrorKind::DisplayVersion => "__version__".to_owned(),
_ => error.to_string(), _ => error.to_string(),
} }
}); });

View file

@ -32,7 +32,7 @@ impl Capabilities {
let once = self let once = self
.executable .executable
.as_ref() .as_ref()
.and_then(|_| self.socket.as_ref()) .and(self.socket.as_ref())
.map(|_| ()) .map(|_| ())
.map_err(ToString::to_string); .map_err(ToString::to_string);
let ui = once.clone(); let ui = once.clone();
@ -72,10 +72,10 @@ pub async fn run(
if let Ok(ipc) = IpcClient::connect(&endpoints.local).await { if let Ok(ipc) = IpcClient::connect(&endpoints.local).await {
return Ok(ConnectionContext { ipc }); return Ok(ConnectionContext { ipc });
} }
if endpoints.system != endpoints.local { if endpoints.system != endpoints.local
if let Ok(ipc) = IpcClient::connect(&endpoints.system).await { && let Ok(ipc) = IpcClient::connect(&endpoints.system).await
return Ok(ConnectionContext { ipc }); {
} return Ok(ConnectionContext { ipc });
} }
let options = caps.options(); let options = caps.options();
if !options.iter().any(|o| o.enabled) { if !options.iter().any(|o| o.enabled) {

View file

@ -32,13 +32,13 @@ impl LocalDaemonGuard {
} }
impl Drop for LocalDaemonGuard { impl Drop for LocalDaemonGuard {
fn drop(&mut self) { fn drop(&mut self) {
if !self.committed { if !self.committed
if let Some(mut child) = self.child.take() { && let Some(mut child) = self.child.take()
let _ = child.start_kill(); {
tokio::spawn(async move { let _ = child.start_kill();
let _ = child.wait().await; tokio::spawn(async move {
}); let _ = child.wait().await;
} });
} }
} }
} }

View file

@ -1208,7 +1208,7 @@ fn render_table(payload: &ResponsePayload) {
println!( println!(
"{:<15} {}", "{:<15} {}",
"Authority", "Authority",
format!("{:?}", invitation.authority) format_args!("{:?}", invitation.authority)
); );
println!("{:<15} {}", "Token", invitation.raw_token.0); println!("{:<15} {}", "Token", invitation.raw_token.0);
println!("{:<15} {}", "Expires", invitation.expires_at); println!("{:<15} {}", "Expires", invitation.expires_at);
@ -1298,8 +1298,8 @@ fn render_table(payload: &ResponsePayload) {
println!("No active tasks."); println!("No active tasks.");
return; return;
} }
println!("{}", "NAME"); println!("NAME");
println!("{}", "--------"); println!("--------");
for task in tasks { for task in tasks {
println!("{}", task.name); println!("{}", task.name);
} }
@ -1309,8 +1309,8 @@ fn render_table(payload: &ResponsePayload) {
println!("No component health data available."); println!("No component health data available.");
return; return;
} }
println!("{:<20} {:<10} {}", "COMPONENT", "STATUS", "MESSAGE"); println!("{:<20} {:<10} MESSAGE", "COMPONENT", "STATUS");
println!("{:<20} {:<10} {}", "--------", "--------", "--------"); println!("{:<20} {:<10} --------", "--------", "--------");
for comp in components { for comp in components {
let status_str = match comp.status { let status_str = match comp.status {
iota_ipc::HealthStatus::Healthy => "healthy", iota_ipc::HealthStatus::Healthy => "healthy",
@ -1331,8 +1331,8 @@ fn render_table(payload: &ResponsePayload) {
println!("No communities."); println!("No communities.");
return; return;
} }
println!("{:<20} {}", "NAME", "TITLE"); println!("{:<20} TITLE", "NAME");
println!("{:<20} {}", "--------", "--------"); println!("{:<20} --------", "--------");
for c in communities { for c in communities {
println!("{:<20} {}", c.name, c.title); println!("{:<20} {}", c.name, c.title);
} }
@ -1343,12 +1343,12 @@ fn render_table(payload: &ResponsePayload) {
return; return;
} }
println!( println!(
"{:<20} {:<6} {:<12} {}", "{:<20} {:<6} {:<12} MESSAGE",
"TIMESTAMP", "LEVEL", "SENDER", "MESSAGE" "TIMESTAMP", "LEVEL", "SENDER"
); );
println!( println!(
"{:<20} {:<6} {:<12} {}", "{:<20} {:<6} {:<12} --------",
"--------", "--------", "--------", "--------" "--------", "--------", "--------"
); );
for entry in &logs.entries { for entry in &logs.entries {
let level = if entry.is_error { "ERR" } else { "INF" }; let level = if entry.is_error { "ERR" } else { "INF" };
@ -1359,8 +1359,8 @@ fn render_table(payload: &ResponsePayload) {
} }
} }
ResponsePayload::Status(status) => { ResponsePayload::Status(status) => {
println!("{:<15} {}", "Field", "Value"); println!("{:<15} Value", "Field");
println!("{:<15} {}", "--------", "--------"); println!("{:<15} --------", "--------");
println!("{:<15} {}", "Phase", status.phase); println!("{:<15} {}", "Phase", status.phase);
if !status.tasks.is_empty() { if !status.tasks.is_empty() {
println!("{:<15} {}", "Tasks", status.tasks.join(", ")); println!("{:<15} {}", "Tasks", status.tasks.join(", "));
@ -1376,16 +1376,16 @@ fn render_table(payload: &ResponsePayload) {
println!("{}", config.yaml); println!("{}", config.yaml);
} }
ResponsePayload::OmikronStatus(status) => { ResponsePayload::OmikronStatus(status) => {
println!("{:<15} {}", "Field", "Value"); println!("{:<15} Value", "Field");
println!("{:<15} {}", "--------", "--------"); println!("{:<15} --------", "--------");
println!("{:<15} {}", "Connected", status.connected); println!("{:<15} {}", "Connected", status.connected);
if let Some(id) = &status.iota_id { if let Some(id) = &status.iota_id {
println!("{:<15} {}", "Iota ID", id); println!("{:<15} {}", "Iota ID", id);
} }
} }
ResponsePayload::UpdateStatus(status) => { ResponsePayload::UpdateStatus(status) => {
println!("{:<15} {}", "Field", "Value"); println!("{:<15} Value", "Field");
println!("{:<15} {}", "--------", "--------"); println!("{:<15} --------", "--------");
println!("{:<15} {}", "Available", status.available); println!("{:<15} {}", "Available", status.available);
} }
ResponsePayload::UserCreated { user_id, username } => { ResponsePayload::UserCreated { user_id, username } => {
@ -1428,8 +1428,8 @@ fn render_table(payload: &ResponsePayload) {
println!("{}", message); println!("{}", message);
} }
ResponsePayload::UserDetail(user) => { ResponsePayload::UserDetail(user) => {
println!("{:<15} {}", "Field", "Value"); println!("{:<15} Value", "Field");
println!("{:<15} {}", "--------", "--------"); println!("{:<15} --------", "--------");
println!("{:<15} {}", "Username", user.username); println!("{:<15} {}", "Username", user.username);
println!("{:<15} {}", "User ID", user.user_id); println!("{:<15} {}", "User ID", user.user_id);
if let Some(ref name) = user.display_name { if let Some(ref name) = user.display_name {

View file

@ -73,11 +73,11 @@ async fn accept(system: bool) -> Result<(), StartupError> {
for document in [&documents.0, &documents.1, &documents.2] { for document in [&documents.0, &documents.1, &documents.2] {
println!( println!(
"\n===== {} =====\nVersion: {}\nDocument hash: {}\n", "\n===== {} =====\nVersion: {}\nDocument hash: {}\n",
document.kind().to_string(), document.kind(),
document.version(), document.version(),
document.hash() document.hash()
); );
print!("{}\n", document.content()); println!("{}", document.content());
if !confirm(document)? { if !confirm(document)? {
return Err(StartupError::Consent( return Err(StartupError::Consent(
"No terms were accepted. Iota remains inactive.".into(), "No terms were accepted. Iota remains inactive.".into(),

View file

@ -1,3 +1,8 @@
#![allow(
clippy::result_large_err,
reason = "return protocol error frames directly to the sender"
)]
use base64::{Engine as _, engine::general_purpose::STANDARD}; use base64::{Engine as _, engine::general_purpose::STANDARD};
use dashmap::{DashMap, DashSet}; use dashmap::{DashMap, DashSet};
use iota_logger::{LogLevel, PrintType, log, log_cv_in, log_cv_out, log_event, log_t}; use iota_logger::{LogLevel, PrintType, log, log_cv_in, log_cv_out, log_event, log_t};
@ -350,7 +355,7 @@ pub struct WaitingTask {
pub inserted_at: Instant, pub inserted_at: Instant,
} }
pub static WAITING_TASKS: LazyLock<DashMap<u32, WaitingTask>> = LazyLock::new(|| DashMap::new()); pub static WAITING_TASKS: LazyLock<DashMap<u32, WaitingTask>> = LazyLock::new(DashMap::new);
pub fn start_task_cleanup_loop() { pub fn start_task_cleanup_loop() {
tokio::spawn(async { tokio::spawn(async {
@ -960,7 +965,7 @@ impl OmikronConnection {
let conf = CONFIG.load(); let conf = CONFIG.load();
match (&conf.omikron_id, &conf.omikron_host, conf.omikron_port) { match (&conf.omikron_id, &conf.omikron_host, conf.omikron_port) {
(Some(id), Some(host), Some(port)) if !host.trim().is_empty() && port != 0 => { (Some(id), Some(host), Some(port)) if !host.trim().is_empty() && port != 0 => {
mtp::files::load_public_key_bundle(&omikron_public_key_path(*id)) mtp::files::load_public_key_bundle(omikron_public_key_path(*id))
.ok() .ok()
.map(|public_key| ResolvedOmikronEndpoint { .map(|public_key| ResolvedOmikronEndpoint {
id: Some(*id), id: Some(*id),
@ -1100,10 +1105,10 @@ impl OmikronConnection {
}); });
continue; continue;
}; };
if let Some((_, task)) = WAITING_TASKS.remove(&msg_id) { if let Some((_, task)) = WAITING_TASKS.remove(&msg_id)
if (task.task)(cv.clone()) { && (task.task)(cv.clone())
continue; {
} continue;
} }
let permit = self.handler_semaphore.clone().acquire_owned().await; let permit = self.handler_semaphore.clone().acquire_owned().await;
let self_clone = self.clone(); let self_clone = self.clone();
@ -1604,8 +1609,7 @@ impl OmikronConnection {
Ok(response) if !response.is_type(CommunicationType::ErrorInternal) => { Ok(response) if !response.is_type(CommunicationType::ErrorInternal) => {
if let (Some(message_id), Some(signer_id)) = if let (Some(message_id), Some(signer_id)) =
(record.relay_message_id.as_deref(), record.relay_signer_id) (record.relay_message_id.as_deref(), record.relay_signer_id)
{ && let Err(error) =
if let Err(error) =
iota_storage::util::downstream_relay::reject_iota_delivery( iota_storage::util::downstream_relay::reject_iota_delivery(
record.frame_id, record.frame_id,
signer_principal, signer_principal,
@ -1620,7 +1624,6 @@ impl OmikronConnection {
error error
); );
} }
}
} }
Ok(response) => log!( Ok(response) => log!(
"Pending Relay {} route returned retryable {}", "Pending Relay {} route returned retryable {}",
@ -1701,10 +1704,10 @@ impl OmikronConnection {
return; return;
}; };
if let Some((_, task)) = WAITING_TASKS.remove(&msg_id) { if let Some((_, task)) = WAITING_TASKS.remove(&msg_id)
if (task.task)(cv.clone()) { && (task.task)(cv.clone())
return; {
} return;
} }
self.clone().handle_message_impl(cv).await; self.clone().handle_message_impl(cv).await;
@ -1916,15 +1919,14 @@ impl OmikronConnection {
if matches!( if matches!(
result, result,
Ok(iota_storage::users::invitations::ProvisioningResult::MissingInvitation) Ok(iota_storage::users::invitations::ProvisioningResult::MissingInvitation)
) { ) && self.sync_omega_invitations().await.is_ok()
if self.sync_omega_invitations().await.is_ok() { {
result = iota_storage::users::invitations::apply_external_invitation_provisioning( result = iota_storage::users::invitations::apply_external_invitation_provisioning(
invitation_id, invitation_id,
invitation_revision, invitation_revision,
&profile, &profile,
now, now,
); );
}
} }
match result { match result {
Ok( Ok(
@ -2378,7 +2380,7 @@ impl OmikronConnection {
let port = config let port = config
.omikron_port .omikron_port
.ok_or_else(|| "Omikron port is unavailable".to_string())?; .ok_or_else(|| "Omikron port is unavailable".to_string())?;
let omikron_key = mtp::files::load_public_key_bundle(&omikron_public_key_path(omikron_id)) let omikron_key = mtp::files::load_public_key_bundle(omikron_public_key_path(omikron_id))
.map_err(|error| error.to_string())?; .map_err(|error| error.to_string())?;
let omikron_public_key = omikron_key let omikron_public_key = omikron_key
.try_to_base64() .try_to_base64()
@ -3150,11 +3152,7 @@ impl OmikronConnection {
} }
async fn handle_call_envelope_store(self: Arc<Self>, cv: &CommunicationValue) { async fn handle_call_envelope_store(self: Arc<Self>, cv: &CommunicationValue) {
let response = match CONFIG let response = match CONFIG.load().omikron_id {
.load()
.omikron_id
.and_then(|id| i64::try_from(id).ok())
{
Some(owner) => message_handlers::handle_call_envelope_store(cv, owner), Some(owner) => message_handlers::handle_call_envelope_store(cv, owner),
None => error_response(cv, CommunicationType::ErrorInternal), None => error_response(cv, CommunicationType::ErrorInternal),
}; };
@ -3162,11 +3160,7 @@ impl OmikronConnection {
} }
async fn handle_call_envelope_get(self: Arc<Self>, cv: &CommunicationValue) { async fn handle_call_envelope_get(self: Arc<Self>, cv: &CommunicationValue) {
let response = match CONFIG let response = match CONFIG.load().omikron_id {
.load()
.omikron_id
.and_then(|id| i64::try_from(id).ok())
{
Some(owner) => message_handlers::handle_call_envelope_get(cv, owner), Some(owner) => message_handlers::handle_call_envelope_get(cv, owner),
None => error_response(cv, CommunicationType::ErrorInternal), None => error_response(cv, CommunicationType::ErrorInternal),
}; };

View file

@ -121,6 +121,7 @@ impl OmikronConnection {
) )
} }
#[expect(clippy::too_many_arguments, reason = "explicit protected frame fields")]
pub(super) fn build_protected( pub(super) fn build_protected(
&self, &self,
frame: &CommunicationValue, frame: &CommunicationValue,

View file

@ -79,10 +79,10 @@ impl AttemptLease {
impl Drop for AttemptLease { impl Drop for AttemptLease {
fn drop(&mut self) { fn drop(&mut self) {
if !self.settled { if !self.settled
if let Some(runtime) = self.runtime.upgrade() { && let Some(runtime) = self.runtime.upgrade()
runtime.finish_attempt_cancel(self.user_id); {
} runtime.finish_attempt_cancel(self.user_id);
} }
} }
} }
@ -219,10 +219,10 @@ impl PasswordAuthRuntime {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for id in expired { for id in expired {
if let Some((_, pending)) = self.logins.remove(&id) { if let Some((_, pending)) = self.logins.remove(&id)
if let Some(attempt) = pending.attempt { && let Some(attempt) = pending.attempt
attempt.failure(); {
} attempt.failure();
} }
} }
self.enrollments self.enrollments
@ -311,10 +311,10 @@ impl PasswordAuthRuntime {
.filter_map(|entry| (entry.user_id == user_id).then_some(*entry.key())) .filter_map(|entry| (entry.user_id == user_id).then_some(*entry.key()))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for id in ids { for id in ids {
if let Some((_, pending)) = self.logins.remove(&id) { if let Some((_, pending)) = self.logins.remove(&id)
if let Some(attempt) = pending.attempt { && let Some(attempt) = pending.attempt
attempt.cancel(); {
} attempt.cancel();
} }
} }
} }

View file

@ -386,15 +386,15 @@ pub async fn reconcile_managed_users(connection: &dyn OmikronClient) {
let _ = pending_operations::remove(operation.user_id); let _ = pending_operations::remove(operation.user_id);
} }
} }
PendingUserOperationKind::Release if remote_iota_id != Some(local_iota_id) => { PendingUserOperationKind::Release
if iota_storage::users::user_manager::finalize_local_release( if remote_iota_id != Some(local_iota_id)
operation.user_id, && iota_storage::users::user_manager::finalize_local_release(
Some(&operation.username), operation.user_id,
) Some(&operation.username),
.is_ok() )
{ .is_ok() =>
let _ = pending_operations::remove(operation.user_id); {
} let _ = pending_operations::remove(operation.user_id);
} }
_ => {} _ => {}
} }
@ -425,17 +425,17 @@ pub async fn reconcile_managed_users(connection: &dyn OmikronClient) {
continue; continue;
} }
}; };
if should_release { if should_release
if let Err(error) = iota_storage::users::user_manager::finalize_local_release( && let Err(error) = iota_storage::users::user_manager::finalize_local_release(
user.user_id, user.user_id,
Some(&user.username), Some(&user.username),
) { )
log!( {
"Could not release local user {} after Omega reconciliation: {}", log!(
user.user_id, "Could not release local user {} after Omega reconciliation: {}",
error user.user_id,
); error
} );
} }
} }
} }
@ -598,7 +598,7 @@ pub async fn create_user(
let mut bytes = [0u8; 192]; let mut bytes = [0u8; 192];
OsRng.fill_bytes(&mut bytes); OsRng.fill_bytes(&mut bytes);
let reset_token = STANDARD.encode(&bytes); let reset_token = STANDARD.encode(bytes);
let user_profile = UserProfile::new( let user_profile = UserProfile::new(
user_id, user_id,