Skip to content

Commit

Permalink
add db migration
Browse files Browse the repository at this point in the history
  • Loading branch information
Sn0wAlice committed Oct 23, 2024
1 parent d4a80ae commit 54367db
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 4 deletions.
18 changes: 18 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: '3.8'

services:
mysql:
image: mysql:8.0 # You can choose another version of MySQL if needed
container_name: matryriska-mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword # Set your root password
MYSQL_DATABASE: matryriska # This creates the database on startup
MYSQL_USER: matryriska # Optional: Set up an additional user
MYSQL_PASSWORD: StrongPassword123 # Optional: Set a password for the user
volumes:
- mysql_data:/var/lib/mysql # Persist MySQL data
ports:
- "3306:3306" # Expose MySQL port

volumes:
mysql_data:
16 changes: 15 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,29 @@ services:
MYSQL_DATABASE: matryriska # This creates the database on startup
MYSQL_USER: matryriska # Optional: Set up an additional user
MYSQL_PASSWORD: StrongPassword123 # Optional: Set a password for the user
networks:
matryriska-net:
ipv4_address: 172.20.0.2 # Assign a fixed IP address
volumes:
- mysql_data:/var/lib/mysql # Persist MySQL data
ports:
- "3306:3306" # Expose MySQL port

web:
image: ghcr.io/sn0walice/matryriska:latest
container_name: matryriska-web
networks:
matryriska-net:
ipv4_address: 172.20.0.3 # Assign a fixed IP address for the web container
ports:
- "8080:8080"
- "8080:8080" # Expose the web service port

volumes:
mysql_data:

networks:
matryriska-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16 # Define a custom subnet
219 changes: 217 additions & 2 deletions src/helper/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,17 @@ async fn periodic_database() {
}

async fn reset_database() {

let mut h = "127.0.0.1";

// check if process arg --prod is used
if std::env::args().any(|arg| arg == "--prod") {
h = "172.20.0.2";
}

// Define MySQL connection options
let opts = mysql::OptsBuilder::new()
.ip_or_hostname(Some("mysql"))
.ip_or_hostname(Some(h))
.db_name(Some("matryriska"))
.user(Some("matryriska"))
.pass(Some("StrongPassword123"));
Expand Down Expand Up @@ -1053,4 +1061,211 @@ pub async fn delete_countermeasure_from_sc(scenario_uuid: String) -> Result<(),
}

return Err("No database connection".to_owned());
}
}










// ------------ DATABASE UTILS ------------
pub async fn check_if_table_exist(table_name:String) -> bool {
// check if DB_CLIENT.lock().unwrap().is_none() return any poison error
let lock_result = unsafe { DB_CLIENT.lock() };

if lock_result.is_err() {
// kill script
trace_logs("Error: DB_CLIENT.lock().unwrap() is_none() return any poison".to_owned());
std::process::exit(1);
}

// check if need to create new client
if lock_result.unwrap().is_none() {
new_client().await;
}

// perform database operations
let db_client = unsafe { DB_CLIENT.lock().unwrap() };

let db_client = db_client.as_ref();

if let Some(pool) = db_client {
let mut conn = pool.get_conn().unwrap();

let query = format!("SELECT table_name FROM information_schema.tables WHERE table_name = '{}' LIMIT 1", table_name);

let result = conn.query_map(query, |(table_name): (String)| {
table_name
});

// check how many rows are returned
match result {
Ok(fetched_table) => {
if fetched_table.len() > 0 {
return true;
}
},
Err(_) => {
return false;
}
}

return false;
}

println!("No database connection");
return false;
}

pub async fn create_table(table_name:String, column:Vec<serde_json::Value>) {
// check if DB_CLIENT.lock().unwrap().is_none() return any poison error
let lock_result = unsafe { DB_CLIENT.lock() };

if lock_result.is_err() {
// kill script
trace_logs("Error: DB_CLIENT.lock().unwrap() is_none() return any poison".to_owned());
std::process::exit(1);
}

// check if need to create new client
if lock_result.unwrap().is_none() {
new_client().await;
}

// perform database operations
let db_client = unsafe { DB_CLIENT.lock().unwrap() };

let db_client = db_client.as_ref();

if let Some(pool) = db_client {
let mut conn = pool.get_conn().unwrap();

let mut query = format!("CREATE TABLE {} (", table_name);

for (i, col) in column.iter().enumerate() {
if i == column.len() - 1 {
query.push_str(&format!("{} {})", col["name"], col["type"]));
} else {
query.push_str(&format!("{} {}, ", col["name"], col["type"]));
}
}

query = query.replace("\"", "");

let result = conn.query_drop(query);

match result {
Ok(_) => {
return;
},
Err(_) => {
return;
}
}
}

println!("No database connection");
return;
}

pub async fn check_column_exist(table_name:String, column_name:String) -> bool {
// check if DB_CLIENT.lock().unwrap().is_none() return any poison error
let lock_result = unsafe { DB_CLIENT.lock() };

if lock_result.is_err() {
// kill script
trace_logs("Error: DB_CLIENT.lock().unwrap() is_none() return any poison".to_owned());
std::process::exit(1);
}

// check if need to create new client
if lock_result.unwrap().is_none() {
new_client().await;
}

// perform database operations
let db_client = unsafe { DB_CLIENT.lock().unwrap() };

let db_client = db_client.as_ref();

if let Some(pool) = db_client {
let mut conn = pool.get_conn().unwrap();

let query = format!("SELECT column_name FROM information_schema.columns WHERE table_name = '{}' AND column_name = '{}' LIMIT 1", table_name, column_name);

let result = conn.query_map(query, |(column_name): (String)| {
column_name
});

// check how many rows are returned
match result {
Ok(fetched_column) => {
if fetched_column.len() > 0 {
return true;
}
},
Err(_) => {
return false;
}
}

return false;
}

println!("No database connection");
return false;
}

pub async fn add_column(table_name:String, column_name:String, column_type:String) {
// check if DB_CLIENT.lock().unwrap().is_none() return any poison error
let lock_result = unsafe { DB_CLIENT.lock() };

if lock_result.is_err() {
// kill script
trace_logs("Error: DB_CLIENT.lock().unwrap() is_none() return any poison".to_owned());
std::process::exit(1);
}

// check if need to create new client
if lock_result.unwrap().is_none() {
new_client().await;
}

// perform database operations
let db_client = unsafe { DB_CLIENT.lock().unwrap() };

let db_client = db_client.as_ref();

if let Some(pool) = db_client {
let mut conn = pool.get_conn().unwrap();

let query = format!("ALTER TABLE {} ADD COLUMN {} {}", table_name, column_name, column_type);

let result = conn.query_drop(query);

match result {
Ok(_) => {
return;
},
Err(_) => {
return;
}
}
}

println!("No database connection");
return;
}









102 changes: 102 additions & 0 deletions src/helper/db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
[
{
"name": "risk",
"columns": [
{
"name": "risk_uuid",
"type": "varchar(36) primary key"
},
{
"name": "risk_name",
"type": "varchar(255) not null default 'New Risk'"
},
{
"name": "risk_description",
"type": "text not null"
}
]
},
{
"name": "scenario",
"columns": [
{
"name": "scenario_uuid",
"type": "varchar(36) primary key"
},
{
"name": "risk_uuid",
"type": "varchar(36) not null"
},
{
"name": "scenario_description",
"type": "text not null"
},
{
"name": "threat_description",
"type": "text not null"
},
{
"name": "add_note",
"type": "text"
}
]
},
{
"name": "scenario_risk",
"columns": [
{
"name": "scenario_uuid",
"type": "varchar(36) not null"
},
{
"name": "likehood",
"type": "int not null"
},
{
"name": "reputation",
"type": "int not null"
},
{
"name": "operational",
"type": "int not null"
},
{
"name": "legal_compliance",
"type": "int not null"
},
{
"name": "financial",
"type": "int not null"
}
]
},
{
"name": "countermeasure",
"columns": [
{
"name": "ctm_uuid",
"type": "varchar(36) primary key"
},
{
"name": "scenario_uuid",
"type": "varchar(36) not null"
},
{
"name": "title",
"type": "varchar(255) not null default 'New Countermeasure'"
},
{
"name": "description",
"type": "text not null"
},
{
"name": "solved",
"type": "int not null default 0"
},
{
"name": "solved_description",
"type": "text"
}
]
}
]
3 changes: 2 additions & 1 deletion src/helper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ pub mod find_insert;
pub mod replace_in_body;
pub mod trace;
pub mod database;
pub mod functions;
pub mod functions;
pub mod start;
Loading

0 comments on commit 54367db

Please sign in to comment.