Files
App/src/auth/auth_service.hpp
2026-06-16 11:17:28 +07:00

83 lines
3.2 KiB
C++

#pragma once
#include <httplib.h>
#include <nlohmann/json.hpp>
#include <filesystem>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>
namespace lm {
struct AuthSession
{
std::string token;
std::string user_id;
std::string username;
std::string group_id;
std::string group_name;
nlohmann::json permissions;
};
class AuthService
{
public:
explicit AuthService(std::filesystem::path store_path);
httplib::Server::HandlerResponse preRoute(const httplib::Request& req, httplib::Response& res);
const AuthSession* currentSession() const;
std::optional<nlohmann::json> loginPassword(const std::string& username,
const std::string& password,
std::string& err);
std::optional<nlohmann::json> loginPin(const std::string& pin, std::string& err);
bool logout(const std::string& token);
std::optional<nlohmann::json> sessionInfo(const std::string& token) const;
bool changePassword(const std::string& token,
const std::string& current_password,
const std::string& new_password,
std::string& err);
std::optional<nlohmann::json> changeProfile(const std::string& token,
const nlohmann::json& payload,
std::string& err);
nlohmann::json listGroups() const;
nlohmann::json listUsers() const;
std::optional<nlohmann::json> createUser(const nlohmann::json& payload, std::string& err);
std::optional<nlohmann::json> updateUser(const std::string& id,
const nlohmann::json& payload,
std::string& err);
bool deleteUser(const std::string& id, std::string& err);
void registerRoutes(httplib::Server& svr);
private:
std::filesystem::path store_path_;
mutable std::mutex mu_;
nlohmann::json data_;
std::unordered_map<std::string, AuthSession> sessions_;
thread_local static const AuthSession* tls_session_;
void loadOrSeed();
void saveUnlocked();
std::string extractToken(const httplib::Request& req) const;
std::optional<AuthSession> buildSessionUnlocked(const nlohmann::json& user);
bool permissionAllows(const nlohmann::json& perms, const std::string& resource, bool write) const;
bool authorizeApiRequest(const httplib::Request& req, httplib::Response& res);
static bool isPublicApiPath(const std::string& path, const std::string& method);
static std::optional<std::string> resourceForApiPath(const std::string& path);
static bool requiresWrite(const std::string& method);
static nlohmann::json userPublicView(const nlohmann::json& user, const nlohmann::json& group);
const nlohmann::json* findUserByIdUnlocked(const std::string& id) const;
const nlohmann::json* findUserByUsernameUnlocked(const std::string& username) const;
const nlohmann::json* findGroupByIdUnlocked(const std::string& id) const;
bool verifyPasswordUnlocked(const nlohmann::json& user, const std::string& password) const;
bool verifyPinUnlocked(const nlohmann::json& user, const std::string& pin) const;
bool groupAllowsPinUnlocked(const std::string& group_id) const;
};
} // namespace lm