qswiki/cli.cpp
Albert S cfee2bf1d8 Begin CLI
Parse args using getopt_long() in main().

Begin implementation of a CLI.
2021-09-26 10:10:16 +02:00

185 lines
3.8 KiB
C++

#include <map>
#include <functional>
#include "cli.h"
#include "utils.h"
#include "random.h"
#include "authenticator.h"
#include "config.h"
CLI::CLI(Config &config, Database &db)
{
this->db = &db;
this->conf = &config;
}
bool CLI::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())
{
std::cout << "Error during hashing - Got empty hash";
return false;
}
user.password = hashResult;
try
{
userDao->save(user);
}
catch(std::runtime_error &e)
{
std::cout << "Exception: " << e.what() << std::endl;
return false;
}
return true;
}
bool CLI::user_change_pw(const std::vector<std::string> &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->sault);
if(user->password.empty())
{
std::cout << "Error during hashing - Got empty hash";
return false;
}
userDao->save(*user);
}
else
{
std::cout << "User not found" << std::endl;
return false;
}
}
bool CLI::user_rename(const std::vector<std::string> &args)
{
}
bool CLI::user_set_perms(const std::vector<std::string> &args)
{
}
bool CLI::user_list(const std::vector<std::string> &args)
{
}
bool CLI::user_show(const std::vector<std::string> &args)
{
}
bool CLI::cli_help(const std::vector<std::string> &args)
{
std::string command;
if(args.size() > 0)
command = args[0];
for(struct cmd &cmd : cmds)
{
if(command != "" && cmd.name != command)
{
continue;
}
std::cout << cmd.name << " - " << cmd.helptext << std::endl;
for(struct cmd &subCmd : cmd.subCommands)
{
std::cout << "\t" << subCmd.name << " " << subCmd.helptext << std::endl;
}
std::cout << std::endl;
}
return true;
}
bool CLI::processCommand(const std::vector<CLI::cmd> &commands, std::string cmd, const std::vector<std::string> &args)
{
auto c = std::find_if(commands.begin(), commands.end(), [&cmd](const struct CLI::cmd &a) { return a.name == cmd; });
if(c == commands.end())
{
std::cout << "No such command" << 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());
processCommand(c->subCommands, newcmd, newargs);
}
if(args.size() < c->required_args)
{
std::cout << "not enough parameters passed" << std::endl;
return false;
}
try
{
return c->func(this, args);
}
catch(std::runtime_error &e)
{
std::cout << "Exception: " << e.what() << std::endl;
}
return false;
}
bool CLI::processCommand(std::string cmd, const std::vector<std::string> &args)
{
return processCommand(this->cmds, cmd, args);
}
void CLI::startInteractive()
{
std::cout << "qswiki cli" << std::endl;
while(true)
{
std::string input;
std::cout << "> ";
std::getline(std::cin, input);
std::vector<std::string> splitted = utils::split(input, "\\s+");
if(splitted.empty())
{
continue;
}
std::string cmd = splitted[0];
splitted.erase(splitted.begin());
if(!processCommand(cmd, splitted))
{
std::cout << "Command failed" << std::endl;
}
std::cout << "\n";
}
}