geopro/src/app/Credential.cpp

75 lines
1.9 KiB
C++

#include "Credential.hpp"
#include <QDateTime>
#include <QEventLoop>
#include <keychain.h>
namespace geopro::app {
namespace {
const QString kService = QStringLiteral("Geopro3");
const QString kKey = QStringLiteral("session");
// QtKeychain 的 job 是异步的;用局部事件循环跑成同步(启动/登录时一次性调用,可接受)。
QString readRaw()
{
QKeychain::ReadPasswordJob job(kService);
job.setAutoDelete(false);
job.setKey(kKey);
QEventLoop loop;
QObject::connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
job.start();
loop.exec();
if (job.error() != QKeychain::NoError) return {};
return job.textData();
}
} // namespace
void rememberSession(const QString& token)
{
if (token.isEmpty()) return;
const QString payload =
QString::number(QDateTime::currentSecsSinceEpoch()) + QStringLiteral("|") + token;
QKeychain::WritePasswordJob job(kService);
job.setAutoDelete(false);
job.setKey(kKey);
job.setTextData(payload);
QEventLoop loop;
QObject::connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
job.start();
loop.exec();
}
QString recallValidToken(int maxAgeDays)
{
const QString raw = readRaw();
if (raw.isEmpty()) return {};
const int sep = raw.indexOf(QLatin1Char('|'));
if (sep <= 0) return {};
bool ok = false;
const qint64 ts = raw.left(sep).toLongLong(&ok);
if (!ok) return {};
const qint64 ageSec = QDateTime::currentSecsSinceEpoch() - ts;
if (ageSec < 0 || ageSec > static_cast<qint64>(maxAgeDays) * 24 * 3600) return {};
return raw.mid(sep + 1);
}
void forgetSession()
{
QKeychain::DeletePasswordJob job(kService);
job.setAutoDelete(false);
job.setKey(kKey);
QEventLoop loop;
QObject::connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
job.start();
loop.exec();
}
} // namespace geopro::app