279 řádky
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			279 řádky
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <map>
 | |
| #include <functional>
 | |
| #include <iomanip>
 | |
| 
 | |
| #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<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, ""};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::user_change_pw([[maybe_unused]] 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->salt);
 | |
| 		if(user->password.empty())
 | |
| 		{
 | |
| 			return {false, "Error during hashing - Got empty hash"};
 | |
| 		}
 | |
| 
 | |
| 		userDao->save(*user);
 | |
| 	}
 | |
| 	return {false, "User not found"};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::user_rename([[maybe_unused]] const std::vector<std::string> &args)
 | |
| {
 | |
| 
 | |
| 	return {true, ""};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::user_set_perms([[maybe_unused]] const std::vector<std::string> &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<bool, std::string> CLIHandler::user_list([[maybe_unused]] const std::vector<std::string> &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<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"};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::page_list([[maybe_unused]] const std::vector<std::string> &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<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, ""};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::attach([[maybe_unused]] const std::vector<std::string> &args)
 | |
| {
 | |
| 	/* 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};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::version([[maybe_unused]] const std::vector<std::string> &args)
 | |
| {
 | |
| 	return {true, get_version_string()};
 | |
| }
 | |
| 
 | |
| std::pair<bool, std::string> CLIHandler::category_list([[maybe_unused]] const std::vector<std::string> &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<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;
 | |
| 	for(Page &member : members)
 | |
| 	{
 | |
| 		stream << member.name << std::endl;
 | |
| 	}
 | |
| 	return {true, stream.str()};
 | |
| }
 |