mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-10-03 00:52:10 +00:00
fix: redact user-controlled log fields
This commit is contained in:
@@ -34,7 +34,7 @@ impl Config {
|
|||||||
fn parse_u64(name: &str, default: u64) -> u64 {
|
fn parse_u64(name: &str, default: u64) -> u64 {
|
||||||
match env::var(name) {
|
match env::var(name) {
|
||||||
Ok(v) => v.parse::<u64>().unwrap_or_else(|_| {
|
Ok(v) => v.parse::<u64>().unwrap_or_else(|_| {
|
||||||
log::warn!("invalid {name}={v:?}; using default {default}");
|
log::warn!("invalid {name}; using default {default}");
|
||||||
default
|
default
|
||||||
}),
|
}),
|
||||||
Err(_) => default,
|
Err(_) => default,
|
||||||
@@ -46,7 +46,7 @@ impl Config {
|
|||||||
fn parse_opt<T: std::str::FromStr>(name: &str) -> Option<T> {
|
fn parse_opt<T: std::str::FromStr>(name: &str) -> Option<T> {
|
||||||
env::var(name).ok().and_then(|s| {
|
env::var(name).ok().and_then(|s| {
|
||||||
s.parse::<T>().ok().or_else(|| {
|
s.parse::<T>().ok().or_else(|| {
|
||||||
log::warn!("invalid {name}={s:?}");
|
log::warn!("invalid {name}");
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -68,7 +68,7 @@ impl Config {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if !bad.is_empty() {
|
if !bad.is_empty() {
|
||||||
log::warn!("BOT_ADMIN: ignoring non-numeric ids: {bad:?}");
|
log::warn!("BOT_ADMIN: ignoring {} non-numeric id(s)", bad.len());
|
||||||
}
|
}
|
||||||
ids
|
ids
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -202,14 +202,21 @@ async fn handle_callback(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
log::info!("template '{name}' applied to prompt {prompt_message_id}");
|
log::info!(
|
||||||
|
"template '{}' applied to prompt {prompt_message_id}",
|
||||||
|
super::log_escape(name)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Nothing was applied, so nothing is recorded either: the
|
// Nothing was applied, so nothing is recorded either: the
|
||||||
// prompt keeps rendering through whatever it used before, and
|
// prompt keeps rendering through whatever it used before, and
|
||||||
// the toast says why (a silently "successful" press left the
|
// the toast says why (a silently "successful" press left the
|
||||||
// caption unchanged).
|
// caption unchanged).
|
||||||
super::EditOutcome::Failed(reason) => {
|
super::EditOutcome::Failed(reason) => {
|
||||||
log::error!("template '{name}' could not be applied: {reason}");
|
log::error!(
|
||||||
|
"template '{}' could not be applied: {}",
|
||||||
|
super::log_escape(name),
|
||||||
|
super::log_escape(&reason)
|
||||||
|
);
|
||||||
answer = Some(format!("Could not apply the template: {reason}"));
|
answer = Some(format!("Could not apply the template: {reason}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ async fn answer_inline_query(
|
|||||||
// The query is user input: `debug` keeps only its normalized key, the
|
// The query is user input: `debug` keeps only its normalized key, the
|
||||||
// text itself is `trace` (same split as the message handler).
|
// text itself is `trace` (same split as the message handler).
|
||||||
log::debug!("inline query [key={}]", log_key(&query.query));
|
log::debug!("inline query [key={}]", log_key(&query.query));
|
||||||
log::trace!("inline query: {}", query.query);
|
log::trace!("inline query: {}", super::log_escape(&query.query));
|
||||||
let Some(key) = x_media::site::cache_key(&query.query) else {
|
let Some(key) = x_media::site::cache_key(&query.query) else {
|
||||||
answer(ctx.sender, query.id, Vec::new()).await?;
|
answer(ctx.sender, query.id, Vec::new()).await?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
|
|||||||
@@ -222,14 +222,15 @@ pub(crate) async fn handle_message(
|
|||||||
.text()
|
.text()
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
let end = t.floor_char_boundary(120.min(t.len()));
|
let end = t.floor_char_boundary(120.min(t.len()));
|
||||||
&t[..end]
|
log_escape(&t[..end])
|
||||||
})
|
})
|
||||||
.unwrap_or("<no text>");
|
.unwrap_or_else(|| std::borrow::Cow::Borrowed("<no text>"));
|
||||||
// Per-request detail: who and where at `debug`; the message text itself is
|
// Per-request detail: who and where at `debug`; the message text itself is
|
||||||
// user data and only ever appears at `trace`, so a `debug` log can be
|
// user data and only ever appears at `trace`, so a `debug` log can be
|
||||||
// shared without leaking what people pasted.
|
// shared without leaking what people pasted.
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"message from {sender} in {} (private={is_private})",
|
"message from {} in {} (private={is_private})",
|
||||||
|
log_escape(&sender),
|
||||||
message.chat.id
|
message.chat.id
|
||||||
);
|
);
|
||||||
log::trace!("message text: {text_preview}");
|
log::trace!("message text: {text_preview}");
|
||||||
@@ -249,7 +250,7 @@ pub(crate) async fn handle_message(
|
|||||||
log::debug!(
|
log::debug!(
|
||||||
"command from {}: {}",
|
"command from {}: {}",
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
text.split_whitespace().next().unwrap_or("<empty>")
|
log_escape(text.split_whitespace().next().unwrap_or("<empty>"))
|
||||||
);
|
);
|
||||||
log::trace!("command text: {text_preview}");
|
log::trace!("command text: {text_preview}");
|
||||||
execute_command(ctx, bot, &message, command).await?;
|
execute_command(ctx, bot, &message, command).await?;
|
||||||
|
|||||||
@@ -609,7 +609,7 @@ async fn url_media_inner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("fetching [key={}]", log_key(url));
|
log::debug!("fetching [key={}]", log_key(url));
|
||||||
log::trace!("fetching {url}");
|
log::trace!("fetching {}", super::log_escape(url));
|
||||||
// One fetch per post at a time: a concurrent duplicate of this link waits
|
// One fetch per post at a time: a concurrent duplicate of this link waits
|
||||||
// for *this* fetch instead of running its own.
|
// for *this* fetch instead of running its own.
|
||||||
let outcome = match x_media::site::cache_key(url) {
|
let outcome = match x_media::site::cache_key(url) {
|
||||||
@@ -624,11 +624,15 @@ async fn url_media_inner(
|
|||||||
// The URL itself is user data, so only `trace` names the link;
|
// The URL itself is user data, so only `trace` names the link;
|
||||||
// `debug` just records that the message was looked at.
|
// `debug` just records that the message was looked at.
|
||||||
log::debug!("no site pattern matches the link; ignoring");
|
log::debug!("no site pattern matches the link; ignoring");
|
||||||
log::trace!("no site pattern matches {url}");
|
log::trace!("no site pattern matches {}", super::log_escape(url));
|
||||||
}
|
}
|
||||||
// Retries exhausted: notify the user (Rust-only requirement 3).
|
// Retries exhausted: notify the user (Rust-only requirement 3).
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("fetch [key={}]: {e}", log_key(url));
|
log::error!(
|
||||||
|
"fetch [key={}]: {}",
|
||||||
|
log_key(url),
|
||||||
|
super::log_escape(&e.to_string())
|
||||||
|
);
|
||||||
let _ = reply(ctx.sender, chat_id, reply_to, fetch_error_message(e)).await;
|
let _ = reply(ctx.sender, chat_id, reply_to, fetch_error_message(e)).await;
|
||||||
}
|
}
|
||||||
Ok(Some(fetched)) => {
|
Ok(Some(fetched)) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user