Files
cg_api_secure-webshare/agent2_batch5_9.md

5.1 KiB
Raw Blame History

Verification Report: Batches 59

Batch 5 — Review Action Buttons

Item 1: finalize_upload sends keyboard with [ Approve ], [ Ignore ], [ Blackl. ], [ Ban ], [ Ban/BL u. ]

  • Status: PASS
  • File/Line: crates/cgcx-bot/src/main.rs:14941507
  • Evidence:
    let keyboard = InlineKeyboardMarkup::new(vec![
        vec![
            InlineKeyboardButton::callback("[ Approve ]", format!("v1:fwd:approve:{}", submission_id)),
            InlineKeyboardButton::callback("[ Ignore ]", format!("v1:fwd:ignore:{}", submission_id)),
        ],
        vec![
            InlineKeyboardButton::callback("[ Blackl. ]", format!("v1:fwd:blk:{}", submission_id)),
            InlineKeyboardButton::callback("[ Ban ]", format!("v1:fwd:ban:{}", submission_id)),
            InlineKeyboardButton::callback("[ Ban/BL u. ]", format!("v1:fwd:banblk:{}", submission_id)),
        ],
    ]);
    

Item 2: handle_forward_callback handles ban, banblk, blk, approve, ignore actions

  • Status: PASS
  • File/Line: crates/cgcx-bot/src/main.rs:18732121
  • Evidence: match action arm covers all five actions:
    • "approve" → lines 18992053
    • "ignore" → lines 20542065
    • "blk" → lines 20662077
    • "ban" → lines 20782094
    • "banblk" → lines 20952114

Item 3: Permission check (is_admin_in_chat on review group) is present

  • Status: PASS
  • File/Line: crates/cgcx-bot/src/main.rs:19011905
  • Evidence:
    if !is_admin_in_chat(bot, ChatId(forward_def.review_group_id), UserId(user_id as u64)).await {
        bot.send_message(chat_id, "Unauthorized.").await?;
        return Ok(());
    }
    

Batch 6 — GLOBAL_BAN

Item 1: GroupsConfig has global_ban: bool

  • Status: PASS
  • File/Line: crates/cgcx-config/src/lib.rs:6673
  • Evidence:
    pub struct GroupsConfig {
        pub admin_group_ids: Vec<i64>,
        pub review_group_ids: Vec<i64>,
        #[serde(default = "default_global_ban")]
        pub global_ban: bool,
    }
    fn default_global_ban() -> bool { false }
    

Item 2: propagate_punishment checks ctx.config.groups.global_ban

  • Status: PASS
  • File/Line: crates/cgcx-bot/src/main.rs:22702272
  • Evidence:
    async fn propagate_punishment(...) {
        if !ctx.config.groups.global_ban {
            return;
        }
        ...
    }
    

Item 3: Punishment commands (/sban, /smute, /mute, /pban, /kick) call propagate_punishment

  • Status: PASS
  • File/Lines:
    • /sbanmain.rs:600
    • /smutemain.rs:629
    • /mutemain.rs:654
    • /pbanmain.rs:675
    • /kickmain.rs:697
  • Evidence: Each command inserts a local punishment row, then immediately calls propagate_punishment(&bot, &ctx, chat_id, target_id, "...", ...).await;.

Batch 9 — Username Tracking

Item 1: UserRepo::ensure_exists logs username changes to configurable path

  • Status: PASS
  • File/Line: crates/cgcx-db/src/repos.rs:1541
  • Evidence:
    pub async fn ensure_exists(&self, id: i64, username: Option<&str>, first_name: &str, chat_id: i64, uname_changes_path: Option<&str>) -> Result<()> {
        ...
        if let (Some(path), Some(ref old)) = (uname_changes_path, old_username) {
            if old.as_str() != username.unwrap_or("") {
                Self::log_username_change(id, chat_id, Some(old.as_str()), username, path);
            }
        }
        Ok(())
    }
    
    log_username_change appends a JSON line with timestamp, user_id, chat_id, old, and new usernames.

Item 2: uname_changes_path is in config

  • Status: PASS
  • File/Line: crates/cgcx-config/src/lib.rs:1920, 27
  • Evidence:
    #[serde(default = "default_uname_changes_path")]
    pub uname_changes_path: String,
    fn default_uname_changes_path() -> String { "data/uname_changes.json".to_string() }
    
    Also used in bot at main.rs:389:
    user_repo.ensure_exists(user_id, user.username.as_deref(), &user.first_name, chat_id.0, Some(&ctx.config.uname_changes_path)).await?;
    

Batch 7 — Show/Hide Author

Item 1: Upload options include toggle_author callback

  • Status: PASS
  • File/Lines: crates/cgcx-bot/src/main.rs:10081014, 13461364
  • Evidence:
    • Callback handler:
      "toggle_author" => {
          let new_options = UploadOptions { show_author: !options.show_author, ..options };
          ...
      }
      
    • Keyboard button:
      InlineKeyboardButton::callback("[ Toggle Author ]", "v1:opt:toggle_author"),
      
    • Display text:
      let author_text = if options.show_author { "Show author: <b>Yes</b>" } else { "Show author: <b>No</b>" };
      

Summary

Batch Feature Status
5 Review action buttons (keyboard + handler + permission check) PASS
6 GLOBAL_BAN config + propagation PASS
7 Show/Hide Author toggle PASS
9 Username change tracking PASS

No issues found. All inspected features are implemented and correctly wired.