2022-08-28 17:37:09 +02:00
|
|
|
#ifndef BACKEND_CONTROLLERS_H
|
|
|
|
#define BACKEND_CONTROLLERS_H
|
2022-09-03 23:32:20 +02:00
|
|
|
#include <variant>
|
2022-09-04 05:33:26 +02:00
|
|
|
#include <unordered_map>
|
|
|
|
#include <shared_mutex>
|
2022-09-03 23:32:20 +02:00
|
|
|
|
2022-08-28 17:37:09 +02:00
|
|
|
#include <drogon/drogon.h>
|
|
|
|
#include <botan/rng.h>
|
2022-09-03 23:32:20 +02:00
|
|
|
#include <msd/channel.hpp>
|
2022-09-04 05:33:26 +02:00
|
|
|
#include <trantor/net/EventLoopThread.h>
|
|
|
|
#include <kubazip/zip/zip.h>
|
2022-08-28 17:37:09 +02:00
|
|
|
|
|
|
|
#include "db/db.h"
|
|
|
|
|
|
|
|
using req_type = const drogon::HttpRequestPtr&;
|
|
|
|
using cbk_type = std::function<void(const drogon::HttpResponsePtr &)>&&;
|
|
|
|
|
|
|
|
namespace api {
|
|
|
|
class admin : public drogon::HttpController<admin> {
|
|
|
|
public:
|
|
|
|
METHOD_LIST_BEGIN
|
|
|
|
METHOD_ADD(admin::users, "/users", drogon::Get, "Login", "Admin");
|
|
|
|
METHOD_ADD(admin::set_role, "/set_role", drogon::Post, "Login", "Admin");
|
|
|
|
METHOD_ADD(admin::logout, "/logout", drogon::Post, "Login", "Admin");
|
|
|
|
METHOD_ADD(admin::delete_user, "/delete", drogon::Post, "Login", "Admin");
|
|
|
|
METHOD_ADD(admin::disable_2fa, "/disable_2fa", drogon::Post, "Login", "Admin");
|
2022-09-05 16:29:13 +02:00
|
|
|
METHOD_ADD(admin::is_admin, "/is_admin", drogon::Get, "Login", "Admin");
|
2022-09-06 15:33:54 +02:00
|
|
|
METHOD_ADD(admin::get_token, "/get_token/{}", drogon::Get, "Login", "Admin");
|
2022-08-28 17:37:09 +02:00
|
|
|
METHOD_LIST_END
|
|
|
|
|
|
|
|
void users(req_type, cbk_type);
|
|
|
|
void set_role(req_type, cbk_type);
|
|
|
|
void logout(req_type, cbk_type);
|
|
|
|
void delete_user(req_type, cbk_type);
|
|
|
|
void disable_2fa(req_type, cbk_type);
|
2022-09-05 16:29:13 +02:00
|
|
|
void is_admin(req_type, cbk_type);
|
2022-09-06 15:33:54 +02:00
|
|
|
void get_token(req_type, cbk_type, uint64_t user);
|
2022-08-28 17:37:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class auth : public drogon::HttpController<auth> {
|
|
|
|
public:
|
|
|
|
METHOD_LIST_BEGIN
|
|
|
|
METHOD_ADD(auth::gitlab, "/gitlab", drogon::Get);
|
|
|
|
METHOD_ADD(auth::gitlab_callback, "/gitlab_callback?code={}", drogon::Get);
|
|
|
|
METHOD_ADD(auth::signup, "/signup", drogon::Post);
|
|
|
|
METHOD_ADD(auth::login, "/login", drogon::Post);
|
|
|
|
METHOD_ADD(auth::refresh, "/refresh", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(auth::tfa_setup, "/2fa/setup", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(auth::tfa_complete, "/2fa/complete", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(auth::tfa_disable, "/2fa/disable", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(auth::change_password, "/change_password", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(auth::logout_all, "/logout_all", drogon::Post, "Login");
|
|
|
|
METHOD_LIST_END
|
|
|
|
|
|
|
|
struct gitlab_tokens {
|
|
|
|
gitlab_tokens(std::string at, std::string rt) : at(std::move(at)), rt(std::move(rt)) {}
|
|
|
|
std::string at, rt;
|
|
|
|
};
|
|
|
|
struct gitlab_user {
|
|
|
|
gitlab_user(std::string name, bool isAdmin) : name(std::move(name)), is_admin(isAdmin) {}
|
|
|
|
std::string name;
|
|
|
|
bool is_admin;
|
|
|
|
};
|
|
|
|
|
|
|
|
static std::unique_ptr<Botan::RNG> rng;
|
|
|
|
|
2022-09-04 10:35:10 +02:00
|
|
|
static std::optional<gitlab_tokens> get_gitlab_tokens(const std::string&, bool token);
|
2022-08-28 17:37:09 +02:00
|
|
|
static std::optional<gitlab_user> get_gitlab_user(const std::string&);
|
|
|
|
static bool verify2fa(const db::User&, uint32_t totp);
|
|
|
|
static void send_mail(const db::User&);
|
|
|
|
static std::string get_token(const db::User&);
|
|
|
|
static void generate_root(db::User&);
|
|
|
|
static void revoke_all(const db::User&);
|
2022-09-05 15:59:15 +02:00
|
|
|
static std::string get_jwt_secret();
|
2022-08-28 17:37:09 +02:00
|
|
|
|
|
|
|
void gitlab(req_type, cbk_type);
|
|
|
|
void gitlab_callback(req_type, cbk_type, std::string code);
|
|
|
|
void signup(req_type, cbk_type);
|
|
|
|
void login(req_type, cbk_type);
|
|
|
|
void refresh(req_type, cbk_type);
|
|
|
|
void tfa_setup(req_type, cbk_type);
|
|
|
|
void tfa_complete(req_type, cbk_type);
|
|
|
|
void tfa_disable(req_type, cbk_type);
|
|
|
|
void change_password(req_type, cbk_type);
|
|
|
|
void logout_all(req_type, cbk_type);
|
|
|
|
};
|
|
|
|
|
|
|
|
class fs : public drogon::HttpController<fs> {
|
|
|
|
public:
|
|
|
|
METHOD_LIST_BEGIN
|
|
|
|
METHOD_ADD(fs::root, "/root", drogon::Get, "Login");
|
|
|
|
METHOD_ADD(fs::node, "/node/{}", drogon::Get, "Login");
|
|
|
|
METHOD_ADD(fs::path, "/path/{}", drogon::Get, "Login");
|
|
|
|
METHOD_ADD(fs::create_node_req<false>, "/createFolder", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(fs::create_node_req<true>, "/createFile", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(fs::delete_node_req, "/delete/{}", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(fs::upload, "/upload/{}", drogon::Post, "Login");
|
2022-09-03 23:32:20 +02:00
|
|
|
METHOD_ADD(fs::create_zip, "/create_zip", drogon::Post, "Login");
|
2022-08-28 17:37:09 +02:00
|
|
|
METHOD_ADD(fs::download, "/download", drogon::Post, "Login");
|
2022-09-03 23:32:20 +02:00
|
|
|
METHOD_ADD(fs::download_multi, "/download_multi", drogon::Post, "Login");
|
|
|
|
METHOD_ADD(fs::download_preview, "/download_preview/{}", drogon::Get, "Login");
|
|
|
|
METHOD_ADD(fs::get_type, "/get_type/{}", drogon::Get, "Login");
|
2022-08-28 17:37:09 +02:00
|
|
|
METHOD_LIST_END
|
|
|
|
|
2022-09-03 23:32:20 +02:00
|
|
|
enum class create_node_error {
|
|
|
|
INVALID_NAME,
|
|
|
|
INVALID_PARENT,
|
|
|
|
FILE_PARENT
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mutex_stream {
|
|
|
|
std::stringstream ss;
|
|
|
|
std::mutex mutex;
|
|
|
|
bool done = false;
|
|
|
|
};
|
|
|
|
|
2022-08-28 17:37:09 +02:00
|
|
|
static std::optional<db::INode> get_node(uint64_t node);
|
|
|
|
static std::optional<db::INode> get_node_and_validate(const db::User& user, uint64_t node);
|
|
|
|
static std::vector<db::INode> get_children(const db::INode& parent);
|
2022-09-03 23:32:20 +02:00
|
|
|
static std::variant<db::INode, fs::create_node_error, std::tuple<bool, uint64_t>>
|
|
|
|
create_node(std::string name, const db::User& owner, bool file, const std::optional<uint64_t> &parent, bool force = false);
|
|
|
|
static void delete_node(db::INode node, msd::channel<std::string>& chan, bool allow_root = false);
|
2022-09-04 05:33:26 +02:00
|
|
|
static std::shared_ptr<std::shared_mutex> get_user_mutex(uint64_t user_id);
|
2022-08-28 17:37:09 +02:00
|
|
|
|
|
|
|
void root(req_type, cbk_type);
|
|
|
|
void node(req_type, cbk_type, uint64_t node);
|
|
|
|
void path(req_type, cbk_type, uint64_t node);
|
|
|
|
template<bool file> void create_node_req(req_type req, cbk_type cbk);
|
|
|
|
void delete_node_req(req_type, cbk_type, uint64_t node);
|
|
|
|
void upload(req_type, cbk_type, uint64_t node);
|
2022-09-03 23:32:20 +02:00
|
|
|
void create_zip(req_type, cbk_type);
|
2022-08-28 17:37:09 +02:00
|
|
|
void download(req_type, cbk_type);
|
2022-09-03 23:32:20 +02:00
|
|
|
void download_multi(req_type, cbk_type);
|
|
|
|
void download_preview(req_type, cbk_type, uint64_t node);
|
|
|
|
void get_type(req_type, cbk_type, uint64_t node);
|
2022-09-04 05:33:26 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
static trantor::EventLoop* get_zip_loop();
|
|
|
|
static trantor::EventLoop* get_delete_loop();
|
|
|
|
static void generate_path(db::INode node, std::string& str);
|
|
|
|
static Json::Value generate_path(db::INode node);
|
|
|
|
static uint64_t calc_total_size(const db::INode& base);
|
|
|
|
static void add_to_zip(struct zip_t* zip, const std::string& key, const db::INode& node, const std::string& path);
|
|
|
|
|
|
|
|
static uint64_t next_temp_id;
|
|
|
|
static std::unordered_map<std::string, std::string> zip_to_temp_map;
|
|
|
|
static std::unordered_map<std::string, std::tuple<std::string, uint64_t, uint64_t>> in_progress_zips;
|
2022-08-28 17:37:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class user : public drogon::HttpController<user> {
|
|
|
|
public:
|
|
|
|
METHOD_LIST_BEGIN
|
|
|
|
METHOD_ADD(user::info, "/info", drogon::Get, "Login");
|
|
|
|
METHOD_ADD(user::delete_user, "/delete", drogon::Post, "Login");
|
|
|
|
METHOD_LIST_END
|
|
|
|
|
|
|
|
void info(req_type, cbk_type);
|
|
|
|
void delete_user(req_type, cbk_type);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif //BACKEND_CONTROLLERS_H
|