Read-Only Configuration-Database support (#1046)

This commit is contained in:
LordGrey
2020-11-01 19:47:30 +01:00
committed by GitHub
parent 85a55de28c
commit bb652ade36
35 changed files with 268 additions and 90 deletions

View File

@@ -378,11 +378,18 @@ QString API::saveEffect(const QJsonObject &data)
return NO_AUTH;
}
void API::saveSettings(const QJsonObject &data)
bool API::saveSettings(const QJsonObject &data)
{
bool rc = true;
if (!_adminAuthorized)
return;
QMetaObject::invokeMethod(_hyperion, "saveSettings", Qt::QueuedConnection, Q_ARG(QJsonObject, data), Q_ARG(bool, true));
{
rc = false;
}
else
{
QMetaObject::invokeMethod(_hyperion, "saveSettings", Qt::DirectConnection, Q_RETURN_ARG(bool, rc), Q_ARG(QJsonObject, data), Q_ARG(bool, true));
}
return rc;
}
bool API::updateHyperionPassword(const QString &password, const QString &newPassword)

View File

@@ -293,6 +293,7 @@ void JsonAPI::handleSysInfoCommand(const QJsonObject &, const QString &command,
hyperion["gitremote"] = QString(HYPERION_GIT_REMOTE);
hyperion["time"] = QString(__DATE__ " " __TIME__);
hyperion["id"] = _authManager->getID();
hyperion["readOnlyMode"] = _hyperion->getReadOnlyMode();
info["hyperion"] = hyperion;
@@ -875,8 +876,14 @@ void JsonAPI::handleConfigSetCommand(const QJsonObject &message, const QString &
QJsonObject config = message["config"].toObject();
if (API::isHyperionEnabled())
{
API::saveSettings(config);
sendSuccessReply(command, tan);
if ( API::saveSettings(config) )
{
sendSuccessReply(command, tan);
}
else
{
sendErrorReply("Save settings failed", command, tan);
}
}
else
sendErrorReply("Saving configuration while Hyperion is disabled isn't possible", command, tan);

View File

@@ -19,6 +19,7 @@ static QThreadStorage<QSqlDatabase> _databasePool;
DBManager::DBManager(QObject* parent)
: QObject(parent)
, _log(Logger::getInstance("DB"))
, _readonlyMode (false)
{
}
@@ -58,6 +59,11 @@ QSqlDatabase DBManager::getDB() const
bool DBManager::createRecord(const VectorPair& conditions, const QVariantMap& columns) const
{
if ( _readonlyMode )
{
return false;
}
if(recordExists(conditions))
{
// if there is no column data, return
@@ -144,6 +150,11 @@ bool DBManager::recordExists(const VectorPair& conditions) const
bool DBManager::updateRecord(const VectorPair& conditions, const QVariantMap& columns) const
{
if ( _readonlyMode )
{
return false;
}
QSqlDatabase idb = getDB();
QSqlQuery query(idb);
query.setForwardOnly(true);
@@ -276,6 +287,11 @@ bool DBManager::getRecords(QVector<QVariantMap>& results, const QStringList& tCo
bool DBManager::deleteRecord(const VectorPair& conditions) const
{
if ( _readonlyMode )
{
return false;
}
if(conditions.isEmpty())
{
Error(_log, "Oops, a deleteRecord() call wants to delete the entire table (%s)! Denied it", QSTRING_CSTR(_table));
@@ -311,6 +327,11 @@ bool DBManager::deleteRecord(const VectorPair& conditions) const
bool DBManager::createTable(QStringList& columns) const
{
if ( _readonlyMode )
{
return false;
}
if(columns.isEmpty())
{
Error(_log,"Empty tables aren't supported!");
@@ -353,6 +374,11 @@ bool DBManager::createTable(QStringList& columns) const
bool DBManager::createColumn(const QString& column) const
{
if ( _readonlyMode )
{
return false;
}
QSqlDatabase idb = getDB();
QSqlQuery query(idb);
if(!query.exec(QString("ALTER TABLE %1 ADD COLUMN %2").arg(_table,column)))
@@ -374,6 +400,11 @@ bool DBManager::tableExists(const QString& table) const
bool DBManager::deleteTable(const QString& table) const
{
if ( _readonlyMode )
{
return false;
}
if(tableExists(table))
{
QSqlDatabase idb = getDB();

View File

@@ -10,10 +10,10 @@
AuthManager *AuthManager::manager = nullptr;
AuthManager::AuthManager(QObject *parent)
AuthManager::AuthManager(QObject *parent, bool readonlyMode)
: QObject(parent)
, _authTable(new AuthTable("", this))
, _metaTable(new MetaTable(this))
, _authTable(new AuthTable("", this, readonlyMode))
, _metaTable(new MetaTable(this, readonlyMode))
, _pendingRequests()
, _authRequired(true)
, _timer(new QTimer(this))

View File

@@ -39,10 +39,10 @@
// Boblight
#include <boblightserver/BoblightServer.h>
Hyperion::Hyperion(quint8 instance)
Hyperion::Hyperion(quint8 instance, bool readonlyMode)
: QObject()
, _instIndex(instance)
, _settingsManager(new SettingsManager(instance, this))
, _settingsManager(new SettingsManager(instance, this, readonlyMode))
, _componentRegister(this)
, _ledString(hyperion::createLedString(getSetting(settings::LEDS).array(), hyperion::createColorOrder(getSetting(settings::DEVICE).object())))
, _imageProcessor(new ImageProcessor(_ledString, this))
@@ -54,6 +54,7 @@ Hyperion::Hyperion(quint8 instance)
, _hwLedCount()
, _ledGridSize(hyperion::getLedLayoutGridSize(getSetting(settings::LEDS).array()))
, _ledBuffer(_ledString.leds().size(), ColorRgb::BLACK)
, _readOnlyMode(readonlyMode)
{
}

View File

@@ -9,11 +9,12 @@
HyperionIManager* HyperionIManager::HIMinstance;
HyperionIManager::HyperionIManager(const QString& rootPath, QObject* parent)
HyperionIManager::HyperionIManager(const QString& rootPath, QObject* parent, bool readonlyMode)
: QObject(parent)
, _log(Logger::getInstance("HYPERION"))
, _instanceTable( new InstanceTable(rootPath, this) )
, _instanceTable( new InstanceTable(rootPath, this, readonlyMode) )
, _rootPath( rootPath )
, _readonlyMode(readonlyMode)
{
HIMinstance = this;
qRegisterMetaType<InstanceState>("InstanceState");
@@ -75,7 +76,7 @@ bool HyperionIManager::startInstance(quint8 inst, bool block, QObject* caller, i
{
QThread* hyperionThread = new QThread();
hyperionThread->setObjectName("HyperionThread");
Hyperion* hyperion = new Hyperion(inst);
Hyperion* hyperion = new Hyperion(inst, _readonlyMode);
hyperion->moveToThread(hyperionThread);
// setup thread management
connect(hyperionThread, &QThread::started, hyperion, &Hyperion::start);

View File

@@ -14,11 +14,13 @@
QJsonObject SettingsManager::schemaJson;
SettingsManager::SettingsManager(quint8 instance, QObject* parent)
SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonlyMode)
: QObject(parent)
, _log(Logger::getInstance("SETTINGSMGR"))
, _sTable(new SettingsTable(instance, this))
, _readonlyMode(readonlyMode)
{
_sTable->setReadonlyMode(_readonlyMode);
// get schema
if(schemaJson.isEmpty())
{
@@ -152,18 +154,24 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
}
}
int rc = true;
// compare database data with new data to emit/save changes accordingly
for(const auto & key : keyList)
{
QString data = newValueList.takeFirst();
if(_sTable->getSettingsRecordString(key) != data)
{
_sTable->createSettingsRecord(key, data);
emit settingsChanged(settings::stringToType(key), QJsonDocument::fromJson(data.toLocal8Bit()));
if ( ! _sTable->createSettingsRecord(key, data) )
{
rc = false;
}
else
{
emit settingsChanged(settings::stringToType(key), QJsonDocument::fromJson(data.toLocal8Bit()));
}
}
}
return true;
return rc;
}
bool SettingsManager::handleConfigUpgrade(QJsonObject& config)