2021-10-03 17:03:22 +02:00
|
|
|
#include <map>
|
|
|
|
#include <functional>
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
|
|
#include "cli.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "random.h"
|
|
|
|
#include "authenticator.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "logger.h"
|
2021-10-03 23:04:46 +02:00
|
|
|
#include "version.h"
|
2021-10-03 17:03:22 +02:00
|
|
|
|
|
|
|
CLIHandler::CLIHandler(Config &config, Database &db)
|
|
|
|
{
|
|
|
|
this->db = &db;
|
|
|
|
this->conf = &config;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<bool, std::string> CLIHandler::user_add(const std::vector<std::string> &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<char> 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, ""};
|
|
|
|
}
|
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::user_change_pw([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-03 17:03:22 +02:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2021-10-25 18:13:25 +02:00
|
|
|
return {false, "User not found"};
|
2021-10-03 17:03:22 +02:00
|
|
|
}
|
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::user_rename([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-03 17:03:22 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
return {true, ""};
|
|
|
|
}
|
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::user_set_perms([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-03 17:03:22 +02:00
|
|
|
{
|
|
|
|
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"};
|
|
|
|
}
|
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::user_list([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-03 17:03:22 +02:00
|
|
|
{
|
|
|
|
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<bool, std::string> CLIHandler::user_show(const std::vector<std::string> &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"};
|
|
|
|
}
|
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::page_list([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-05 21:57:20 +02:00
|
|
|
{
|
|
|
|
auto pageDao = this->db->createPageDao();
|
|
|
|
QueryOption o;
|
|
|
|
auto result = pageDao->getPageList(o);
|
|
|
|
std::stringstream stream;
|
2022-04-03 11:11:28 +02:00
|
|
|
for(Page &page : result)
|
2021-10-05 21:57:20 +02:00
|
|
|
{
|
2022-04-03 11:11:28 +02:00
|
|
|
stream << page.name << " " << page.pageid << " " << std::string(page.listed ? "listed" : "unlisted") << std::endl;
|
2021-10-05 21:57:20 +02:00
|
|
|
}
|
|
|
|
return {true, stream.str()};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<bool, std::string> CLIHandler::pageperms_set_permissions(const std::vector<std::string> &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, ""};
|
|
|
|
}
|
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::attach([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-03 17:03:22 +02:00
|
|
|
{
|
|
|
|
/* TODO: consider authentication */
|
|
|
|
pid_t pid = getpid();
|
|
|
|
return {true, "Hi, I am pid: " + std::to_string(pid)};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<bool, std::string> CLIHandler::cli_help(const std::vector<std::string> &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<bool, std::string> CLIHandler::processCommand(const std::vector<CLIHandler::cmd> &commands, std::string cmd,
|
|
|
|
const std::vector<std::string> &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<std::string> 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<bool, std::string> CLIHandler::processCommand(std::string cmd, const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
return processCommand(this->cmds, cmd, args);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<std::string, std::vector<std::string>> CLIHandler::splitCommand(std::string input)
|
|
|
|
{
|
|
|
|
input = utils::trim(input);
|
|
|
|
std::vector<std::string> splitted = utils::split(input, "\\s+");
|
|
|
|
if(splitted.empty())
|
|
|
|
{
|
|
|
|
return {" ", splitted};
|
|
|
|
}
|
|
|
|
std::string cmd = splitted[0];
|
|
|
|
splitted.erase(splitted.begin());
|
|
|
|
return {cmd, splitted};
|
|
|
|
}
|
2021-10-03 23:04:46 +02:00
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::version([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-03 23:04:46 +02:00
|
|
|
{
|
|
|
|
return {true, get_version_string()};
|
|
|
|
}
|
2021-10-12 20:02:43 +02:00
|
|
|
|
2021-10-25 17:56:37 +02:00
|
|
|
std::pair<bool, std::string> CLIHandler::category_list([[maybe_unused]] const std::vector<std::string> &args)
|
2021-10-12 20:02:43 +02:00
|
|
|
{
|
|
|
|
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<bool, std::string> CLIHandler::category_delete(const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
auto categoryDao = this->db->createCategoryDao();
|
|
|
|
categoryDao->deleteCategory(args.at(0));
|
|
|
|
return {true, ""};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<bool, std::string> CLIHandler::category_show(const std::vector<std::string> &args)
|
|
|
|
{
|
|
|
|
auto categoryDao = this->db->createCategoryDao();
|
|
|
|
auto members = categoryDao->fetchMembers(args.at(0), QueryOption{});
|
|
|
|
std::stringstream stream;
|
2022-04-03 11:11:28 +02:00
|
|
|
for(Page &member : members)
|
2021-10-12 20:02:43 +02:00
|
|
|
{
|
2022-04-03 11:11:28 +02:00
|
|
|
stream << member.name << std::endl;
|
2021-10-12 20:02:43 +02:00
|
|
|
}
|
|
|
|
return {true, stream.str()};
|
|
|
|
}
|