Imported Base

This commit is contained in:
Maddox Werts 2025-02-11 12:02:54 -05:00
parent 9ab9074912
commit 398708bd30
3 changed files with 305 additions and 0 deletions

22
project/src/base.rs Normal file
View 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
View 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);
}
}

View 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);
}
}