mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
* Refactor config API * Corrections * Test Qt 6.8 * Revert "Test Qt 6.8" This reverts commit eceebec49ecf1a3eda281a0630a9a7577b44ef0a. * Corrections 2 * Update Changelog * Add configFilter element for getconfig call * Do not create errors for DB updates when in read-only mode * Have configuration migration and validation before Hyperion starts * Correct Tests * Corrections * Add migration items * Correct windows build * Ensure that first instance as default one exists * Remove dependency between AuthManager and SSDPHandler * Correct typos * Address CodeQL findings * Replace CamkeSettings by Presets and provide debug scenarios
177 lines
4.5 KiB
C++
177 lines
4.5 KiB
C++
|
|
// hyperion
|
|
#include <db/AuthTable.h>
|
|
#include <QCryptographicHash>
|
|
|
|
// qt
|
|
#include <QDateTime>
|
|
#include <QUuid>
|
|
|
|
/// construct wrapper with auth table
|
|
AuthTable::AuthTable(QObject* parent)
|
|
: DBManager(parent)
|
|
{
|
|
// init Auth table
|
|
setTable("auth");
|
|
// create table columns
|
|
createTable(QStringList()<<"user TEXT"<<"password BLOB"<<"token BLOB"<<"salt BLOB"<<"comment TEXT"<<"id TEXT"<<"created_at TEXT"<<"last_use TEXT");
|
|
};
|
|
|
|
bool AuthTable::createUser(const QString& user, const QString& password)
|
|
{
|
|
// new salt
|
|
QByteArray salt = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha512).toHex();
|
|
QVariantMap map;
|
|
map["user"] = user;
|
|
map["salt"] = salt;
|
|
map["password"] = hashPasswordWithSalt(password,salt);
|
|
map["created_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
|
|
|
return createRecord({{"user",user}}, map);
|
|
}
|
|
|
|
bool AuthTable::userExist(const QString& user)
|
|
{
|
|
return recordExists({{"user",user}});
|
|
}
|
|
|
|
bool AuthTable::isUserAuthorized(const QString& user, const QString& password)
|
|
{
|
|
if(userExist(user) && (calcPasswordHashOfUser(user, password) == getPasswordHashOfUser(user)))
|
|
{
|
|
updateUserUsed(user);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AuthTable::isUserTokenAuthorized(const QString& usr, const QString& token)
|
|
{
|
|
if(getUserToken(usr) == token.toUtf8())
|
|
{
|
|
updateUserUsed(usr);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AuthTable::setUserToken(const QString& user)
|
|
{
|
|
QVariantMap map;
|
|
map["token"] = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha512).toHex();
|
|
|
|
return updateRecord({{"user",user}}, map);
|
|
}
|
|
|
|
const QByteArray AuthTable::getUserToken(const QString& user)
|
|
{
|
|
QVariantMap results;
|
|
getRecord({{"user",user}}, results, QStringList()<<"token");
|
|
|
|
return results["token"].toByteArray();
|
|
}
|
|
|
|
bool AuthTable::updateUserPassword(const QString& user, const QString& newPassword)
|
|
{
|
|
QVariantMap map;
|
|
map["password"] = calcPasswordHashOfUser(user, newPassword);
|
|
|
|
return updateRecord({{"user",user}}, map);
|
|
}
|
|
|
|
bool AuthTable::resetHyperionUser()
|
|
{
|
|
QVariantMap map;
|
|
map["password"] = calcPasswordHashOfUser(hyperion::DEFAULT_USER, hyperion::DEFAULT_PASSWORD);
|
|
|
|
return updateRecord({{"user", hyperion::DEFAULT_USER}}, map);
|
|
}
|
|
|
|
void AuthTable::updateUserUsed(const QString& user)
|
|
{
|
|
QVariantMap map;
|
|
map["last_use"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
|
|
|
updateRecord({{"user",user}}, map);
|
|
}
|
|
|
|
bool AuthTable::tokenExist(const QString& token)
|
|
{
|
|
QVariantMap map;
|
|
map["last_use"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
|
|
|
VectorPair cond;
|
|
cond.append(CPair("token", hashToken(token)));
|
|
if(recordExists(cond))
|
|
{
|
|
// update it
|
|
createRecord(cond,map);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AuthTable::createToken(const QString& token, const QString& comment, const QString& identifier)
|
|
{
|
|
QVariantMap map;
|
|
map["comment"] = comment;
|
|
map["id"] = identifierExist(identifier) ? QUuid::createUuid().toString().remove("{").remove("}").left(5) : identifier;
|
|
map["created_at"] = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
|
|
|
|
return createRecord({{"token", hashToken(token)}}, map);
|
|
}
|
|
|
|
bool AuthTable::deleteToken(const QString& identifier)
|
|
{
|
|
return deleteRecord({{"id", identifier}});
|
|
}
|
|
|
|
bool AuthTable::renameToken(const QString &identifier, const QString &comment)
|
|
{
|
|
QVariantMap map;
|
|
map["comment"] = comment;
|
|
|
|
return updateRecord({{"id", identifier}}, map);
|
|
}
|
|
|
|
const QVector<QVariantMap> AuthTable::getTokenList()
|
|
{
|
|
QVector<QVariantMap> results;
|
|
getRecords(results, QStringList() << "comment" << "id" << "last_use");
|
|
|
|
return results;
|
|
}
|
|
|
|
bool AuthTable::identifierExist(const QString& identifier)
|
|
{
|
|
return recordExists({{"id", identifier}});
|
|
}
|
|
|
|
const QByteArray AuthTable::getPasswordHashOfUser(const QString& user)
|
|
{
|
|
QVariantMap results;
|
|
getRecord({{"user",user}}, results, QStringList()<<"password");
|
|
|
|
return results["password"].toByteArray();
|
|
}
|
|
|
|
const QByteArray AuthTable::calcPasswordHashOfUser(const QString& user, const QString& password)
|
|
{
|
|
// get salt
|
|
QVariantMap results;
|
|
getRecord({{"user",user}}, results, QStringList()<<"salt");
|
|
|
|
// calc
|
|
return hashPasswordWithSalt(password,results["salt"].toByteArray());
|
|
}
|
|
|
|
const QByteArray AuthTable::hashPasswordWithSalt(const QString& password, const QByteArray& salt)
|
|
{
|
|
return QCryptographicHash::hash(password.toUtf8().append(salt), QCryptographicHash::Sha512).toHex();
|
|
}
|
|
|
|
const QByteArray AuthTable::hashToken(const QString& token)
|
|
{
|
|
return QCryptographicHash::hash(token.toUtf8(), QCryptographicHash::Sha512).toHex();
|
|
}
|