generated from OBJNULL/Dockerized-Rust
Imported Base
This commit is contained in:
parent
9ab9074912
commit
398708bd30
3 changed files with 305 additions and 0 deletions
22
project/src/base.rs
Normal file
22
project/src/base.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Libraries
|
||||
use std::error::Error;
|
||||
|
||||
pub mod conf;
|
||||
pub mod database;
|
||||
|
||||
use conf::Conf;
|
||||
use database::Database;
|
||||
|
||||
// Functions
|
||||
pub fn init_db(conf: &Conf) -> Result<Database, Box<dyn Error>> {
|
||||
// Initilizing & Connecting to Database
|
||||
let mut database: Database = Database::init();
|
||||
database.connect(
|
||||
conf.get_string("database.address")?,
|
||||
conf.get_string("database.user")?,
|
||||
conf.get_string("database.pass")?
|
||||
)?;
|
||||
|
||||
// Returning database
|
||||
return Ok(database);
|
||||
}
|
||||
80
project/src/base/conf.rs
Normal file
80
project/src/base/conf.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// Libraries
|
||||
use std::error::Error;
|
||||
use config::{self, File, Value, Config};
|
||||
|
||||
// Structures
|
||||
pub struct Conf {
|
||||
settings: Option<Config>
|
||||
}
|
||||
|
||||
// Implementations
|
||||
impl Conf {
|
||||
// Constructores
|
||||
pub fn init(path: &str) -> Result<Conf, Box<dyn Error>> {
|
||||
// Loading based on path and what not
|
||||
// Loading the Configuration File
|
||||
let settings: Config = Config::builder()
|
||||
.add_source(File::with_name(&path))
|
||||
.build()?;
|
||||
|
||||
// Returning empty config
|
||||
return Ok(Conf {
|
||||
settings: Some(settings)
|
||||
});
|
||||
}
|
||||
|
||||
// Functions
|
||||
pub fn get_string(&self, key: &str) -> Result<String, Box<dyn Error>> {
|
||||
// Checking if the key exists
|
||||
let result: String = match &self.settings {
|
||||
Some(config_file) => {
|
||||
config_file.get_string(key)?
|
||||
},
|
||||
None => {
|
||||
panic!("Conf> Config File not loaded!");
|
||||
}
|
||||
};
|
||||
|
||||
// Return result
|
||||
return Ok(result);
|
||||
}
|
||||
pub fn get_i32(&self, key: &str) -> Result<i32, Box<dyn Error>> {
|
||||
// Checking if the key exists
|
||||
let result: i32 = match &self.settings {
|
||||
Some(config_file) => {
|
||||
config_file.get_int(key)? as i32
|
||||
},
|
||||
None => {
|
||||
panic!("Conf> Config File not loaded!");
|
||||
}
|
||||
};
|
||||
|
||||
// Return result
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
pub fn get_arr_str(&self, key: &str) -> Result<Vec<String>, Box<dyn Error>> {
|
||||
// Creating result object
|
||||
let mut result: Vec<String> = Vec::new();
|
||||
|
||||
// Checking if the key exists
|
||||
match &self.settings {
|
||||
Some(config_file) => {
|
||||
// Getting all values
|
||||
let values: Vec<Value> = config_file.get_array(key)?;
|
||||
|
||||
// Iter through values
|
||||
for value in values {
|
||||
// Adding it to result
|
||||
result.push(value.into_string()?);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
panic!("Conf> Config File not loaded!");
|
||||
}
|
||||
};
|
||||
|
||||
// Return result
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
203
project/src/base/database.rs
Normal file
203
project/src/base/database.rs
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// Libraries
|
||||
use std::error::Error;
|
||||
use mysql::{prelude::Queryable, Opts, Pool, PooledConn, Row};
|
||||
use chrono::Utc;
|
||||
use regex::Regex;
|
||||
|
||||
// Structures
|
||||
pub struct Database {
|
||||
connection: Option<PooledConn>
|
||||
}
|
||||
|
||||
// Functions
|
||||
impl Database {
|
||||
// Constructors
|
||||
pub fn init() -> Database {
|
||||
// Returning a database
|
||||
return Database {
|
||||
connection: None
|
||||
};
|
||||
}
|
||||
|
||||
// Functions
|
||||
fn check_injection(&mut self, query: &str) -> Result<Option<String>, Box<dyn Error>> {
|
||||
let sql_injection_pattern: Regex = Regex::new(r"(?i)(--|;|/\*|\*/|xp_|exec|select|insert|update|delete|drop|union|shutdown|create|alter)")?;
|
||||
if sql_injection_pattern.is_match(query) {
|
||||
// Getting time
|
||||
let now: chrono::DateTime<Utc> = Utc::now();
|
||||
let formatted: String = now.format("%Y-%m-%d %H:%M:%S").to_string();
|
||||
|
||||
// Add to flag database
|
||||
self.inst_table("Flags", "`occurance` DATETIME")?;
|
||||
self.insert("Flags", "`occurance`", &format!("'{}'", formatted))?;
|
||||
|
||||
// Return error
|
||||
return Ok(Some(format!("SQL Injection Detected ({})", query)));
|
||||
} else {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(&mut self, address: String, user: String, pass: String) -> Result<(), Box<dyn Error>> {
|
||||
// Creating database connection url
|
||||
let url: String = format!("mysql://{}:{}@{}/neurostock", user, pass, address);
|
||||
|
||||
// Connecting via pool
|
||||
let pool: Pool = Pool::new(Opts::from_url(&url)?)?;
|
||||
|
||||
// Creating the connection
|
||||
self.connection = Some(pool.get_conn()?);
|
||||
|
||||
// Success
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn inst_table(&mut self, table: &str, columns: &str) -> Result<(), Box<dyn Error>> {
|
||||
// Preparing sql query
|
||||
let query: String = format!("CREATE TABLE IF NOT EXISTS {} ({})", table, columns);
|
||||
|
||||
// Verify we have a connection
|
||||
match &mut self.connection {
|
||||
Some(conn) => {
|
||||
// Creating table if it doesn't exist
|
||||
conn.query_drop(query)?;
|
||||
},
|
||||
None => {
|
||||
panic!("Database> No database connection to check or create table.");
|
||||
}
|
||||
};
|
||||
|
||||
// Successful
|
||||
return Ok(());
|
||||
}
|
||||
pub fn exists_table(&mut self, table: &str) -> Result<bool, Box<dyn Error>> {
|
||||
// Result
|
||||
let result: bool;
|
||||
|
||||
// Compile SQL query
|
||||
let query: String = format!("SELECT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '{}') AS status;", table);
|
||||
|
||||
// Sending to get result
|
||||
match &mut self.connection {
|
||||
Some(conn) => {
|
||||
// Getting the first row
|
||||
let row: Row = conn.query_iter(query)?.nth(0).unwrap()?;
|
||||
|
||||
// Was it successful?
|
||||
result = row.get(0).unwrap();
|
||||
},
|
||||
None => {
|
||||
panic!("Database> No database connection to insert data into.");
|
||||
}
|
||||
}
|
||||
|
||||
// Success
|
||||
return Ok(result);
|
||||
}
|
||||
pub fn exists_row(&mut self, table: &str, element: &str, value: &str) -> Result<bool, Box<dyn Error>> {
|
||||
// Preparing sql query
|
||||
let response: Vec<Row> = self.get(
|
||||
table,
|
||||
"*",
|
||||
&format!(" WHERE {}={}", element, value)
|
||||
)?;
|
||||
|
||||
// Success
|
||||
return Ok(response.len() != 0);
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, table: &str, columns: &str, data: &str) -> Result<(), Box<dyn Error>> {
|
||||
// Checking for SQL Injection
|
||||
match self.check_injection(data)? {
|
||||
Some(e) => {
|
||||
return Err(e.into());
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
// Preparing sql query
|
||||
let query: String = format!("INSERT INTO {} ({}) VALUES ({})", table, columns, data);
|
||||
|
||||
// Verify we have a connection
|
||||
match &mut self.connection {
|
||||
Some(conn) => {
|
||||
// Sending query
|
||||
conn.query_drop(query)?;
|
||||
},
|
||||
None => {
|
||||
panic!("Database> No database connection to insert data into.");
|
||||
}
|
||||
};
|
||||
|
||||
// Successful
|
||||
return Ok(());
|
||||
}
|
||||
pub fn update(&mut self, table: &str, element: &str, value: &str, case: &str) -> Result<(), Box<dyn Error>> {
|
||||
// Checking for SQL Injection
|
||||
match self.check_injection(value)? {
|
||||
Some(e) => {
|
||||
return Err(e.into());
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
// Checking for SQL Injection
|
||||
match self.check_injection(case)? {
|
||||
Some(e) => {
|
||||
return Err(e.into());
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
// Preparing sql query
|
||||
let query: String = format!("UPDATE {} SET {}={} WHERE {}", table, element, value, case);
|
||||
|
||||
// Verify we have a connection
|
||||
match &mut self.connection {
|
||||
Some(conn) => {
|
||||
// Sending query
|
||||
conn.query_drop(query)?;
|
||||
},
|
||||
None => {
|
||||
panic!("Database> No database connection to insert data into.");
|
||||
}
|
||||
};
|
||||
|
||||
// Successful
|
||||
return Ok(());
|
||||
}
|
||||
pub fn get(&mut self, table: &str, elements: &str, case: &str) -> Result<Vec<Row>, Box<dyn Error>> {
|
||||
// Is there a case?
|
||||
if case.contains("WHERE") {
|
||||
// Checking for SQL Injection
|
||||
match self.check_injection(&case.split("WHERE").nth(1).unwrap())? {
|
||||
Some(e) => {
|
||||
return Err(e.into());
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Preparing sql query
|
||||
let query: String = format!("SELECT {} FROM {}{}", elements, table, case);
|
||||
|
||||
// Creating vector to store the data in
|
||||
let mut result: Vec<Row> = Vec::new();
|
||||
|
||||
// Verify we have a connection
|
||||
match &mut self.connection {
|
||||
Some(conn) => {
|
||||
// Going through all rows it sent back
|
||||
for row in conn.query_iter(query)? {
|
||||
result.push(row?);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
panic!("Database> No database connection to insert data into.");
|
||||
}
|
||||
};
|
||||
|
||||
// Successful
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue