#include "database_manager.h" #include #include "vfs.h" DatabaseManager::DatabaseManager(const std::string& db_path) : _db(db_path) { _player_repository = std::make_unique(_db); _machine_repository = std::make_unique(_db); _service_repository = std::make_unique(_db); _vfs_repository = std::make_unique(_db); _db << "CREATE TABLE IF NOT EXISTS players(" "id INTEGER PRIMARY KEY AUTOINCREMENT," "username TEXT NOT NULL UNIQUE," "password TEXT NOT NULL," "hostname TEXT NOT NULL," "home_machine_id INTEGER" ");"; _db << "CREATE TABLE IF NOT EXISTS machines (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "owner_id INTEGER," "hostname TEXT NOT NULL," "ip_address TEXT NOT NULL UNIQUE" ");"; _db << "CREATE TABLE IF NOT EXISTS vfs_nodes (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "machine_id INTEGER NOT NULL," "parent_id INTEGER," "name TEXT NOT NULL," "type INTEGER NOT NULL," "content TEXT," "owner_id INTEGER NOT NULL," "group_id INTEGER NOT NULL," "permissions INTEGER NOT NULL" ");"; _db << "CREATE TABLE IF NOT EXISTS services (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "machine_id INTEGER NOT NULL," "port INTEGER NOT NULL," "name TEXT NOT NULL" ");"; } DatabaseManager::~DatabaseManager(void) { /* db is auto closed when _db goes out of scope. */ } bool DatabaseManager::create_player(const std::string& username, const std::string& password, const std::string& hostname, vfs_node* vfs_template) { long long player_id = 0; long long machine_id = 0; try { _db << "BEGIN;"; player_id = _player_repository->create(username, password, hostname); /* Create the home machine. */ /* TODO: Implement real IP allication. */ std::string ip_address = "192.168.1." + std::to_string(player_id); machine_id = _machine_repository->create(player_id, hostname, ip_address); _player_repository->set_home_machine_id(player_id, machine_id); /* Create the root dir for the new machine's VFS. */ long long root_id = _vfs_repository->create_node(machine_id, nullptr, "/", DIR_NODE, "", player_id, player_id, 0755); /* Create default subdirs. */ _vfs_repository->create_node(machine_id, &root_id, "home", DIR_NODE, "", player_id, player_id, 0755); _vfs_repository->create_node(machine_id, &root_id, "etc", DIR_NODE, "", player_id, player_id, 0755); /* Create /bin and get it's ID */ long long bin_id = _vfs_repository->create_node(machine_id, &root_id, "bin", DIR_NODE, "", player_id, player_id, 0755); /* Copy scripts from template into new machine's /bin */ vfs_node* template_bin = vfs_template->children["bin"]; for(auto const& [name, node] : template_bin->children) { _vfs_repository->create_node(machine_id, &bin_id, name, node->type, node->content, player_id, player_id, 0755); } /* Add default SSH service. */ _service_repository->create(machine_id, 22, "SSH"); _db << "COMMIT"; } catch(const std::exception& e) { _db << "ROLLBACK;"; /* Ensure atomicity. */ return false; } return true; }