Compare commits

...

2 commits

Author SHA1 Message Date
3e1d1e4a1f
feat: Dry run mode
The bot can run in dry-run mode, i.e. log that it has blocked users but
will not actually block them

Signed-off-by: Awiteb <a@4rs.nl>
2024-11-15 12:26:25 +03:00
880330576d
fix: Split the haystack lines
Match each line separately

Signed-off-by: Awiteb <a@4rs.nl>
2024-11-15 09:20:18 +00:00
5 changed files with 25 additions and 10 deletions

View file

@ -138,6 +138,9 @@ pub struct Exprs {
/// forgejo-guard configuration /// forgejo-guard configuration
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct Config { pub struct Config {
/// Dry run, without banning the users
#[serde(default)]
pub dry_run: bool,
/// Configuration for the forgejo guard itself /// Configuration for the forgejo guard itself
pub forgejo: Forgejo, pub forgejo: Forgejo,
/// Configuration of the telegram bot /// Configuration of the telegram bot

View file

@ -40,6 +40,7 @@ async fn try_main() -> error::GuardResult<()> {
let (sus_sender, sus_receiver) = sync::mpsc::channel::<forgejo_api::ForgejoUser>(100); let (sus_sender, sus_receiver) = sync::mpsc::channel::<forgejo_api::ForgejoUser>(100);
tracing::info!("The instance: {}", config.forgejo.instance); tracing::info!("The instance: {}", config.forgejo.instance);
tracing::info!("Dry run: {}", config.dry_run);
tracing::debug!("The config exprs: {:#?}", config.expressions); tracing::debug!("The config exprs: {:#?}", config.expressions);
rust_i18n::set_locale(config.telegram.lang.as_str()); rust_i18n::set_locale(config.telegram.lang.as_str());

View file

@ -30,7 +30,8 @@ use teloxide::{
use crate::{config::Config, forgejo_api}; use crate::{config::Config, forgejo_api};
/// Inline keyboard with a single button that links to the Forgejo Guardian repository. /// Inline keyboard with a single button that links to the Forgejo Guardian
/// repository.
fn source_inline_keyboard(text: &str) -> InlineKeyboardMarkup { fn source_inline_keyboard(text: &str) -> InlineKeyboardMarkup {
InlineKeyboardMarkup::new([[InlineKeyboardButton::new( InlineKeyboardMarkup::new([[InlineKeyboardButton::new(
text, text,
@ -58,15 +59,17 @@ pub async fn callback_handler(
match command { match command {
"b" => { "b" => {
// ban the user // ban the user
let button_text = if forgejo_api::ban_user( let button_text = if config.dry_run
&Client::new(), || forgejo_api::ban_user(
&config.forgejo.instance, &Client::new(),
&config.forgejo.token, &config.forgejo.instance,
data, &config.forgejo.token,
) data,
.await )
.is_ok() .await
.is_ok()
{ {
tracing::info!("Suspicious user @{data} has been blocked");
t!("messages.ban_success") t!("messages.ban_success")
} else { } else {
t!("messages.ban_failed") t!("messages.ban_failed")

View file

@ -26,7 +26,11 @@ pub trait ExprChecker {
impl ExprChecker for Expr { impl ExprChecker for Expr {
fn is_match<'a>(&'a self, user: &ForgejoUser) -> Option<Regex> { fn is_match<'a>(&'a self, user: &ForgejoUser) -> Option<Regex> {
let one_of = |hay, exprs: &'a Vec<Regex>| exprs.iter().find(|re| re.is_match(hay)); let one_of = |hay: &str, exprs: &'a Vec<Regex>| {
exprs
.iter()
.find(|re| hay.split('\n').any(|line| re.is_match(line.trim())))
};
[ [
one_of(&user.username, &self.usernames), one_of(&user.username, &self.usernames),
one_of(&user.full_name, &self.full_names), one_of(&user.full_name, &self.full_names),

View file

@ -62,6 +62,10 @@ async fn check_new_user(
) { ) {
if let Some(re) = config.expressions.ban.is_match(&user) { if let Some(re) = config.expressions.ban.is_match(&user) {
tracing::info!("@{} has been banned because `{re}`", user.username); tracing::info!("@{} has been banned because `{re}`", user.username);
if config.dry_run {
return;
}
if let Err(err) = forgejo_api::ban_user( if let Err(err) = forgejo_api::ban_user(
request_client, request_client,
&config.forgejo.instance, &config.forgejo.instance,