Add scope verification and tests
This commit is contained in:
parent
88aa22f3a2
commit
e638c8cab2
@ -96,7 +96,7 @@ UserManager::UserManager(const QString &dbName, QObject *parent):
|
|||||||
|
|
||||||
if (!initDB()) {
|
if (!initDB()) {
|
||||||
qCWarning(dcUserManager()) << "Error initializing user database. Trying to correct it.";
|
qCWarning(dcUserManager()) << "Error initializing user database. Trying to correct it.";
|
||||||
if (QFileInfo(m_db.databaseName()).exists()) {
|
if (QFileInfo::exists(m_db.databaseName())) {
|
||||||
rotate(m_db.databaseName());
|
rotate(m_db.databaseName());
|
||||||
if (!initDB()) {
|
if (!initDB()) {
|
||||||
qCWarning(dcUserManager()) << "Error fixing user database. Giving up. Users can't be stored.";
|
qCWarning(dcUserManager()) << "Error fixing user database. Giving up. Users can't be stored.";
|
||||||
@ -141,6 +141,7 @@ UserInfoList UserManager::users() const
|
|||||||
qCWarning(dcUserManager()) << "Unable to execute SQL query" << userQuery << m_db.lastError().databaseText() << m_db.lastError().driverText();
|
qCWarning(dcUserManager()) << "Unable to execute SQL query" << userQuery << m_db.lastError().databaseText() << m_db.lastError().driverText();
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (resultQuery.next()) {
|
while (resultQuery.next()) {
|
||||||
UserInfo info = UserInfo(resultQuery.value("username").toString());
|
UserInfo info = UserInfo(resultQuery.value("username").toString());
|
||||||
info.setEmail(resultQuery.value("email").toString());
|
info.setEmail(resultQuery.value("email").toString());
|
||||||
@ -164,6 +165,11 @@ UserManager::UserError UserManager::createUser(const QString &username, const QS
|
|||||||
return UserErrorBadPassword;
|
return UserErrorBadPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!validateScopes(scopes)) {
|
||||||
|
// The method warns about he specific validation
|
||||||
|
return UserErrorInconsistantScopes;
|
||||||
|
}
|
||||||
|
|
||||||
QSqlQuery checkForDuplicateUserQuery(m_db);
|
QSqlQuery checkForDuplicateUserQuery(m_db);
|
||||||
checkForDuplicateUserQuery.prepare("SELECT * FROM users WHERE lower(username) = ?;");
|
checkForDuplicateUserQuery.prepare("SELECT * FROM users WHERE lower(username) = ?;");
|
||||||
// Note: We're using toLower() on the username mainly for the reason that in old versions the username used to be an email address
|
// Note: We're using toLower() on the username mainly for the reason that in old versions the username used to be an email address
|
||||||
@ -223,9 +229,9 @@ UserManager::UserError UserManager::changePassword(const QString &username, cons
|
|||||||
QByteArray salt = QUuid::createUuid().toString().remove(QRegularExpression("[{}]")).toUtf8();
|
QByteArray salt = QUuid::createUuid().toString().remove(QRegularExpression("[{}]")).toUtf8();
|
||||||
QByteArray hashedPassword = QCryptographicHash::hash(QString(newPassword + salt).toUtf8(), QCryptographicHash::Sha512).toBase64();
|
QByteArray hashedPassword = QCryptographicHash::hash(QString(newPassword + salt).toUtf8(), QCryptographicHash::Sha512).toBase64();
|
||||||
QString updatePasswordQueryString = QString("UPDATE users SET password = \"%1\", salt = \"%2\" WHERE lower(username) = \"%3\";")
|
QString updatePasswordQueryString = QString("UPDATE users SET password = \"%1\", salt = \"%2\" WHERE lower(username) = \"%3\";")
|
||||||
.arg(QString::fromUtf8(hashedPassword))
|
.arg(QString::fromUtf8(hashedPassword))
|
||||||
.arg(QString::fromUtf8(salt))
|
.arg(QString::fromUtf8(salt))
|
||||||
.arg(username.toLower());
|
.arg(username.toLower());
|
||||||
|
|
||||||
QSqlQuery updatePasswordQuery(m_db);
|
QSqlQuery updatePasswordQuery(m_db);
|
||||||
if (!updatePasswordQuery.exec(updatePasswordQueryString)) {
|
if (!updatePasswordQuery.exec(updatePasswordQueryString)) {
|
||||||
@ -267,6 +273,12 @@ UserManager::UserError UserManager::removeUser(const QString &username)
|
|||||||
|
|
||||||
UserManager::UserError UserManager::setUserScopes(const QString &username, Types::PermissionScopes scopes)
|
UserManager::UserError UserManager::setUserScopes(const QString &username, Types::PermissionScopes scopes)
|
||||||
{
|
{
|
||||||
|
if (!validateScopes(scopes)) {
|
||||||
|
// The method warns about he specific validation
|
||||||
|
return UserErrorInconsistantScopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString scopesString = Types::scopesToStringList(scopes).join(',');
|
QString scopesString = Types::scopesToStringList(scopes).join(',');
|
||||||
QSqlQuery setScopesQuery(m_db);
|
QSqlQuery setScopesQuery(m_db);
|
||||||
setScopesQuery.prepare("UPDATE users SET scopes = ? WHERE username = ?");
|
setScopesQuery.prepare("UPDATE users SET scopes = ? WHERE username = ?");
|
||||||
@ -332,11 +344,11 @@ QByteArray UserManager::authenticate(const QString &username, const QString &pas
|
|||||||
|
|
||||||
QByteArray token = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha256).toBase64();
|
QByteArray token = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha256).toBase64();
|
||||||
QString storeTokenQueryString = QString("INSERT INTO tokens(id, username, token, creationdate, devicename) VALUES(\"%1\", \"%2\", \"%3\", \"%4\", \"%5\");")
|
QString storeTokenQueryString = QString("INSERT INTO tokens(id, username, token, creationdate, devicename) VALUES(\"%1\", \"%2\", \"%3\", \"%4\", \"%5\");")
|
||||||
.arg(QUuid::createUuid().toString())
|
.arg(QUuid::createUuid().toString())
|
||||||
.arg(username.toLower())
|
.arg(username.toLower())
|
||||||
.arg(QString::fromUtf8(token))
|
.arg(QString::fromUtf8(token))
|
||||||
.arg(NymeaCore::instance()->timeManager()->currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
.arg(NymeaCore::instance()->timeManager()->currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
||||||
.arg(deviceName);
|
.arg(deviceName);
|
||||||
|
|
||||||
QSqlQuery storeTokenQuery(m_db);
|
QSqlQuery storeTokenQuery(m_db);
|
||||||
if (!storeTokenQuery.exec(storeTokenQueryString)) {
|
if (!storeTokenQuery.exec(storeTokenQueryString)) {
|
||||||
@ -391,9 +403,8 @@ void UserManager::cancelPushButtonAuth(int transactionId)
|
|||||||
*/
|
*/
|
||||||
UserInfo UserManager::userInfo(const QString &username) const
|
UserInfo UserManager::userInfo(const QString &username) const
|
||||||
{
|
{
|
||||||
|
|
||||||
QString getUserQueryString = QString("SELECT * FROM users WHERE lower(username) = \"%1\";")
|
QString getUserQueryString = QString("SELECT * FROM users WHERE lower(username) = \"%1\";")
|
||||||
.arg(username);
|
.arg(username);
|
||||||
|
|
||||||
QSqlQuery getUserQuery(m_db);
|
QSqlQuery getUserQuery(m_db);
|
||||||
if (!getUserQuery.exec(getUserQueryString)) {
|
if (!getUserQuery.exec(getUserQueryString)) {
|
||||||
@ -444,7 +455,7 @@ TokenInfo UserManager::tokenInfo(const QByteArray &token) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString getTokenQueryString = QString("SELECT id, username, creationdate, deviceName FROM tokens WHERE token = \"%1\";")
|
QString getTokenQueryString = QString("SELECT id, username, creationdate, deviceName FROM tokens WHERE token = \"%1\";")
|
||||||
.arg(QString::fromUtf8(token));
|
.arg(QString::fromUtf8(token));
|
||||||
|
|
||||||
QSqlQuery getTokenQuery(m_db);
|
QSqlQuery getTokenQuery(m_db);
|
||||||
if (!getTokenQuery.exec(getTokenQueryString)) {
|
if (!getTokenQuery.exec(getTokenQueryString)) {
|
||||||
@ -467,7 +478,7 @@ TokenInfo UserManager::tokenInfo(const QUuid &tokenId) const
|
|||||||
{
|
{
|
||||||
|
|
||||||
QString getTokenQueryString = QString("SELECT id, username, creationdate, deviceName FROM tokens WHERE id = \"%1\";")
|
QString getTokenQueryString = QString("SELECT id, username, creationdate, deviceName FROM tokens WHERE id = \"%1\";")
|
||||||
.arg(tokenId.toString());
|
.arg(tokenId.toString());
|
||||||
|
|
||||||
QSqlQuery getTokenQuery(m_db);
|
QSqlQuery getTokenQuery(m_db);
|
||||||
if (!getTokenQuery.exec(getTokenQueryString)) {
|
if (!getTokenQuery.exec(getTokenQueryString)) {
|
||||||
@ -490,7 +501,7 @@ TokenInfo UserManager::tokenInfo(const QUuid &tokenId) const
|
|||||||
UserManager::UserError UserManager::removeToken(const QUuid &tokenId)
|
UserManager::UserError UserManager::removeToken(const QUuid &tokenId)
|
||||||
{
|
{
|
||||||
QString removeTokenQueryString = QString("DELETE FROM tokens WHERE id = \"%1\";")
|
QString removeTokenQueryString = QString("DELETE FROM tokens WHERE id = \"%1\";")
|
||||||
.arg(tokenId.toString());
|
.arg(tokenId.toString());
|
||||||
|
|
||||||
QSqlQuery removeTokenQuery(m_db);
|
QSqlQuery removeTokenQuery(m_db);
|
||||||
if (!removeTokenQuery.exec(removeTokenQueryString)) {
|
if (!removeTokenQuery.exec(removeTokenQueryString)) {
|
||||||
@ -519,7 +530,7 @@ bool UserManager::verifyToken(const QByteArray &token)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QString getTokenQueryString = QString("SELECT * FROM tokens WHERE token = \"%1\";")
|
QString getTokenQueryString = QString("SELECT * FROM tokens WHERE token = \"%1\";")
|
||||||
.arg(QString::fromUtf8(token));
|
.arg(QString::fromUtf8(token));
|
||||||
|
|
||||||
QSqlQuery getTokenQuery(m_db);
|
QSqlQuery getTokenQuery(m_db);
|
||||||
if (!getTokenQuery.exec(getTokenQueryString)) {
|
if (!getTokenQuery.exec(getTokenQueryString)) {
|
||||||
@ -738,6 +749,47 @@ bool UserManager::validateToken(const QByteArray &token) const
|
|||||||
return validator.match(token).hasMatch();
|
return validator.match(token).hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UserManager::validateScopes(Types::PermissionScopes scopes) const
|
||||||
|
{
|
||||||
|
if (scopes.testFlag(Types::PermissionScopeAdmin) || scopes == Types::PermissionScopeNone || scopes == Types::PermissionScopeControlThings)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (scopes.testFlag(Types::PermissionScopeConfigureThings)) {
|
||||||
|
if (!scopes.testFlag(Types::PermissionScopeControlThings) ||
|
||||||
|
!scopes.testFlag(Types::PermissionScopeAccessAllThings)) {
|
||||||
|
qCWarning(dcUserManager()) << "Invalid scopes combination. If a user can configure things he must have access to all things and must be able to control them.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: if access to all things, there are no restrictions
|
||||||
|
if (!scopes.testFlag(Types::PermissionScopeAccessAllThings)) {
|
||||||
|
if (scopes.testFlag(Types::PermissionScopeControlThings) ||
|
||||||
|
scopes.testFlag(Types::PermissionScopeConfigureRules)||
|
||||||
|
scopes.testFlag(Types::PermissionScopeExecuteRules)) {
|
||||||
|
qCWarning(dcUserManager()) << "Invalid scopes combination. If a user has not access to all things, he can not configure them or create/execute rules.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scopes.testFlag(Types::PermissionScopeExecuteRules)) {
|
||||||
|
if (!scopes.testFlag(Types::PermissionScopeAccessAllThings)) {
|
||||||
|
qCWarning(dcUserManager()) << "Invalid scopes combination. If a user can execute rules, he must have access to all things.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scopes.testFlag(Types::PermissionScopeConfigureRules)) {
|
||||||
|
if (!scopes.testFlag(Types::PermissionScopeAccessAllThings) ||
|
||||||
|
!scopes.testFlag(Types::PermissionScopeExecuteRules)) {
|
||||||
|
qCWarning(dcUserManager()) << "Invalid scopes combination. If a user can create rules, he must have access to all things and be able to execute them.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void UserManager::dumpDBError(const QString &message)
|
void UserManager::dumpDBError(const QString &message)
|
||||||
{
|
{
|
||||||
qCCritical(dcUserManager) << message << "Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
|
qCCritical(dcUserManager) << message << "Driver error:" << m_db.lastError().driverText() << "Database error:" << m_db.lastError().databaseText();
|
||||||
@ -770,11 +822,11 @@ void UserManager::onPushButtonPressed()
|
|||||||
|
|
||||||
QByteArray token = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha256).toBase64();
|
QByteArray token = QCryptographicHash::hash(QUuid::createUuid().toByteArray(), QCryptographicHash::Sha256).toBase64();
|
||||||
QString storeTokenQueryString = QString("INSERT INTO tokens(id, username, token, creationdate, devicename) VALUES(\"%1\", \"%2\", \"%3\", \"%4\", \"%5\");")
|
QString storeTokenQueryString = QString("INSERT INTO tokens(id, username, token, creationdate, devicename) VALUES(\"%1\", \"%2\", \"%3\", \"%4\", \"%5\");")
|
||||||
.arg(QUuid::createUuid().toString())
|
.arg(QUuid::createUuid().toString())
|
||||||
.arg("")
|
.arg("")
|
||||||
.arg(QString::fromUtf8(token))
|
.arg(QString::fromUtf8(token))
|
||||||
.arg(NymeaCore::instance()->timeManager()->currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
.arg(NymeaCore::instance()->timeManager()->currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
|
||||||
.arg(m_pushButtonTransaction.second);
|
.arg(m_pushButtonTransaction.second);
|
||||||
|
|
||||||
QSqlQuery storeTokenQuery(m_db);
|
QSqlQuery storeTokenQuery(m_db);
|
||||||
if (!storeTokenQuery.exec(storeTokenQueryString) || m_db.lastError().type() != QSqlError::NoError) {
|
if (!storeTokenQuery.exec(storeTokenQueryString) || m_db.lastError().type() != QSqlError::NoError) {
|
||||||
|
|||||||
@ -46,7 +46,8 @@ public:
|
|||||||
UserErrorDuplicateUserId,
|
UserErrorDuplicateUserId,
|
||||||
UserErrorBadPassword,
|
UserErrorBadPassword,
|
||||||
UserErrorTokenNotFound,
|
UserErrorTokenNotFound,
|
||||||
UserErrorPermissionDenied
|
UserErrorPermissionDenied,
|
||||||
|
UserErrorInconsistantScopes
|
||||||
};
|
};
|
||||||
Q_ENUM(UserError)
|
Q_ENUM(UserError)
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ private:
|
|||||||
bool validateUsername(const QString &username) const;
|
bool validateUsername(const QString &username) const;
|
||||||
bool validatePassword(const QString &password) const;
|
bool validatePassword(const QString &password) const;
|
||||||
bool validateToken(const QByteArray &token) const;
|
bool validateToken(const QByteArray &token) const;
|
||||||
|
bool validateScopes(Types::PermissionScopes scopes) const;
|
||||||
|
|
||||||
void dumpDBError(const QString &message);
|
void dumpDBError(const QString &message);
|
||||||
|
|
||||||
|
|||||||
@ -102,6 +102,9 @@ private slots:
|
|||||||
|
|
||||||
void getUserInfo();
|
void getUserInfo();
|
||||||
|
|
||||||
|
void testScopeConsitancy_data();
|
||||||
|
void testScopeConsitancy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// m_apiToken is in testBase
|
// m_apiToken is in testBase
|
||||||
QUuid m_tokenId;
|
QUuid m_tokenId;
|
||||||
@ -116,11 +119,11 @@ void TestUsermanager::initTestCase()
|
|||||||
{
|
{
|
||||||
NymeaDBusService::setBusType(QDBusConnection::SessionBus);
|
NymeaDBusService::setBusType(QDBusConnection::SessionBus);
|
||||||
NymeaTestBase::initTestCase("*.debug=false\n"
|
NymeaTestBase::initTestCase("*.debug=false\n"
|
||||||
"Application.debug=true\n"
|
"Application.debug=true\n"
|
||||||
"Tests.debug=true\n"
|
"Tests.debug=true\n"
|
||||||
"UserManager.debug=true\n"
|
"UserManager.debug=true\n"
|
||||||
"PushButtonAgent.debug=true\n"
|
"PushButtonAgent.debug=true\n"
|
||||||
"MockDevice.debug=true");
|
"MockDevice.debug=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestUsermanager::init()
|
void TestUsermanager::init()
|
||||||
@ -357,7 +360,7 @@ void TestUsermanager::authenticatePushButtonAuthConnectionDrop()
|
|||||||
|
|
||||||
// Create a new clientId for alice and connect it to the server
|
// Create a new clientId for alice and connect it to the server
|
||||||
QUuid aliceId = QUuid::createUuid();
|
QUuid aliceId = QUuid::createUuid();
|
||||||
m_mockTcpServer->clientConnected(aliceId);
|
emit m_mockTcpServer->clientConnected(aliceId);
|
||||||
m_mockTcpServer->injectData(aliceId, "{\"id\": 0, \"method\": \"JSONRPC.Hello\"}");
|
m_mockTcpServer->injectData(aliceId, "{\"id\": 0, \"method\": \"JSONRPC.Hello\"}");
|
||||||
if (clientSpy.count() == 0) clientSpy.wait();
|
if (clientSpy.count() == 0) clientSpy.wait();
|
||||||
|
|
||||||
@ -368,12 +371,12 @@ void TestUsermanager::authenticatePushButtonAuthConnectionDrop()
|
|||||||
QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true);
|
QCOMPARE(response.toMap().value("params").toMap().value("success").toBool(), true);
|
||||||
|
|
||||||
// Disconnect alice
|
// Disconnect alice
|
||||||
m_mockTcpServer->clientDisconnected(aliceId);
|
emit m_mockTcpServer->clientDisconnected(aliceId);
|
||||||
|
|
||||||
// Now try with bob
|
// Now try with bob
|
||||||
// Create a new clientId for bob and connect it to the server
|
// Create a new clientId for bob and connect it to the server
|
||||||
QUuid bobId = QUuid::createUuid();
|
QUuid bobId = QUuid::createUuid();
|
||||||
m_mockTcpServer->clientConnected(bobId);
|
emit m_mockTcpServer->clientConnected(bobId);
|
||||||
clientSpy.clear();
|
clientSpy.clear();
|
||||||
m_mockTcpServer->injectData(bobId, "{\"id\": 0, \"method\": \"JSONRPC.Hello\"}");
|
m_mockTcpServer->injectData(bobId, "{\"id\": 0, \"method\": \"JSONRPC.Hello\"}");
|
||||||
if (clientSpy.count() == 0) clientSpy.wait();
|
if (clientSpy.count() == 0) clientSpy.wait();
|
||||||
@ -495,9 +498,8 @@ void TestUsermanager::authenticateAfterPasswordChangeFail()
|
|||||||
QVERIFY2(disconnectedSpy.count() == 1, "Connection should have dropped");
|
QVERIFY2(disconnectedSpy.count() == 1, "Connection should have dropped");
|
||||||
|
|
||||||
QTest::qWait(3200);
|
QTest::qWait(3200);
|
||||||
m_mockTcpServer->clientConnected(m_clientId);
|
emit m_mockTcpServer->clientConnected(m_clientId);
|
||||||
injectAndWait("JSONRPC.Hello");
|
injectAndWait("JSONRPC.Hello");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestUsermanager::getUserInfo()
|
void TestUsermanager::getUserInfo()
|
||||||
@ -505,14 +507,9 @@ void TestUsermanager::getUserInfo()
|
|||||||
authenticate();
|
authenticate();
|
||||||
|
|
||||||
QVariant response = injectAndWait("Users.GetUserInfo");
|
QVariant response = injectAndWait("Users.GetUserInfo");
|
||||||
|
|
||||||
QCOMPARE(response.toMap().value("status").toString(), QString("success"));
|
QCOMPARE(response.toMap().value("status").toString(), QString("success"));
|
||||||
|
|
||||||
QVariantMap userInfoMap = response.toMap().value("params").toMap().value("userInfo").toMap();
|
QVariantMap userInfoMap = response.toMap().value("params").toMap().value("userInfo").toMap();
|
||||||
|
|
||||||
|
|
||||||
QCOMPARE(userInfoMap.value("username").toString(), QString("valid@user.test"));
|
QCOMPARE(userInfoMap.value("username").toString(), QString("valid@user.test"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestUsermanager::unauthenticatedCallAfterTokenRemove()
|
void TestUsermanager::unauthenticatedCallAfterTokenRemove()
|
||||||
@ -530,9 +527,117 @@ void TestUsermanager::unauthenticatedCallAfterTokenRemove()
|
|||||||
QVERIFY2(spy.count() == 1, "Connection should be terminated!");
|
QVERIFY2(spy.count() == 1, "Connection should be terminated!");
|
||||||
|
|
||||||
QTest::qWait(3200);
|
QTest::qWait(3200);
|
||||||
m_mockTcpServer->clientConnected(m_clientId);
|
emit m_mockTcpServer->clientConnected(m_clientId);
|
||||||
injectAndWait("JSONRPC.Hello");
|
injectAndWait("JSONRPC.Hello");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestUsermanager::testScopeConsitancy_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QList<Types::PermissionScope>>("scopes");
|
||||||
|
QTest::addColumn<QString>("error");
|
||||||
|
|
||||||
|
QTest::newRow("valid: admin")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeAdmin)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
QTest::newRow("valid: none")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeNone)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
QTest::newRow("valid: only control, not all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeControlThings
|
||||||
|
<< Types::PermissionScopeAccessAllThings)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
QTest::newRow("valid: only control, not all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeControlThings
|
||||||
|
<< Types::PermissionScopeConfigureThings
|
||||||
|
<< Types::PermissionScopeAccessAllThings)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
QTest::newRow("valid: only control, all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeControlThings
|
||||||
|
<< Types::PermissionScopeAccessAllThings)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
QTest::newRow("valid: control things/rules, all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeControlThings
|
||||||
|
<< Types::PermissionScopeAccessAllThings
|
||||||
|
<< Types::PermissionScopeExecuteRules)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
QTest::newRow("valid: only execute rules")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeAccessAllThings
|
||||||
|
<< Types::PermissionScopeExecuteRules)
|
||||||
|
<< "UserErrorNoError";
|
||||||
|
|
||||||
|
|
||||||
|
QTest::newRow("invalid: missing control and all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeConfigureThings)
|
||||||
|
<< "UserErrorInconsistantScopes";
|
||||||
|
|
||||||
|
QTest::newRow("invalid: control/configure things. not all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeControlThings
|
||||||
|
<< Types::PermissionScopeConfigureThings)
|
||||||
|
<< "UserErrorInconsistantScopes";
|
||||||
|
|
||||||
|
QTest::newRow("invalid: only execute rules, not all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeExecuteRules)
|
||||||
|
<< "UserErrorInconsistantScopes";
|
||||||
|
|
||||||
|
QTest::newRow("invalid: only configure rules")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeConfigureRules)
|
||||||
|
<< "UserErrorInconsistantScopes";
|
||||||
|
|
||||||
|
QTest::newRow("invalid: configure and execute rules, not all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeExecuteRules
|
||||||
|
<< Types::PermissionScopeConfigureRules)
|
||||||
|
<< "UserErrorInconsistantScopes";
|
||||||
|
|
||||||
|
QTest::newRow("invalid: control things/rules, not all things")
|
||||||
|
<< (QList<Types::PermissionScope>()
|
||||||
|
<< Types::PermissionScopeControlThings
|
||||||
|
<< Types::PermissionScopeExecuteRules)
|
||||||
|
<< "UserErrorInconsistantScopes";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestUsermanager::testScopeConsitancy()
|
||||||
|
{
|
||||||
|
QFETCH(QList<Types::PermissionScope>, scopes);
|
||||||
|
QFETCH(QString, error);
|
||||||
|
|
||||||
|
authenticate();
|
||||||
|
|
||||||
|
QVariant response = injectAndWait("Users.GetUserInfo");
|
||||||
|
QCOMPARE(response.toMap().value("status").toString(), QString("success"));
|
||||||
|
QVariantMap userInfoMap = response.toMap().value("params").toMap().value("userInfo").toMap();
|
||||||
|
QCOMPARE(userInfoMap.value("username").toString(), QString("valid@user.test"));
|
||||||
|
|
||||||
|
QMetaEnum metaEnum = QMetaEnum::fromType<Types::PermissionScope>();
|
||||||
|
QStringList scopesList;
|
||||||
|
foreach (Types::PermissionScope scope, scopes)
|
||||||
|
scopesList.append(metaEnum.valueToKey(scope));
|
||||||
|
|
||||||
|
// Now try to edit with the given scopes
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("username", userInfoMap.value("username").toString());
|
||||||
|
params.insert("scopes", scopesList);
|
||||||
|
response = injectAndWait("Users.SetUserScopes", params);
|
||||||
|
QCOMPARE(response.toMap().value("status").toString(), QString("success"));
|
||||||
|
QCOMPARE(response.toMap().value("params").toMap().value("error").toString(), error);
|
||||||
|
}
|
||||||
|
|
||||||
#include "testusermanager.moc"
|
#include "testusermanager.moc"
|
||||||
QTEST_MAIN(TestUsermanager)
|
QTEST_MAIN(TestUsermanager)
|
||||||
|
|||||||
Reference in New Issue
Block a user