Files
logos-protocol/cpp/token_manager.cpp
T
Dario Gabriel LipicarandClaude Opus 5 b218f4c8e5 feat: the host-services C ABI a trust-root module needs
capability_module is the last legacy Qt Q_INVOKABLE provider, and it cannot
become an ordinary `interface: universal` module while the two things it does
have no C entry point: reading the token store, and pushing a token to an
ARBITRARY target. This adds both, plus the grant that gates them. Purely
additive — no existing symbol changes behaviour.

  lp_token_keys()               the module names THIS image's TokenManager
                                holds. NULL means REFUSED, never "empty" — a
                                granted call with no tokens answers "[]", and a
                                known-caller gate needs to tell those apart.
  lp_inform_module_token_to()   routes to LogosAPIClient::informModuleToken_module,
                                the 5-arg form. Note the existing
                                lp_inform_module_token is the WRONG DIRECTION
                                for this: it reaches a consumer path that
                                hardcodes requestObject("capability_module"),
                                i.e. core -> capability, not capability ->
                                target. That 5-arg method had no C entry point.
  lp_grant_host_services()      sets the in-image grant over the closed set
                                {token_registry, token_delivery}. Replaces
                                rather than merges; NULL/""/"[]" clears. An
                                unknown name is rejected wholesale and leaves
                                the existing grant untouched, so a typo can
                                never silently drop a service.

Why the gate is per-IMAGE, which looks like an odd choice until it doesn't:
the host binary and a module's cdylib each link their own copy of this library,
so they have separate process-global state. A gate "simplified" into the host
would be checked against state the calling image can never set, and would read
as ungranted forever. The grant therefore crosses the module-impl C ABI the
same way the auth token already does — hence the logos_module_grant_host_services
declaration added to logos_module_impl.h, whose generated body and host-side
call land in logos-cpp-sdk and logos-module-loader-qt respectively.

MINOR 2 -> 3; MAJOR unchanged, so the equal-MAJOR compatibility rule is
unaffected. 387/387 tests pass, including 6 new ones covering both gates
closed, both opened, clearing re-closing them, and the unknown-name rejection.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 20:43:08 -03:00

96 lines
2.1 KiB
C++

#include "token_manager.h"
#include <QMutexLocker>
TokenManager& TokenManager::instance()
{
static TokenManager instance;
return instance;
}
TokenManager::TokenManager(QObject *parent)
: QObject(parent)
{
}
TokenManager::~TokenManager()
{
}
void TokenManager::saveToken(const QString& key, const QString& token)
{
QMutexLocker locker(&m_mutex);
m_tokens[key] = token;
emit tokenSaved(key);
}
void TokenManager::saveToken(const std::string& key, const std::string& token)
{
saveToken(QString::fromStdString(key), QString::fromStdString(token));
}
QString TokenManager::getToken(const QString& key) const
{
QMutexLocker locker(&m_mutex);
return m_tokens.value(key, QString());
}
std::string TokenManager::getToken(const std::string& key) const
{
return getToken(QString::fromStdString(key)).toStdString();
}
bool TokenManager::hasToken(const QString& key) const
{
QMutexLocker locker(&m_mutex);
return m_tokens.contains(key);
}
bool TokenManager::hasToken(const std::string& key) const
{
return hasToken(QString::fromStdString(key));
}
bool TokenManager::removeToken(const QString& key)
{
QMutexLocker locker(&m_mutex);
if (m_tokens.contains(key)) {
m_tokens.remove(key);
emit tokenRemoved(key);
return true;
}
return false;
}
bool TokenManager::removeToken(const std::string& key)
{
return removeToken(QString::fromStdString(key));
}
void TokenManager::clearAllTokens()
{
QMutexLocker locker(&m_mutex);
m_tokens.clear();
emit allTokensCleared();
}
QList<QString> TokenManager::getTokenKeys() const
{
QMutexLocker locker(&m_mutex);
return m_tokens.keys();
}
std::vector<std::string> TokenManager::getTokenKeysStd() const
{
QMutexLocker locker(&m_mutex);
std::vector<std::string> keys;
keys.reserve(static_cast<size_t>(m_tokens.size()));
for (auto it = m_tokens.constBegin(); it != m_tokens.constEnd(); ++it)
keys.push_back(it.key().toStdString());
return keys;
}
int TokenManager::tokenCount() const
{
QMutexLocker locker(&m_mutex);
return m_tokens.size();
}