#include "../include/UserManager.h" #include "../../libs/libbcrypt/bcrypt.h" // TODO read userStorage file location from config // initialize static filename to empty string std::string UserManager::filename = ""; void UserManager::init(const std::string &file) { filename = file; std::ifstream ifile(filename); if (!ifile.is_open()) { // create new file by adding a user if userStorage does not exist addUser("user", "pass"); std::cout << "Created \"" << filename << "\" and added the default user" << std::endl; } ifile.close(); } bool UserManager::isAllowed(const std::string &name, const std::string &pw) { std::map user_map; readFromFile(user_map); auto it = user_map.find(name); // check if user exists and pw is valid if (it != user_map.end()) { // check bcrypt hash std::string hash = it->second; int ret = bcrypt_checkpw(pw.c_str(), hash.c_str()); if (ret != 0) return false; return true; } return false; } bool UserManager::addUser(const std::string &name, const std::string &pw) { std::map user_map; readFromFile(user_map); auto it = user_map.find(name); // if user exists, do nothing if (it != user_map.end()) { return false; } // calculate bcrypt hash std::string salt; std::string hash; salt.resize(BCRYPT_HASHSIZE); hash.resize(BCRYPT_HASHSIZE); int ret = bcrypt_gensalt(10, &salt.front()); if (ret != 0) return false; ret = bcrypt_hashpw(pw.c_str(), salt.c_str(), &hash.front()); if (ret != 0) return false; user_map.insert(std::pair(name, hash)); writeToFile(user_map); return true; } bool UserManager::deleteUser(const std::string &name, const std::string &pw) { // TODO check pw before delete std::map user_map; readFromFile(user_map); auto it = user_map.find(name); if (it == user_map.end()) { return false; } if (it->second.compare(pw) != 0) { return false; } user_map.erase(it); writeToFile(user_map); return true; } // read content from file into given map void UserManager::readFromFile(std::map &user_map) { std::ifstream ifile(filename); std::string line; while (getline(ifile, line)) { std::stringstream ss(line); std::string segment; std::vector v; while (std::getline(ss, segment, ';')) { v.push_back(segment); } user_map.insert(std::pair(v.at(0), v.at(1))); } ifile.close(); } // write content from map to file void UserManager::writeToFile(std::map &user_map) { std::ofstream file; file.open(filename); for (auto const &x : user_map) { file << x.first << ";" << x.second << std::endl; } file.close(); }