1use mybatis_core::convert::StmtConvert;
2
3use crate::mybatis::Mybatis;
4use crate::plus::MybatisPlus;
5use mybatis_core::db::DriverType;
6use mybatis_core::Error;
7use mybatis_sql::TEMPLATE;
8use rbson::Bson;
9use std::fmt::{Debug, Display};
10
11pub trait SqlIntercept: Send + Sync + Debug {
13 fn name(&self) -> &str {
15 std::any::type_name::<Self>()
16 }
17 fn do_intercept(
20 &self,
21 rb: &Mybatis,
22 sql: &mut String,
23 args: &mut Vec<rbson::Bson>,
24 is_prepared_sql: bool,
25 ) -> Result<(), Error>;
26}
27
28#[derive(Debug)]
29pub struct MyBatisLogFormatSqlIntercept {}
30
31impl SqlIntercept for MyBatisLogFormatSqlIntercept {
32 fn do_intercept(
33 &self,
34 rb: &Mybatis,
35 sql: &mut String,
36 args: &mut Vec<Bson>,
37 is_prepared_sql: bool,
38 ) -> Result<(), Error> {
39 let driver_type = rb.driver_type()?;
40 match driver_type {
41 DriverType::None => {}
42 DriverType::Mysql | DriverType::Postgres | DriverType::Sqlite | DriverType::Mssql => {
43 let mut formated = format!("[format_sql]{}", sql);
44 for index in 0..args.len() {
45 let mut data = String::new();
46 driver_type.stmt_convert(index, &mut data);
47 formated =
48 formated.replacen(&data, &format!("{}", args.get(index).unwrap()), 1);
49 }
50 rb.log_plugin.info(0, &formated);
51 }
52 }
53 return Ok(());
54 }
55}
56
57#[derive(Debug)]
59pub struct BlockAttackDeleteInterceptor {}
60
61impl SqlIntercept for BlockAttackDeleteInterceptor {
62 fn do_intercept(
63 &self,
64 rb: &Mybatis,
65 sql: &mut String,
66 args: &mut Vec<Bson>,
67 is_prepared_sql: bool,
68 ) -> Result<(), Error> {
69 let sql = sql.trim();
70 if sql.starts_with(TEMPLATE.delete_from.value)
71 && !sql.contains(TEMPLATE.r#where.left_right_space)
72 {
73 return Err(Error::from(format!(
74 "[mybatis][BlockAttackDeleteInterceptor] not allow attack sql:{}",
75 sql
76 )));
77 }
78 return Ok(());
79 }
80}
81
82#[derive(Debug)]
84pub struct BlockAttackUpdateInterceptor {}
85
86impl SqlIntercept for BlockAttackUpdateInterceptor {
87 fn do_intercept(
88 &self,
89 rb: &Mybatis,
90 sql: &mut String,
91 args: &mut Vec<Bson>,
92 is_prepared_sql: bool,
93 ) -> Result<(), Error> {
94 let sql = sql.trim();
95 if sql.starts_with(TEMPLATE.update.value)
96 && !sql.contains(TEMPLATE.r#where.left_right_space)
97 {
98 return Err(Error::from(format!(
99 "[mybatis][BlockAttackUpdateInterceptor] not allow attack sql:{}",
100 sql
101 )));
102 }
103 return Ok(());
104 }
105}