#pragma once #include #include #include #include #include #include #include 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 loginPassword(const std::string& username, const std::string& password, std::string& err); std::optional loginPin(const std::string& pin, std::string& err); bool logout(const std::string& token); std::optional 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 changeProfile(const std::string& token, const nlohmann::json& payload, std::string& err); nlohmann::json listGroups() const; nlohmann::json listUsers() const; std::optional createUser(const nlohmann::json& payload, std::string& err); std::optional 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 sessions_; thread_local static const AuthSession* tls_session_; void loadOrSeed(); void saveUnlocked(); std::string extractToken(const httplib::Request& req) const; std::optional 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 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