Files
logos-basecamp/app/utils/AccessPolicyOption.cpp
T
Dario Gabriel Lipicar 7851bf9f46 feat(host): per-plugin identities, an opt-in access policy, and the source split
Each loaded plugin -- including pure-QML ones -- gets its own LogosAPI identity
rather than sharing the host's, so a plugin's calls are attributable and can be
refused independently. The host-services grant is wired through to
capability_module, and its trust root is guarded on an OUTCOME rather than a
log line.

Inter-module access policy stays OFF by default: enforce mode's derived
deny-by-default gates every ui_qml app's calls to its own backend module,
because UI plugins load out-of-process and are not tracked as dependents in the
core ModuleRegistry. Operators opt in per launch with --access-policy enforce
or LOGOS_ACCESS_POLICY.

Takes the Qt host runtime from logos-plugin-qt rather than logos-qt-sdk, which
keeps only the Qt<->lp seam headers, and moves logos-protocol onto the rev that
split host needs. On Windows logos_core must come LAST on the link line: GNU ld
resolves an archive left to right, so the view runtime's references have to be
undefined already when it reaches the import library.

Separates the two source trees -- app/ is the host, src/ is the UI shell -- and
brings the CI onto setup-nix-cache-action. Merges master.
2026-08-22 16:42:13 -03:00

57 lines
1.8 KiB
C++

#include "AccessPolicyOption.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonParseError>
namespace LogosBasecamp {
AccessPolicyResolution resolveAccessPolicy(const QString& arg)
{
AccessPolicyResolution out;
const QString trimmed = arg.trimmed();
if (trimmed.isEmpty())
return out; // ok, no policy — the default
// Checked before the file branch, so `--access-policy enforce` never gets
// read as a relative path named "enforce" (which would make arming
// enforcement depend on the working directory the app was launched from).
if (trimmed == QLatin1String(kAccessPolicyEnforceAlias)) {
out.policyJson = QString::fromUtf8(kAccessPolicyEnforceEnvelope);
return out;
}
QString content;
QString source;
if (trimmed.startsWith(QLatin1Char('{'))) {
content = trimmed;
source = QStringLiteral("inline --access-policy JSON");
} else {
QFile f(trimmed);
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
out.ok = false;
out.error = QStringLiteral("--access-policy file '%1' could not be opened: %2")
.arg(trimmed, f.errorString());
return out;
}
content = QString::fromUtf8(f.readAll());
source = QStringLiteral("--access-policy file '%1'").arg(trimmed);
}
QJsonParseError err{};
QJsonDocument::fromJson(content.toUtf8(), &err);
if (err.error != QJsonParseError::NoError) {
out.ok = false;
out.error = QStringLiteral("%1 is not valid JSON: %2 (at offset %3)")
.arg(source, err.errorString())
.arg(err.offset);
return out;
}
out.policyJson = content;
return out;
}
} // namespace LogosBasecamp