148 lines
3.8 KiB
C++
148 lines
3.8 KiB
C++
|
|
#include "LocalStateHelper.h"
|
||
|
|
#include <QFile>
|
||
|
|
#include <QFileInfo>
|
||
|
|
#include <QJsonDocument>
|
||
|
|
#include <QDir>
|
||
|
|
|
||
|
|
LocalStateHelper::LocalStateHelper(const QString& baseDir)
|
||
|
|
: m_baseDir(baseDir)
|
||
|
|
, m_filePath(baseDir + "/config/local_state.json")
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LocalStateHelper::loadState(const QString& relativePath)
|
||
|
|
{
|
||
|
|
m_filePath = m_baseDir + "/" + relativePath;
|
||
|
|
QFile file(m_filePath);
|
||
|
|
if (!file.exists())
|
||
|
|
{
|
||
|
|
QDir dir(QFileInfo(m_filePath).path());
|
||
|
|
if (!dir.exists() && !dir.mkpath("."))
|
||
|
|
{
|
||
|
|
m_error = QString("Cannot create state directory: %1").arg(dir.path());
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_state = QJsonObject{
|
||
|
|
{"max_policy_seq", 0},
|
||
|
|
{"last_success_run_at", QString()},
|
||
|
|
{"last_online_verified_at", QString()},
|
||
|
|
{"last_success_version", QString()}
|
||
|
|
};
|
||
|
|
m_loaded = true;
|
||
|
|
if (!saveState())
|
||
|
|
{
|
||
|
|
m_error = QString("Cannot write new state file: %1").arg(m_filePath);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!file.open(QIODevice::ReadOnly))
|
||
|
|
{
|
||
|
|
m_error = QString("Cannot open state file: %1").arg(m_filePath);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
QByteArray raw = file.readAll();
|
||
|
|
file.close();
|
||
|
|
|
||
|
|
QJsonParseError parseError;
|
||
|
|
QJsonDocument doc = QJsonDocument::fromJson(raw, &parseError);
|
||
|
|
if (parseError.error != QJsonParseError::NoError || !doc.isObject())
|
||
|
|
{
|
||
|
|
m_error = QString("Invalid state JSON: %1").arg(parseError.errorString());
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_state = doc.object();
|
||
|
|
m_loaded = true;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LocalStateHelper::saveState() const
|
||
|
|
{
|
||
|
|
if (!m_loaded)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
QFile file(m_filePath);
|
||
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
QJsonDocument doc(m_state);
|
||
|
|
file.write(doc.toJson(QJsonDocument::Indented));
|
||
|
|
file.close();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LocalStateHelper::isLoaded() const
|
||
|
|
{
|
||
|
|
return m_loaded;
|
||
|
|
}
|
||
|
|
|
||
|
|
QString LocalStateHelper::errorString() const
|
||
|
|
{
|
||
|
|
return m_error;
|
||
|
|
}
|
||
|
|
|
||
|
|
qint64 LocalStateHelper::maxPolicySeq() const
|
||
|
|
{
|
||
|
|
return m_state.value("max_policy_seq").toVariant().toLongLong();
|
||
|
|
}
|
||
|
|
|
||
|
|
QDateTime LocalStateHelper::lastSuccessRunAt() const
|
||
|
|
{
|
||
|
|
return QDateTime::fromString(m_state.value("last_success_run_at").toString(), Qt::ISODate);
|
||
|
|
}
|
||
|
|
|
||
|
|
QDateTime LocalStateHelper::lastOnlineVerifiedAt() const
|
||
|
|
{
|
||
|
|
return QDateTime::fromString(m_state.value("last_online_verified_at").toString(), Qt::ISODate);
|
||
|
|
}
|
||
|
|
|
||
|
|
QString LocalStateHelper::lastSuccessVersion() const
|
||
|
|
{
|
||
|
|
return m_state.value("last_success_version").toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LocalStateHelper::isPolicySeqRolledBack(qint64 policySeq) const
|
||
|
|
{
|
||
|
|
if (!m_loaded)
|
||
|
|
return false;
|
||
|
|
return policySeq < maxPolicySeq();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LocalStateHelper::isSystemTimeRewound() const
|
||
|
|
{
|
||
|
|
if (!m_loaded)
|
||
|
|
return false;
|
||
|
|
const QDateTime now = QDateTime::currentDateTimeUtc();
|
||
|
|
const QDateTime lastRun = lastSuccessRunAt();
|
||
|
|
const QDateTime lastOnline = lastOnlineVerifiedAt();
|
||
|
|
return (lastRun.isValid() && now < lastRun)
|
||
|
|
|| (lastOnline.isValid() && now < lastOnline);
|
||
|
|
}
|
||
|
|
|
||
|
|
void LocalStateHelper::updateAfterSuccessfulRun(const QString& currentVersion, qint64 policySeq)
|
||
|
|
{
|
||
|
|
if (!m_loaded)
|
||
|
|
m_loaded = true;
|
||
|
|
|
||
|
|
m_state["last_success_run_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
||
|
|
m_state["last_success_version"] = currentVersion;
|
||
|
|
if (policySeq > maxPolicySeq())
|
||
|
|
m_state["max_policy_seq"] = policySeq;
|
||
|
|
}
|
||
|
|
|
||
|
|
void LocalStateHelper::updateOnlineVerified(qint64 policySeq)
|
||
|
|
{
|
||
|
|
if (!m_loaded)
|
||
|
|
m_loaded = true;
|
||
|
|
|
||
|
|
m_state["last_online_verified_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
||
|
|
if (policySeq > maxPolicySeq())
|
||
|
|
m_state["max_policy_seq"] = policySeq;
|
||
|
|
}
|