fix: Resolve unused import and variable warnings
This commit is contained in:
parent
3b21ab5ef9
commit
d7211a6c19
9 changed files with 90 additions and 64 deletions
|
|
@ -75,13 +75,13 @@ pub fn convert_mail_line_with_substitution(line: &str) -> String {
|
||||||
pub fn convert_mail_block(recipient: &str, lines: &[String]) -> String {
|
pub fn convert_mail_block(recipient: &str, lines: &[String]) -> String {
|
||||||
let mut subject = String::new();
|
let mut subject = String::new();
|
||||||
let mut body_lines: Vec<String> = Vec::new();
|
let mut body_lines: Vec<String> = Vec::new();
|
||||||
let mut in_subject = true;
|
// let mut in_subject = true; // Removed unused variable
|
||||||
let mut skip_blank = true;
|
let mut skip_blank = true;
|
||||||
|
|
||||||
for line in lines.iter() {
|
for line in lines.iter() {
|
||||||
if line.to_uppercase().starts_with("SUBJECT:") {
|
if line.to_uppercase().starts_with("SUBJECT:") {
|
||||||
subject = line[8..].trim().to_string();
|
subject = line[8..].trim().to_string();
|
||||||
in_subject = false;
|
// in_subject = false; // Removed unused assignment
|
||||||
skip_blank = true;
|
skip_blank = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ use crate::basic::keywords::table_definition::process_table_definitions;
|
||||||
use crate::basic::keywords::webhook::execute_webhook_registration;
|
use crate::basic::keywords::webhook::execute_webhook_registration;
|
||||||
use crate::core::shared::models::TriggerKind;
|
use crate::core::shared::models::TriggerKind;
|
||||||
use crate::core::shared::state::AppState;
|
use crate::core::shared::state::AppState;
|
||||||
use diesel::{QueryableByName, sql_query};
|
use diesel::QueryableByName;
|
||||||
use diesel::sql_types::Text;
|
// use diesel::sql_types::Text; // Removed unused import
|
||||||
use diesel::ExpressionMethods;
|
use diesel::ExpressionMethods;
|
||||||
use diesel::QueryDsl;
|
use diesel::QueryDsl;
|
||||||
use diesel::RunQueryDsl;
|
use diesel::RunQueryDsl;
|
||||||
|
|
@ -771,7 +771,7 @@ impl BasicCompiler {
|
||||||
table_name: &str,
|
table_name: &str,
|
||||||
bot_id: uuid::Uuid,
|
bot_id: uuid::Uuid,
|
||||||
) -> Result<Vec<String>, Box<dyn Error + Send + Sync>> {
|
) -> Result<Vec<String>, Box<dyn Error + Send + Sync>> {
|
||||||
use std::path::Path;
|
// use std::path::Path;
|
||||||
|
|
||||||
// Find the tables.bas file in the bot's data directory
|
// Find the tables.bas file in the bot's data directory
|
||||||
let bot_name = self.get_bot_name_by_id(bot_id)?;
|
let bot_name = self.get_bot_name_by_id(bot_id)?;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ use crate::core::shared::sanitize_identifier;
|
||||||
use crate::core::urls::ApiUrls;
|
use crate::core::urls::ApiUrls;
|
||||||
use crate::security::error_sanitizer::log_and_sanitize;
|
use crate::security::error_sanitizer::log_and_sanitize;
|
||||||
use crate::security::sql_guard::{
|
use crate::security::sql_guard::{
|
||||||
build_safe_count_query, build_safe_select_query, is_table_allowed_with_conn, validate_table_name,
|
build_safe_count_query, build_safe_select_by_id_query, build_safe_select_query,
|
||||||
|
is_table_allowed_with_conn, validate_table_name,
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, Query, State},
|
extract::{Path, Query, State},
|
||||||
|
|
@ -257,10 +258,21 @@ pub async fn get_record_handler(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let query = format!(
|
let query = match build_safe_select_by_id_query(&table_name) {
|
||||||
"SELECT row_to_json(t.*) as data FROM {} t WHERE id = $1",
|
Ok(q) => q,
|
||||||
table_name
|
Err(e) => {
|
||||||
);
|
warn!("Failed to build safe query for {}: {}", table_name, e);
|
||||||
|
return (
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
Json(RecordResponse {
|
||||||
|
success: false,
|
||||||
|
data: None,
|
||||||
|
message: Some("Invalid table name".to_string()),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.into_response();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let row: Result<Option<JsonRow>, _> = sql_query(&query)
|
let row: Result<Option<JsonRow>, _> = sql_query(&query)
|
||||||
.bind::<diesel::sql_types::Uuid, _>(record_id)
|
.bind::<diesel::sql_types::Uuid, _>(record_id)
|
||||||
|
|
@ -700,7 +712,17 @@ pub async fn count_records_handler(
|
||||||
return (StatusCode::FORBIDDEN, Json(json!({ "error": e }))).into_response();
|
return (StatusCode::FORBIDDEN, Json(json!({ "error": e }))).into_response();
|
||||||
}
|
}
|
||||||
|
|
||||||
let query = format!("SELECT COUNT(*) as count FROM {}", table_name);
|
let query = match build_safe_count_query(&table_name) {
|
||||||
|
Ok(q) => q,
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to build count query: {}", e);
|
||||||
|
return (
|
||||||
|
StatusCode::BAD_REQUEST,
|
||||||
|
Json(json!({ "error": "Invalid table name" })),
|
||||||
|
)
|
||||||
|
.into_response();
|
||||||
|
}
|
||||||
|
};
|
||||||
let result: Result<CountResult, _> = sql_query(&query).get_result(&mut conn);
|
let result: Result<CountResult, _> = sql_query(&query).get_result(&mut conn);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|
@ -747,14 +769,18 @@ pub async fn search_records_handler(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let safe_search = search_term.replace('%', "\\%").replace('_', "\\_");
|
||||||
|
|
||||||
let query = format!(
|
let query = format!(
|
||||||
"SELECT row_to_json(t.*) as data FROM {} t WHERE
|
"SELECT row_to_json(t.*) as data FROM {} t WHERE
|
||||||
COALESCE(t.title::text, '') || ' ' || COALESCE(t.name::text, '') || ' ' || COALESCE(t.description::text, '')
|
COALESCE(t.title::text, '') || ' ' || COALESCE(t.name::text, '') || ' ' || COALESCE(t.description::text, '')
|
||||||
ILIKE '%{}%' LIMIT {}",
|
ILIKE '%' || $1 || '%' LIMIT {}",
|
||||||
table_name, search_term, limit
|
table_name, limit
|
||||||
);
|
);
|
||||||
|
|
||||||
let rows: Result<Vec<JsonRow>, _> = sql_query(&query).get_results(&mut conn);
|
let rows: Result<Vec<JsonRow>, _> = sql_query(&query)
|
||||||
|
.bind::<diesel::sql_types::Text, _>(&safe_search)
|
||||||
|
.get_results(&mut conn);
|
||||||
|
|
||||||
match rows {
|
match rows {
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::core::shared::sanitize_identifier;
|
||||||
use crate::core::shared::state::AppState;
|
use crate::core::shared::state::AppState;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use diesel::sql_query;
|
use diesel::sql_query;
|
||||||
use diesel::sql_types::{Text, Nullable};
|
use diesel::sql_types::Text;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
|
||||||
|
|
@ -912,14 +912,14 @@ impl ScriptService {
|
||||||
fn convert_mail_block(recipient: &str, lines: &[String]) -> String {
|
fn convert_mail_block(recipient: &str, lines: &[String]) -> String {
|
||||||
let mut subject = String::new();
|
let mut subject = String::new();
|
||||||
let mut body_lines: Vec<String> = Vec::new();
|
let mut body_lines: Vec<String> = Vec::new();
|
||||||
let mut in_subject = true;
|
// let mut in_subject = true; // Removed unused variable
|
||||||
let mut skip_blank = true;
|
let mut skip_blank = true;
|
||||||
|
|
||||||
for (i, line) in lines.iter().enumerate() {
|
for line in lines.iter() {
|
||||||
// Check if this line is a subject line
|
// Check if this line is a subject line
|
||||||
if line.to_uppercase().starts_with("SUBJECT:") {
|
if line.to_uppercase().starts_with("SUBJECT:") {
|
||||||
subject = line[8..].trim().to_string();
|
subject = line[8..].trim().to_string();
|
||||||
in_subject = false;
|
// in_subject = false; // Removed unused assignment
|
||||||
skip_blank = true;
|
skip_blank = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1203,7 +1203,7 @@ impl ScriptService {
|
||||||
// Split into multiple TALK statements to avoid expression complexity limit
|
// Split into multiple TALK statements to avoid expression complexity limit
|
||||||
// Use chunks of 5 lines per TALK statement
|
// Use chunks of 5 lines per TALK statement
|
||||||
let chunk_size = 5;
|
let chunk_size = 5;
|
||||||
for (chunk_idx, chunk) in talk_block_lines.chunks(chunk_size).enumerate() {
|
for chunk in talk_block_lines.chunks(chunk_size) {
|
||||||
// Convert all talk lines in this chunk to a single TALK statement
|
// Convert all talk lines in this chunk to a single TALK statement
|
||||||
let mut combined_talk = String::new();
|
let mut combined_talk = String::new();
|
||||||
for (i, talk_line) in chunk.iter().enumerate() {
|
for (i, talk_line) in chunk.iter().enumerate() {
|
||||||
|
|
@ -1415,7 +1415,7 @@ impl ScriptService {
|
||||||
/// to avoid creating local variables that shadow outer scope variables.
|
/// to avoid creating local variables that shadow outer scope variables.
|
||||||
pub fn convert_select_case_syntax(script: &str) -> String {
|
pub fn convert_select_case_syntax(script: &str) -> String {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
let mut lines: Vec<&str> = script.lines().collect();
|
let lines: Vec<&str> = script.lines().collect();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
log::info!("[TOOL] Converting SELECT/CASE syntax to if-else chains");
|
log::info!("[TOOL] Converting SELECT/CASE syntax to if-else chains");
|
||||||
|
|
@ -1479,7 +1479,7 @@ impl ScriptService {
|
||||||
// Close the last case arm (no else if, so we need the closing brace)
|
// Close the last case arm (no else if, so we need the closing brace)
|
||||||
result.push_str(" }\n");
|
result.push_str(" }\n");
|
||||||
current_case_body.clear();
|
current_case_body.clear();
|
||||||
in_case = false;
|
//in_case = false; // Removed unused assignment
|
||||||
}
|
}
|
||||||
// No extra closing brace needed - the last } else if ... { already closed the chain
|
// No extra closing brace needed - the last } else if ... { already closed the chain
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
@ -1502,7 +1502,7 @@ impl ScriptService {
|
||||||
// Close the current case arm (no else if, so we need the closing brace)
|
// Close the current case arm (no else if, so we need the closing brace)
|
||||||
result.push_str(" }\n");
|
result.push_str(" }\n");
|
||||||
current_case_body.clear();
|
current_case_body.clear();
|
||||||
in_case = false;
|
//in_case = false; // Removed unused assignment
|
||||||
}
|
}
|
||||||
// No extra closing brace needed
|
// No extra closing brace needed
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
/// Works across all LLM providers (GLM, OpenAI, Claude, etc.)
|
/// Works across all LLM providers (GLM, OpenAI, Claude, etc.)
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
// use std::collections::HashMap;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ static ALLOWED_COMMANDS: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
|
||||||
"systemctl",
|
"systemctl",
|
||||||
"sudo",
|
"sudo",
|
||||||
"visudo",
|
"visudo",
|
||||||
|
"id",
|
||||||
|
"netsh",
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
use crate::security::command_guard::SafeCommand;
|
use crate::security::command_guard::SafeCommand;
|
||||||
|
|
@ -84,12 +83,12 @@ impl ProtectionInstaller {
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub fn check_admin() -> bool {
|
pub fn check_admin() -> bool {
|
||||||
let result = Command::new("powershell")
|
let result = SafeCommand::new("powershell")
|
||||||
.args([
|
.and_then(|cmd| cmd.args(&[
|
||||||
"-Command",
|
"-Command",
|
||||||
"([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"
|
"([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)"
|
||||||
])
|
]))
|
||||||
.output();
|
.and_then(|cmd| cmd.execute());
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
|
|
@ -102,9 +101,9 @@ impl ProtectionInstaller {
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
pub fn check_root() -> bool {
|
pub fn check_root() -> bool {
|
||||||
Command::new("id")
|
SafeCommand::new("id")
|
||||||
.arg("-u")
|
.and_then(|cmd| cmd.arg("-u"))
|
||||||
.output()
|
.and_then(|cmd| cmd.execute())
|
||||||
.map(|o| String::from_utf8_lossy(&o.stdout).trim() == "0")
|
.map(|o| String::from_utf8_lossy(&o.stdout).trim() == "0")
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
@ -268,26 +267,23 @@ impl ProtectionInstaller {
|
||||||
fn configure_windows_security(&self) -> Result<()> {
|
fn configure_windows_security(&self) -> Result<()> {
|
||||||
info!("Configuring Windows security settings...");
|
info!("Configuring Windows security settings...");
|
||||||
|
|
||||||
// Enable Windows Defender real-time protection
|
let _ = SafeCommand::new("powershell")
|
||||||
let _ = Command::new("powershell")
|
.and_then(|cmd| cmd.args(&[
|
||||||
.args([
|
|
||||||
"-Command",
|
"-Command",
|
||||||
"Set-MpPreference -DisableRealtimeMonitoring $false; Set-MpPreference -DisableIOAVProtection $false; Set-MpPreference -DisableScriptScanning $false"
|
"Set-MpPreference -DisableRealtimeMonitoring $false; Set-MpPreference -DisableIOAVProtection $false; Set-MpPreference -DisableScriptScanning $false"
|
||||||
])
|
]))
|
||||||
.output();
|
.and_then(|cmd| cmd.execute());
|
||||||
|
|
||||||
// Enable Windows Firewall
|
let _ = SafeCommand::new("netsh")
|
||||||
let _ = Command::new("netsh")
|
.and_then(|cmd| cmd.args(&["advfirewall", "set", "allprofiles", "state", "on"]))
|
||||||
.args(["advfirewall", "set", "allprofiles", "state", "on"])
|
.and_then(|cmd| cmd.execute());
|
||||||
.output();
|
|
||||||
|
|
||||||
// Enable Windows Defender scanning for mapped drives
|
let _ = SafeCommand::new("powershell")
|
||||||
let _ = Command::new("powershell")
|
.and_then(|cmd| cmd.args(&[
|
||||||
.args([
|
|
||||||
"-Command",
|
"-Command",
|
||||||
"Set-MpPreference -DisableRemovableDriveScanning $false -DisableScanningMappedNetworkDrivesForFullScan $false"
|
"Set-MpPreference -DisableRemovableDriveScanning $false -DisableScanningMappedNetworkDrivesForFullScan $false"
|
||||||
])
|
]))
|
||||||
.output();
|
.and_then(|cmd| cmd.execute());
|
||||||
|
|
||||||
info!("Windows security configuration completed");
|
info!("Windows security configuration completed");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -313,12 +309,11 @@ impl ProtectionInstaller {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
fn validate_sudoers(&self) -> Result<()> {
|
fn validate_sudoers(&self) -> Result<()> {
|
||||||
let output = std::process::Command::new("visudo")
|
let output = SafeCommand::new("visudo")
|
||||||
.args(["-c", "-f", SUDOERS_FILE])
|
.and_then(|cmd| cmd.args(&["-c", "-f", SUDOERS_FILE]))
|
||||||
.output()
|
.and_then(|cmd| cmd.execute())
|
||||||
.context("Failed to run visudo validation")?;
|
.context("Failed to run visudo validation")?;
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
|
|
@ -330,7 +325,6 @@ impl ProtectionInstaller {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
fn install_lmd(&self) -> Result<bool> {
|
fn install_lmd(&self) -> Result<bool> {
|
||||||
let maldet_path = Path::new("/usr/local/sbin/maldet");
|
let maldet_path = Path::new("/usr/local/sbin/maldet");
|
||||||
|
|
@ -398,7 +392,6 @@ impl ProtectionInstaller {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
fn update_databases(&self) -> Result<()> {
|
fn update_databases(&self) -> Result<()> {
|
||||||
info!("Updating security tool databases...");
|
info!("Updating security tool databases...");
|
||||||
|
|
@ -442,12 +435,12 @@ impl ProtectionInstaller {
|
||||||
fn update_windows_signatures(&self) -> Result<()> {
|
fn update_windows_signatures(&self) -> Result<()> {
|
||||||
info!("Updating Windows Defender signatures...");
|
info!("Updating Windows Defender signatures...");
|
||||||
|
|
||||||
let result = Command::new("powershell")
|
let result = SafeCommand::new("powershell")
|
||||||
.args([
|
.and_then(|cmd| cmd.args(&[
|
||||||
"-Command",
|
"-Command",
|
||||||
"Update-MpSignature; Write-Host 'Windows Defender signatures updated'",
|
"Update-MpSignature; Write-Host 'Windows Defender signatures updated'",
|
||||||
])
|
]))
|
||||||
.output();
|
.and_then(|cmd| cmd.execute());
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
|
|
@ -571,13 +564,9 @@ impl ProtectionInstaller {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
for (tool_name, tool_cmd) in WINDOWS_TOOLS {
|
for (tool_name, tool_cmd) in WINDOWS_TOOLS {
|
||||||
let check = Command::new(tool_cmd)
|
let check = SafeCommand::new(tool_cmd)
|
||||||
.arg("--version")
|
.and_then(|cmd| cmd.arg("--version"))
|
||||||
.or_else(|_| {
|
.and_then(|cmd| cmd.execute());
|
||||||
Command::new("powershell")
|
|
||||||
.args(["-Command", &format!("Get-Command {}", tool_cmd)])
|
|
||||||
})
|
|
||||||
.output();
|
|
||||||
|
|
||||||
let installed = check.map(|o| o.status.success()).unwrap_or(false);
|
let installed = check.map(|o| o.status.success()).unwrap_or(false);
|
||||||
result.tools.push(ToolVerification {
|
result.tools.push(ToolVerification {
|
||||||
|
|
|
||||||
|
|
@ -68,11 +68,20 @@ pub struct CombinedRateLimiter {
|
||||||
|
|
||||||
impl CombinedRateLimiter {
|
impl CombinedRateLimiter {
|
||||||
pub fn new(http_config: HttpRateLimitConfig, system_limits: SystemLimits) -> Self {
|
pub fn new(http_config: HttpRateLimitConfig, system_limits: SystemLimits) -> Self {
|
||||||
|
const DEFAULT_RPS: NonZeroU32 = match NonZeroU32::new(100) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => unreachable!(),
|
||||||
|
};
|
||||||
|
const DEFAULT_BURST: NonZeroU32 = match NonZeroU32::new(200) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
let quota = Quota::per_second(
|
let quota = Quota::per_second(
|
||||||
NonZeroU32::new(http_config.requests_per_second).unwrap_or(NonZeroU32::new(100).expect("100 is non-zero")),
|
NonZeroU32::new(http_config.requests_per_second).unwrap_or(DEFAULT_RPS),
|
||||||
)
|
)
|
||||||
.allow_burst(
|
.allow_burst(
|
||||||
NonZeroU32::new(http_config.burst_size).unwrap_or(NonZeroU32::new(200).expect("200 is non-zero")),
|
NonZeroU32::new(http_config.burst_size).unwrap_or(DEFAULT_BURST),
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue