mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Add userToken Auth
This commit is contained in:
parent
7f444a5a92
commit
034bd164a2
@ -91,6 +91,11 @@ signals:
|
|||||||
///
|
///
|
||||||
void forwardJsonMessage(QJsonObject);
|
void forwardJsonMessage(QJsonObject);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief The API might decide to block connections for security reasons, this emitter should close the socket
|
||||||
|
///
|
||||||
|
void forceClose();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Auth management pointer
|
/// Auth management pointer
|
||||||
AuthManager* _authManager;
|
AuthManager* _authManager;
|
||||||
|
@ -80,6 +80,52 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Test if a user token is authorized for access.
|
||||||
|
/// @param usr The user name
|
||||||
|
/// @param token The token
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
inline bool isUserTokenAuthorized(const QString& usr, const QString& token)
|
||||||
|
{
|
||||||
|
if(getUserToken(usr) == token.toUtf8())
|
||||||
|
{
|
||||||
|
updateUserUsed(usr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Update token of a user. It's an alternate login path which is replaced on startup. This token is NOT hashed(!)
|
||||||
|
/// @param user The user name
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
inline bool setUserToken(const QString& user)
|
||||||
|
{
|
||||||
|
QVariantMap map;
|
||||||
|
map["token"] = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha512).toHex();
|
||||||
|
|
||||||
|
VectorPair cond;
|
||||||
|
cond.append(CPair("user", user));
|
||||||
|
return updateRecord(cond, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get token of a user. This token is NOT hashed(!)
|
||||||
|
/// @param user The user name
|
||||||
|
/// @return The token
|
||||||
|
///
|
||||||
|
inline const QByteArray getUserToken(const QString& user)
|
||||||
|
{
|
||||||
|
QVariantMap results;
|
||||||
|
VectorPair cond;
|
||||||
|
cond.append(CPair("user", user));
|
||||||
|
getRecord(cond, results, QStringList()<<"token");
|
||||||
|
|
||||||
|
return results["token"].toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief update password of given user. The user should be tested (isUserAuthorized) to verify this change
|
/// @brief update password of given user. The user should be tested (isUserAuthorized) to verify this change
|
||||||
/// @param user The user name
|
/// @param user The user name
|
||||||
|
@ -61,6 +61,19 @@ public:
|
|||||||
///
|
///
|
||||||
const bool & isLocalAdminAuthRequired() { return _localAdminAuthRequired; };
|
const bool & isLocalAdminAuthRequired() { return _localAdminAuthRequired; };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if Hyperion user has default password
|
||||||
|
/// @return True if so, else false
|
||||||
|
///
|
||||||
|
const bool hasHyperionDefaultPw() { return isUserAuthorized("Hyperion","hyperion"); };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get the current valid token for user. Make sure this call is allowed!
|
||||||
|
/// @param For the defined user
|
||||||
|
/// @return The token
|
||||||
|
///
|
||||||
|
const QString getUserToken(const QString & usr = "Hyperion");
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Reset Hyperion user
|
/// @brief Reset Hyperion user
|
||||||
/// @return True on success else false
|
/// @return True on success else false
|
||||||
@ -89,6 +102,14 @@ public:
|
|||||||
///
|
///
|
||||||
bool isTokenAuthorized(const QString& token);
|
bool isTokenAuthorized(const QString& token);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if token is authorized
|
||||||
|
/// @param usr The username
|
||||||
|
/// @param token The token
|
||||||
|
/// @return True if authorized else false
|
||||||
|
///
|
||||||
|
bool isUserTokenAuthorized(const QString& usr, const QString& token);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Change password of user
|
/// @brief Change password of user
|
||||||
/// @param user The username
|
/// @param user The username
|
||||||
|
@ -58,6 +58,12 @@ JsonAPI::JsonAPI(QString peerAddress, Logger* log, const bool& localConnection,
|
|||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(JSONRPC_schemas);
|
Q_INIT_RESOURCE(JSONRPC_schemas);
|
||||||
|
|
||||||
|
// For security we block external connections if default PW is set
|
||||||
|
if(!localConnection && _authManager->hasHyperionDefaultPw())
|
||||||
|
{
|
||||||
|
emit forceClose();
|
||||||
|
}
|
||||||
|
|
||||||
// if this is localConnection and network allows unauth locals, set authorized flag
|
// if this is localConnection and network allows unauth locals, set authorized flag
|
||||||
if(_apiAuthRequired && localConnection)
|
if(_apiAuthRequired && localConnection)
|
||||||
_authorized = !_authManager->isLocalAuthRequired();
|
_authorized = !_authManager->isLocalAuthRequired();
|
||||||
@ -1127,7 +1133,7 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject & message, const QString
|
|||||||
if(subc == "newPasswordRequired")
|
if(subc == "newPasswordRequired")
|
||||||
{
|
{
|
||||||
QJsonObject req;
|
QJsonObject req;
|
||||||
req["newPasswordRequired"] = _authManager->isUserAuthorized("Hyperion", "hyperion");
|
req["newPasswordRequired"] = _authManager->hasHyperionDefaultPw();
|
||||||
sendSuccessDataReply(QJsonDocument(req), command+"-"+subc, tan);
|
sendSuccessDataReply(QJsonDocument(req), command+"-"+subc, tan);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1287,12 +1293,27 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject & message, const QString
|
|||||||
// login
|
// login
|
||||||
if(subc == "login")
|
if(subc == "login")
|
||||||
{
|
{
|
||||||
// catch token auth
|
|
||||||
const QString& token = message["token"].toString().trimmed();
|
const QString& token = message["token"].toString().trimmed();
|
||||||
|
|
||||||
|
// catch token
|
||||||
if(!token.isEmpty())
|
if(!token.isEmpty())
|
||||||
{
|
{
|
||||||
if(token.count() >= 36)
|
// userToken is longer
|
||||||
|
if(token.count() > 36)
|
||||||
|
{
|
||||||
|
if(_authManager->isUserTokenAuthorized("Hyperion",token))
|
||||||
|
{
|
||||||
|
_authorized = true;
|
||||||
|
_userAuthorized = true;
|
||||||
|
sendSuccessReply(command+"-"+subc, tan);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sendErrorReply("No Authorization", command+"-"+subc, tan);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// usual app token is 36
|
||||||
|
if(token.count() == 36)
|
||||||
{
|
{
|
||||||
if(_authManager->isTokenAuthorized(token))
|
if(_authManager->isTokenAuthorized(token))
|
||||||
{
|
{
|
||||||
@ -1317,7 +1338,10 @@ void JsonAPI::handleAuthorizeCommand(const QJsonObject & message, const QString
|
|||||||
{
|
{
|
||||||
_authorized = true;
|
_authorized = true;
|
||||||
_userAuthorized = true;
|
_userAuthorized = true;
|
||||||
sendSuccessReply(command+"-"+subc, tan);
|
// Return the current valid Hyperion user token
|
||||||
|
QJsonObject obj;
|
||||||
|
obj["token"] = _authManager->getUserToken();
|
||||||
|
sendSuccessDataReply(QJsonDocument(obj),command+"-"+subc, tan);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sendErrorReply("No Authorization", command+"-"+subc, tan);
|
sendErrorReply("No Authorization", command+"-"+subc, tan);
|
||||||
|
@ -32,6 +32,9 @@ AuthManager::AuthManager(QObject* parent)
|
|||||||
{
|
{
|
||||||
_authTable->createUser("Hyperion","hyperion");
|
_authTable->createUser("Hyperion","hyperion");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update Hyperion user token on startup
|
||||||
|
_authTable->setUserToken("Hyperion");
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthManager::AuthDefinition AuthManager::createToken(const QString& comment)
|
const AuthManager::AuthDefinition AuthManager::createToken(const QString& comment)
|
||||||
@ -67,6 +70,11 @@ const QVector<AuthManager::AuthDefinition> AuthManager::getTokenList()
|
|||||||
return finalVec;
|
return finalVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString AuthManager::getUserToken(const QString & usr)
|
||||||
|
{
|
||||||
|
return QString(_authTable->getUserToken("Hyperion"));
|
||||||
|
}
|
||||||
|
|
||||||
bool AuthManager::isUserAuthorized(const QString& user, const QString& pw)
|
bool AuthManager::isUserAuthorized(const QString& user, const QString& pw)
|
||||||
{
|
{
|
||||||
return _authTable->isUserAuthorized(user, pw);
|
return _authTable->isUserAuthorized(user, pw);
|
||||||
@ -77,6 +85,11 @@ bool AuthManager::isTokenAuthorized(const QString& token)
|
|||||||
return _authTable->tokenExist(token);
|
return _authTable->tokenExist(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AuthManager::isUserTokenAuthorized(const QString& usr, const QString& token)
|
||||||
|
{
|
||||||
|
return _authTable->isUserTokenAuthorized(usr, token);
|
||||||
|
}
|
||||||
|
|
||||||
bool AuthManager::updateUserPassword(const QString& user, const QString& pw, const QString& newPw)
|
bool AuthManager::updateUserPassword(const QString& user, const QString& pw, const QString& newPw)
|
||||||
{
|
{
|
||||||
if(isUserAuthorized(user, pw))
|
if(isUserAuthorized(user, pw))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user