#include #include #include #include "cli.h" #include "utils.h" #include "random.h" #include "authenticator.h" #include "config.h" #include "logger.h" #include "version.h" CLIHandler::CLIHandler(Config &config, Database &db) { this->db = &db; this->conf = &config; } std::pair CLIHandler::user_add(const std::vector &args) { std::string username = args.at(0); std::string password = args.at(1); auto userDao = db->createUserDao(); Permissions perms = this->conf->handlersConfig.anon_permissions; int p = perms.getPermissions(); p |= PERM_CAN_CREATE | PERM_CAN_SEARCH | PERM_CAN_EDIT; Permissions newPermissions = Permissions{p}; Random r; User user; user.enabled = true; user.login = username; user.salt = r.getRandom(AUTH_DEFAULT_SALT_SIZE); user.permissions = newPermissions; Authenticator auth{*userDao}; std::vector hashResult = auth.hash(password, user.salt); if(hashResult.empty()) { return {false, "Error during hashing - Got empty hash"}; } user.password = hashResult; try { userDao->save(user); } catch(std::runtime_error &e) { return {false, "Exception: " + std::string(e.what())}; } return {true, ""}; } std::pair CLIHandler::user_change_pw([[maybe_unused]] const std::vector &args) { std::string username = args.at(0); std::string password = args.at(1); auto userDao = db->createUserDao(); auto user = userDao->find(username); if(user) { Random r; Authenticator auth{*userDao}; user->salt = r.getRandom(AUTH_DEFAULT_SALT_SIZE); user->password = auth.hash(password, user->salt); if(user->password.empty()) { return {false, "Error during hashing - Got empty hash"}; } userDao->save(*user); } return {false, "User not found"}; } std::pair CLIHandler::user_rename([[maybe_unused]] const std::vector &args) { return {true, ""}; } std::pair CLIHandler::user_set_perms([[maybe_unused]] const std::vector &args) { auto userDao = this->db->createUserDao(); std::string username = args.at(0); std::string permission_string = args.at(1); Permissions perms{permission_string}; auto user = userDao->find(username); if(user) { user->permissions = perms; userDao->save(*user); user_show({username}); return {true, ""}; } return {false, "User not found"}; } std::pair CLIHandler::user_list([[maybe_unused]] const std::vector &args) { auto userDao = this->db->createUserDao(); QueryOption o; auto result = userDao->list(o); std::stringstream stream; for(User &u : result) { stream << u.login << "\t" << std::string(u.enabled ? "enabled" : "disabled") << "\t" << u.permissions.toString() << std::endl; } return {true, stream.str()}; } std::pair CLIHandler::user_show(const std::vector &args) { std::string username = args.at(0); auto userDao = this->db->createUserDao(); auto user = userDao->find(username); std::stringstream stream; if(user) { stream << "Username: " << user->login << std::endl; stream << "Enabled: " << std::string(user->enabled ? "yes" : "no") << std::endl; stream << "Permissions (general): " << user->permissions.toString() << std::endl; return {true, stream.str()}; } return {false, "User not found"}; } std::pair CLIHandler::page_list([[maybe_unused]] const std::vector &args) { auto pageDao = this->db->createPageDao(); QueryOption o; auto result = pageDao->getPageList(o); std::stringstream stream; for(Page &page : result) { stream << page.name << " " << page.pageid << " " << std::string(page.listed ? "listed" : "unlisted") << std::endl; } return {true, stream.str()}; } std::pair CLIHandler::pageperms_set_permissions(const std::vector &args) { std::string page = args.at(0); std::string username = args.at(1); std::string perms = args.at(2); auto permissionsDao = this->db->createPermissionsDao(); permissionsDao->save(page, username, Permissions{perms}); return {true, ""}; } std::pair CLIHandler::attach([[maybe_unused]] const std::vector &args) { /* TODO: consider authentication */ pid_t pid = getpid(); return {true, "Hi, I am pid: " + std::to_string(pid)}; } std::pair CLIHandler::cli_help(const std::vector &args) { std::string command; if(args.size() > 0) command = args[0]; std::stringstream stream; for(struct cmd &cmd : cmds) { if(command != "" && cmd.name != command) { continue; } stream << cmd.name << " - " << cmd.helptext << std::endl; for(struct cmd &subCmd : cmd.subCommands) { stream << "\t" << subCmd.name << " " << subCmd.helptext << std::endl; } stream << std::endl; } return {true, stream.str()}; } std::pair CLIHandler::processCommand(const std::vector &commands, std::string cmd, const std::vector &args) { auto c = std::find_if(commands.begin(), commands.end(), [&cmd](const struct CLIHandler::cmd &a) { return a.name == cmd; }); if(c == commands.end()) { std::cout << "No such command: " << cmd << std::endl; return cli_help({}); } if(!c->subCommands.empty() && args.size() >= c->required_args) { std::string newcmd = args[0]; std::vector newargs = args; newargs.erase(newargs.begin()); return processCommand(c->subCommands, newcmd, newargs); } if(args.size() < c->required_args) { return {false, "not enough parameters passed"}; } try { return c->func(this, args); } catch(std::runtime_error &e) { return {false, "Exception: " + std::string(e.what())}; } return {false, ""}; } std::pair CLIHandler::processCommand(std::string cmd, const std::vector &args) { return processCommand(this->cmds, cmd, args); } std::pair> CLIHandler::splitCommand(std::string input) { input = utils::trim(input); std::vector splitted = utils::split(input, "\\s+"); if(splitted.empty()) { return {" ", splitted}; } std::string cmd = splitted[0]; splitted.erase(splitted.begin()); return {cmd, splitted}; } std::pair CLIHandler::version([[maybe_unused]] const std::vector &args) { return {true, get_version_string()}; } std::pair CLIHandler::category_list([[maybe_unused]] const std::vector &args) { auto categoryDao = this->db->createCategoryDao(); auto categories = categoryDao->fetchList(QueryOption{}); std::stringstream stream; for(std::string &cat : categories) { stream << cat << std::endl; } return {true, stream.str()}; } std::pair CLIHandler::category_delete(const std::vector &args) { auto categoryDao = this->db->createCategoryDao(); categoryDao->deleteCategory(args.at(0)); return {true, ""}; } std::pair CLIHandler::category_show(const std::vector &args) { auto categoryDao = this->db->createCategoryDao(); auto members = categoryDao->fetchMembers(args.at(0), QueryOption{}); std::stringstream stream; for(Page &member : members) { stream << member.name << std::endl; } return {true, stream.str()}; }