diff -Nru signon-8.57+14.10.20141006/debian/changelog signon-8.57+15.04.20150205~rtm/debian/changelog --- signon-8.57+14.10.20141006/debian/changelog 2015-02-05 14:48:57.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/debian/changelog 2015-02-05 14:48:57.000000000 +0000 @@ -1,3 +1,21 @@ +signon (8.57+15.04.20150205~rtm-0ubuntu1) 14.09; urgency=medium + + [ Alberto Mardegan ] + * Enable P2P D-Bus connections (LP: #1415492) + * Add missing build dependency on libdbus-1-dev + + -- Ubuntu daily release Thu, 05 Feb 2015 14:39:49 +0000 + +signon (8.57+15.04.20141127.1-0ubuntu1) vivid; urgency=low + + [ Ubuntu daily release ] + * New rebuild forced + + [ Alberto Mardegan ] + * Merge from upstream + + -- Ubuntu daily release Thu, 27 Nov 2014 10:53:16 +0000 + signon (8.57+14.10.20141006-0ubuntu1) utopic; urgency=low [ Alberto Mardegan ] diff -Nru signon-8.57+14.10.20141006/debian/control signon-8.57+15.04.20150205~rtm/debian/control --- signon-8.57+14.10.20141006/debian/control 2015-02-05 14:48:57.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/debian/control 2015-02-05 14:48:57.000000000 +0000 @@ -6,6 +6,7 @@ pkg-config, doxygen, graphviz, + libdbus-1-dev, libproxy-dev, libqt4-dev (>= 4.6), libqt4-sql-sqlite, diff -Nru signon-8.57+14.10.20141006/debian/rules signon-8.57+15.04.20150205~rtm/debian/rules --- signon-8.57+14.10.20141006/debian/rules 2015-02-05 14:48:57.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/debian/rules 2015-02-05 14:48:57.000000000 +0000 @@ -19,6 +19,7 @@ QT_SELECT=qt5 \ dh_auto_configure -Bbuild/qt5 -- LIBDIR=/usr/lib/$(DEB_HOST_MULTIARCH) \ BUILD_DIR=build/qt5 \ + CONFIG+=enable-p2p \ "QMAKE_CXXFLAGS=$(CFLAGS)" ../../signon.pro override_dh_auto_build: diff -Nru signon-8.57+14.10.20141006/lib/plugins/SignOn/uisessiondata_priv.h signon-8.57+15.04.20150205~rtm/lib/plugins/SignOn/uisessiondata_priv.h --- signon-8.57+14.10.20141006/lib/plugins/SignOn/uisessiondata_priv.h 2014-10-06 07:56:59.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/lib/plugins/SignOn/uisessiondata_priv.h 2015-02-05 14:39:41.000000000 +0000 @@ -68,6 +68,8 @@ /* Process ID of the client application */ #define SSOUI_KEY_PID QLatin1String("Pid") +/* Application ID (security context) of the client application */ +#define SSOUI_KEY_APP_ID QLatin1String("AppId") #define SSOUI_KEY_SLOT_ACCEPT "accept" #define SSOUI_KEY_SLOT_REJECT "reject" diff -Nru signon-8.57+14.10.20141006/src/signond/accesscontrolmanagerhelper.cpp signon-8.57+15.04.20150205~rtm/src/signond/accesscontrolmanagerhelper.cpp --- signon-8.57+14.10.20141006/src/signond/accesscontrolmanagerhelper.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/accesscontrolmanagerhelper.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -89,7 +89,7 @@ IdentityOwnership ownership = isPeerOwnerOfIdentity(peerConnection, peerMessage, identityId); - if (ownership == ApplicationIsOwner || ownership == IdentityDoesNotHaveOwner) + if (ownership == ApplicationIsOwner) return true; if (acl.isEmpty()) diff -Nru signon-8.57+14.10.20141006/src/signond/default-secrets-storage.cpp signon-8.57+15.04.20150205~rtm/src/signond/default-secrets-storage.cpp --- signon-8.57+14.10.20141006/src/signond/default-secrets-storage.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/default-secrets-storage.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -272,7 +272,8 @@ } DefaultSecretsStorage::DefaultSecretsStorage(QObject *parent): - AbstractSecretsStorage(parent) + AbstractSecretsStorage(parent), + m_secretsDB(0) { } @@ -288,7 +289,8 @@ close(); } - QString name = configuration.value(QLatin1String("name")).toString(); + QString name; // force deep copy / detach + name.append(configuration.value(QLatin1String("name")).toString()); m_secretsDB = new SecretsDB(name); if (!m_secretsDB->init()) { @@ -298,6 +300,8 @@ return false; } + m_secretsDBConnectionName.clear(); + m_secretsDBConnectionName.append(m_secretsDB->connectionName()); setIsOpen(true); return true; } @@ -305,9 +309,8 @@ bool DefaultSecretsStorage::close() { if (m_secretsDB != 0) { - QString connectionName = m_secretsDB->connectionName(); delete m_secretsDB; - QSqlDatabase::removeDatabase(connectionName); + QSqlDatabase::removeDatabase(m_secretsDBConnectionName); m_secretsDB = 0; } return AbstractSecretsStorage::close(); diff -Nru signon-8.57+14.10.20141006/src/signond/default-secrets-storage.h signon-8.57+15.04.20150205~rtm/src/signond/default-secrets-storage.h --- signon-8.57+14.10.20141006/src/signond/default-secrets-storage.h 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/default-secrets-storage.h 2015-02-05 14:39:41.000000000 +0000 @@ -95,6 +95,7 @@ private: SecretsDB *m_secretsDB; + QString m_secretsDBConnectionName; }; } //namespace diff -Nru signon-8.57+14.10.20141006/src/signond/pluginproxy.cpp signon-8.57+15.04.20150205~rtm/src/signond/pluginproxy.cpp --- signon-8.57+14.10.20141006/src/signond/pluginproxy.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/pluginproxy.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -436,6 +436,10 @@ } connect(m_process, SIGNAL(readyRead()), this, SLOT(onReadStandardOutput())); + if (m_process->bytesAvailable()) { + TRACE() << "plugin has more to read after handling a response"; + onReadStandardOutput(); + } } void PluginProxy::onReadStandardError() diff -Nru signon-8.57+14.10.20141006/src/signond/signondaemonadaptor.cpp signon-8.57+15.04.20150205~rtm/src/signond/signondaemonadaptor.cpp --- signon-8.57+14.10.20141006/src/signond/signondaemonadaptor.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/signondaemonadaptor.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -172,7 +172,7 @@ /* Access Control */ if (id != SIGNOND_NEW_IDENTITY) { - if (!acm->isPeerAllowedToUseAuthSession(conn, msg, id)) { + if (!acm->isPeerAllowedToUseIdentity(conn, msg, id)) { SignOn::AccessReply *reply = acm->requestAccessToIdentity(conn, msg, id); /* If the request is accepted, we'll need the method name ("type") diff -Nru signon-8.57+14.10.20141006/src/signond/signondaemon.cpp signon-8.57+15.04.20150205~rtm/src/signond/signondaemon.cpp --- signon-8.57+14.10.20141006/src/signond/signondaemon.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/signondaemon.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -271,6 +271,8 @@ exit(0); } + delete m_dbusServer; + SignonAuthSession::stopAllAuthSessions(); m_storedIdentities.clear(); diff -Nru signon-8.57+14.10.20141006/src/signond/signonidentity.cpp signon-8.57+15.04.20150205~rtm/src/signond/signonidentity.cpp --- signon-8.57+14.10.20141006/src/signond/signonidentity.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/signonidentity.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -471,41 +471,19 @@ MethodMap methods = container.isValid() ? qdbus_cast(container.value()) : MethodMap(); - //Add creator to owner list if it has AID - QStringList ownerList = - info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList(); - if (!appId.isNull()) - ownerList.append(appId); - if (m_pInfo == 0) { m_pInfo = new SignonIdentityInfo(info); m_pInfo->setMethods(methods); - m_pInfo->setOwnerList(ownerList); - } else { - if (info.contains(SIGNOND_IDENTITY_INFO_SECRET)) { - QString secret = info.value(SIGNOND_IDENTITY_INFO_SECRET).toString(); - m_pInfo->setPassword(secret); + //Add creator to owner list if it has AID + QStringList ownerList = + info.value(SIGNOND_IDENTITY_INFO_OWNER).toStringList(); + if (!appId.isNull()) { + ownerList.append(appId); } - bool storeSecret = - info.value(SIGNOND_IDENTITY_INFO_STORESECRET).toBool(); - QString userName = - info.value(SIGNOND_IDENTITY_INFO_USERNAME).toString(); - QString caption = - info.value(SIGNOND_IDENTITY_INFO_CAPTION).toString(); - QStringList realms = - info.value(SIGNOND_IDENTITY_INFO_REALMS).toStringList(); - QStringList accessControlList = - info.value(SIGNOND_IDENTITY_INFO_ACL).toStringList(); - int type = info.value(SIGNOND_IDENTITY_INFO_TYPE).toInt(); - - m_pInfo->setStorePassword(storeSecret); - m_pInfo->setUserName(userName); - m_pInfo->setCaption(caption); - m_pInfo->setMethods(methods); - m_pInfo->setRealms(realms); - m_pInfo->setAccessControlList(accessControlList); m_pInfo->setOwnerList(ownerList); - m_pInfo->setType(type); + } else { + SignonIdentityInfo newInfo(info); + m_pInfo->update(newInfo); } m_id = storeCredentials(*m_pInfo); diff -Nru signon-8.57+14.10.20141006/src/signond/signonidentityinfo.cpp signon-8.57+15.04.20150205~rtm/src/signond/signonidentityinfo.cpp --- signon-8.57+14.10.20141006/src/signond/signonidentityinfo.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/signonidentityinfo.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -60,6 +60,18 @@ return *this; } +void SignonIdentityInfo::update(const SignonIdentityInfo &info) +{ + QMapIterator it(info); + while (it.hasNext()) { + it.next(); + // We don't allow updating the ID + if (it.key() == SIGNOND_IDENTITY_INFO_ID) continue; + + insert(it.key(), it.value()); + } +} + bool SignonIdentityInfo::checkMethodAndMechanism(const QString &method, const QString &mechanism, QString &allowedMechanism) diff -Nru signon-8.57+14.10.20141006/src/signond/signonidentityinfo.h signon-8.57+15.04.20150205~rtm/src/signond/signonidentityinfo.h --- signon-8.57+14.10.20141006/src/signond/signonidentityinfo.h 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/signonidentityinfo.h 2015-02-05 14:39:41.000000000 +0000 @@ -46,6 +46,8 @@ const QVariantMap toMap() const; + void update(const SignonIdentityInfo &info); + void setNew() { setId(SIGNOND_NEW_IDENTITY); } bool isNew() const { return id() == SIGNOND_NEW_IDENTITY; } void setId(quint32 id) { insert(SIGNOND_IDENTITY_INFO_ID, id); } diff -Nru signon-8.57+14.10.20141006/src/signond/signonsessioncore.cpp signon-8.57+15.04.20150205~rtm/src/signond/signonsessioncore.cpp --- signon-8.57+14.10.20141006/src/signond/signonsessioncore.cpp 2014-10-06 07:56:59.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/src/signond/signonsessioncore.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -705,8 +705,12 @@ request.m_params[SSOUI_KEY_CLIENT_DATA] = m_clientData; request.m_params[SSOUI_KEY_METHOD] = m_method; request.m_params[SSOUI_KEY_MECHANISM] = request.m_mechanism; - request.m_params[SSOUI_KEY_PID] = - AccessControlManagerHelper::instance()->pidOfPeer(request.m_conn, + /* Pass some data about the requesting client */ + AccessControlManagerHelper *acm = + AccessControlManagerHelper::instance(); + request.m_params[SSOUI_KEY_PID] = acm->pidOfPeer(request.m_conn, + request.m_msg); + request.m_params[SSOUI_KEY_APP_ID] = acm->appIdOfPeer(request.m_conn, request.m_msg); CredentialsAccessManager *camManager = diff -Nru signon-8.57+14.10.20141006/tests/libsignon-qt-tests/ssotestclient.cpp signon-8.57+15.04.20150205~rtm/tests/libsignon-qt-tests/ssotestclient.cpp --- signon-8.57+14.10.20141006/tests/libsignon-qt-tests/ssotestclient.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/libsignon-qt-tests/ssotestclient.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -257,16 +257,137 @@ TEST_DONE } +void SsoTestClient::storeCredentials_data() +{ + QTest::addColumn("addMethods"); + + QTest::newRow("with methods") << true; + QTest::newRow("without methods") << false; +} + void SsoTestClient::storeCredentials() { TEST_START - if (!testAddingNewCredentials()) { - QFAIL("Adding new credentials test failed."); + QFETCH(bool, addMethods); + + m_identityResult.reset(); + + QMap methods; + if (addMethods) { + methods.insert("dummy", QStringList() << "mech1" << "mech2" << "mech3"); + methods.insert("dummy1", QStringList() << "mech11" << "mech12" << "mech13"); } + IdentityInfo info("TEST_CAPTION", "TEST_USERNAME", methods); + info.setSecret("TEST_SECRET"); + info.setRealms(QStringList() << "TEST_REALM1" << "TEST_REALM2"); + info.setAccessControlList(QStringList() << "*"); - if (!testUpdatingCredentials()) { - QFAIL("Updating existing credentials test failed."); + Identity *identity = Identity::newIdentity(info, this); + + QEventLoop loop; + + connect(identity, SIGNAL(error(const SignOn::Error &)), + &m_identityResult, SLOT(error(const SignOn::Error &))); + + connect(identity, SIGNAL(credentialsStored(const quint32)), + &m_identityResult, SLOT(credentialsStored(const quint32))); + connect(&m_identityResult, SIGNAL(testCompleted()), &loop, SLOT(quit())); + + identity->storeCredentials(); + + QTimer::singleShot(test_timeout, &loop, SLOT(quit())); + loop.exec(); + + if (m_identityResult.m_responseReceived == + TestIdentityResult::InexistentResp) { + QFAIL("A response was not received."); + } + + if (m_identityResult.m_responseReceived == TestIdentityResult::NormalResp) { + QCOMPARE(m_identityResult.m_id, identity->id()); + + Identity *existingIdentity = + Identity::existingIdentity(m_identityResult.m_id, this); + QVERIFY2(existingIdentity != NULL, + "Could not create existing identity. '0' ID provided?"); + connect(existingIdentity, SIGNAL(info(const SignOn::IdentityInfo &)), + &m_identityResult, SLOT(info(const SignOn::IdentityInfo &))); + + existingIdentity->queryInfo(); + + QTimer::singleShot(test_timeout, &loop, SLOT(quit())); + loop.exec(); + delete existingIdentity; + + if (!TestIdentityResult::compareIdentityInfos(m_identityResult.m_idInfo, + info)) { + QFAIL("Compared identity infos are not the same."); + } + } else { + QString codeStr = errCodeAsStr(m_identityResult.m_error); + qDebug() << "Error reply: " << m_serviceResult.m_errMsg + << ".\nError code: " << codeStr; + QFAIL("Error received"); + } + + // Test update credentials functionality + + Identity *existingIdentity = Identity::existingIdentity(m_identityResult.m_id, this); + QVERIFY2(existingIdentity != NULL, + "Could not create existing identity. '0' ID provided?"); + + methods.clear(); + if (addMethods) { + methods.insert("dummy1", QStringList() << "mech11" << "mech12" << "mech13"); + methods.insert("dummy2", QStringList() << "mech1_updated" << "mech2" << "mech1_updated2"); + methods.insert("dummy3", QStringList() << "mech1_updated" << "mech2" << "mech1_updated2"); + } + + IdentityInfo updateInfo("TEST_CAPTION", "TEST_USERNAME_UPDATED", methods); + updateInfo.setSecret("TEST_SECRET_YES", false); + + do + { + QEventLoop loop; + + connect(existingIdentity, SIGNAL(error(const SignOn::Error &)), + &m_identityResult, SLOT(error(const SignOn::Error &))); + + connect(existingIdentity, SIGNAL(credentialsStored(const quint32)), + &m_identityResult, SLOT(credentialsStored(const quint32))); + connect(&m_identityResult, SIGNAL(testCompleted()), &loop, SLOT(quit())); + + existingIdentity->storeCredentials(updateInfo); + qDebug(); + QTimer::singleShot(test_timeout, &loop, SLOT(quit())); + loop.exec(); + } while(0); + + if (m_identityResult.m_responseReceived == + TestIdentityResult::InexistentResp) { + QFAIL("A response was not received."); + } + + if (m_identityResult.m_responseReceived == TestIdentityResult::NormalResp) { + QEventLoop loop; + connect(&m_identityResult, SIGNAL(testCompleted()), &loop, SLOT(quit())); + connect(existingIdentity, SIGNAL(info(const SignOn::IdentityInfo &)), + &m_identityResult, SLOT(info(const SignOn::IdentityInfo &))); + + existingIdentity->queryInfo(); + QTimer::singleShot(test_timeout, &loop, SLOT(quit())); + loop.exec(); + + qDebug() << "ID:" << existingIdentity->id(); + QCOMPARE(m_identityResult.m_idInfo.caption(), updateInfo.caption()); + QCOMPARE(m_identityResult.m_idInfo.methods(), updateInfo.methods()); + QCOMPARE(m_identityResult.m_idInfo.userName(), updateInfo.userName()); + } else { + QString codeStr = errCodeAsStr(m_identityResult.m_error); + qDebug() << "Error reply: " << m_serviceResult.m_errMsg + << ".\nError code: " << codeStr; + QFAIL("Error received"); } TEST_DONE @@ -566,21 +687,6 @@ TEST_DONE } -void SsoTestClient::storeCredentialsWithoutAuthMethodsTest() -{ - TEST_START - - if (!testAddingNewCredentials(false)) { - QFAIL("Adding new credentials test failed."); - } - - if (!testUpdatingCredentials()) { - QFAIL("Updating existing credentials test failed."); - } - - TEST_DONE -} - void SsoTestClient::queryInfo() { TEST_START @@ -1448,146 +1554,6 @@ TEST_DONE } -bool SsoTestClient::testAddingNewCredentials(bool addMethods) -{ - m_identityResult.reset(); - - QMap methods; - if (addMethods) { - methods.insert("dummy", QStringList() << "mech1" << "mech2" << "mech3"); - methods.insert("dummy1", QStringList() << "mech11" << "mech12" << "mech13"); - } - IdentityInfo info("TEST_CAPTION", "TEST_USERNAME", methods); - info.setSecret("TEST_SECRET"); - info.setRealms(QStringList() << "TEST_REALM1" << "TEST_REALM2"); - - Identity *identity = Identity::newIdentity(info, this); - - QEventLoop loop; - - connect(identity, SIGNAL(error(const SignOn::Error &)), - &m_identityResult, SLOT(error(const SignOn::Error &))); - - connect(identity, SIGNAL(credentialsStored(const quint32)), - &m_identityResult, SLOT(credentialsStored(const quint32))); - connect(&m_identityResult, SIGNAL(testCompleted()), &loop, SLOT(quit())); - - identity->storeCredentials(); - - QTimer::singleShot(test_timeout, &loop, SLOT(quit())); - loop.exec(); - - if (m_identityResult.m_responseReceived == - TestIdentityResult::InexistentResp) { - qDebug() << "A response was not received."; - return false; - } - - if (m_identityResult.m_responseReceived == TestIdentityResult::NormalResp) { - if (m_identityResult.m_id != identity->id()) { - qDebug() << "Queried identity id does not match with stored data."; - return false; - } - - Identity *existingIdentity = - Identity::existingIdentity(m_identityResult.m_id, this); - if (existingIdentity == NULL) { - qDebug() << "Could not create existing identity. '0' ID provided?"; - return false; - } - connect(existingIdentity, SIGNAL(info(const SignOn::IdentityInfo &)), - &m_identityResult, SLOT(info(const SignOn::IdentityInfo &))); - - existingIdentity->queryInfo(); - - QTimer::singleShot(test_timeout, &loop, SLOT(quit())); - loop.exec(); - delete existingIdentity; - - if (!TestIdentityResult::compareIdentityInfos(m_identityResult.m_idInfo, - info)) { - qDebug() << "Compared identity infos are not the same."; - return false; - } - } else { - QString codeStr = errCodeAsStr(m_identityResult.m_error); - qDebug() << "Error reply: " << m_serviceResult.m_errMsg - << ".\nError code: " << codeStr; - return false; - } - return true; -} - -bool SsoTestClient::testUpdatingCredentials(bool addMethods) -{ - // Test update credentials functionality - - Identity *existingIdentity = Identity::existingIdentity(m_identityResult.m_id, this); - if (existingIdentity == NULL) { - qDebug() << "Could not create existing identity. '0' ID provided?"; - return false; - } - - QMap methods; - if (addMethods) { - methods.insert("dummy1", QStringList() << "mech11" << "mech12" << "mech13"); - methods.insert("dummy2", QStringList() << "mech1_updated" << "mech2" << "mech1_updated2"); - methods.insert("dummy3", QStringList() << "mech1_updated" << "mech2" << "mech1_updated2"); - } - - IdentityInfo updateInfo("TEST_CAPTION", "TEST_USERNAME_UPDATED", methods); - updateInfo.setSecret("TEST_SECRET_YES", false); - - do - { - QEventLoop loop; - - connect(existingIdentity, SIGNAL(error(const SignOn::Error &)), - &m_identityResult, SLOT(error(const SignOn::Error &))); - - connect(existingIdentity, SIGNAL(credentialsStored(const quint32)), - &m_identityResult, SLOT(credentialsStored(const quint32))); - connect(&m_identityResult, SIGNAL(testCompleted()), &loop, SLOT(quit())); - - existingIdentity->storeCredentials(updateInfo); - qDebug(); - QTimer::singleShot(test_timeout, &loop, SLOT(quit())); - loop.exec(); - } while(0); - - qDebug(); - if (m_identityResult.m_responseReceived == - TestIdentityResult::InexistentResp) { - qDebug() << "A response was not received."; - return false; - } - - if (m_identityResult.m_responseReceived == TestIdentityResult::NormalResp) { - QEventLoop loop; - connect(&m_identityResult, SIGNAL(testCompleted()), &loop, SLOT(quit())); - connect(existingIdentity, SIGNAL(info(const SignOn::IdentityInfo &)), - &m_identityResult, SLOT(info(const SignOn::IdentityInfo &))); - - existingIdentity->queryInfo(); - QTimer::singleShot(test_timeout, &loop, SLOT(quit())); - loop.exec(); - - qDebug() << "ID:" << existingIdentity->id(); - if (!TestIdentityResult::compareIdentityInfos(m_identityResult.m_idInfo, - updateInfo)) { - qDebug() << "Compared identity infos are not the same."; - return false; - } - } else { - QString codeStr = errCodeAsStr(m_identityResult.m_error); - qDebug() << "Error reply: " << m_serviceResult.m_errMsg - << ".\nError code: " << codeStr; - - return false; - } - return true; -} - void SsoTestClient::emptyPasswordRegression() { TEST_START diff -Nru signon-8.57+14.10.20141006/tests/libsignon-qt-tests/ssotestclient.h signon-8.57+15.04.20150205~rtm/tests/libsignon-qt-tests/ssotestclient.h --- signon-8.57+14.10.20141006/tests/libsignon-qt-tests/ssotestclient.h 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/libsignon-qt-tests/ssotestclient.h 2015-02-05 14:39:41.000000000 +0000 @@ -56,6 +56,7 @@ * Identity tests */ void queryAvailableMetods(); + void storeCredentials_data(); void storeCredentials(); void requestCredentialsUpdate(); void queryInfo(); @@ -65,7 +66,6 @@ void verifySecret(); void signOut(); void remove(); - void storeCredentialsWithoutAuthMethodsTest(); void sessionTest(); void multipleRemove(); void removeStoreRemove(); diff -Nru signon-8.57+14.10.20141006/tests/libsignon-qt-tests/testauthsession.cpp signon-8.57+15.04.20150205~rtm/tests/libsignon-qt-tests/testauthsession.cpp --- signon-8.57+14.10.20141006/tests/libsignon-qt-tests/testauthsession.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/libsignon-qt-tests/testauthsession.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -361,6 +361,7 @@ methods.insert(QLatin1String("ssotest"), mechs); IdentityInfo info("test_caption", "test_user_name", methods); info.setSecret("test_secret"); + info.setAccessControlList(QStringList() << "*"); Identity *id = Identity::newIdentity(info, this); QSignalSpy spyResponseStoreCreds(id, SIGNAL(credentialsStored(const quint32))); diff -Nru signon-8.57+14.10.20141006/tests/run-with-signond.sh signon-8.57+15.04.20150205~rtm/tests/run-with-signond.sh --- signon-8.57+14.10.20141006/tests/run-with-signond.sh 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/run-with-signond.sh 2015-02-05 14:39:41.000000000 +0000 @@ -6,14 +6,15 @@ # start a local signond +export HOME="$(mktemp -d --tmpdir signond-tests-XXXXXX)" export SSO_LOGGING_LEVEL=2 -export SSO_STORAGE_PATH="/tmp" +export SSO_STORAGE_PATH="${HOME}" export SSO_DAEMON_TIMEOUT=5 export SSO_IDENTITY_TIMEOUT=5 export SSO_AUTHSESSION_TIMEOUT=5 export PATH="${BUILDDIR}/src/remotepluginprocess:$PATH" export LD_LIBRARY_PATH="${BUILDDIR}/lib/plugins":"${BUILDDIR}/lib/plugins/signon-plugins-common":"${BUILDDIR}/lib/signond/SignOn":"$LD_LIBRARY_PATH" -export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp/runtime-$(whoami)}/signon-tests" +export XDG_RUNTIME_DIR="${HOME}/runtime-dir" mkdir -p "$XDG_RUNTIME_DIR" DBUS_CONFIG=${BUILDDIR}/tests/testsession.conf @@ -42,3 +43,5 @@ cleanUp fi +rm -rf ${HOME} + diff -Nru signon-8.57+14.10.20141006/tests/signond-tests/.gitignore signon-8.57+15.04.20150205~rtm/tests/signond-tests/.gitignore --- signon-8.57+14.10.20141006/tests/signond-tests/.gitignore 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/signond-tests/.gitignore 2015-02-05 14:39:41.000000000 +0000 @@ -1,6 +1,7 @@ /identity-tool /mock-ac-plugin/identity-ac-helper /tst_access_control +/tst_access_control_manager_helper /tst_backup /tst_database /tst_pluginproxy diff -Nru signon-8.57+14.10.20141006/tests/signond-tests/signond-tests.pri signon-8.57+15.04.20150205~rtm/tests/signond-tests/signond-tests.pri --- signon-8.57+14.10.20141006/tests/signond-tests/signond-tests.pri 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/signond-tests/signond-tests.pri 2015-02-05 14:39:41.000000000 +0000 @@ -23,6 +23,8 @@ $${TOP_BUILD_DIR}/lib/signond/SignOn QMAKE_RPATHDIR = $${QMAKE_LIBDIR} +SIGNOND_SRC = $${TOP_SRC_DIR}/src/signond + DEFINES += SIGNOND_TRACE DEFINES += SIGNON_PLUGIN_TRACE diff -Nru signon-8.57+14.10.20141006/tests/signond-tests/signond-tests.pro signon-8.57+15.04.20150205~rtm/tests/signond-tests/signond-tests.pro --- signon-8.57+14.10.20141006/tests/signond-tests/signond-tests.pro 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/signond-tests/signond-tests.pro 2015-02-05 14:39:41.000000000 +0000 @@ -1,5 +1,7 @@ TEMPLATE = subdirs +CONFIG += ordered SUBDIRS = \ + tst_access_control_manager_helper.pro \ tst_timeouts.pro \ tst_pluginproxy.pro \ tst_database.pro \ diff -Nru signon-8.57+14.10.20141006/tests/signond-tests/timeouts.cpp signon-8.57+15.04.20150205~rtm/tests/signond-tests/timeouts.cpp --- signon-8.57+14.10.20141006/tests/signond-tests/timeouts.cpp 2014-10-06 07:56:50.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/signond-tests/timeouts.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -62,6 +62,7 @@ IdentityInfo info = IdentityInfo(QLatin1String("timeout test"), QLatin1String("timeout@test"), methods); + info.setAccessControlList(QStringList() << "*"); Identity *identity = Identity::newIdentity(info); QVERIFY(identity != NULL); @@ -135,6 +136,7 @@ IdentityInfo info = IdentityInfo(QLatin1String("timeout test"), QLatin1String("timeout@test"), methods); + info.setAccessControlList(QStringList() << "*"); Identity *identity = Identity::newIdentity(info); QVERIFY(identity != NULL); diff -Nru signon-8.57+14.10.20141006/tests/signond-tests/tst_access_control_manager_helper.cpp signon-8.57+15.04.20150205~rtm/tests/signond-tests/tst_access_control_manager_helper.cpp --- signon-8.57+14.10.20141006/tests/signond-tests/tst_access_control_manager_helper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/signond-tests/tst_access_control_manager_helper.cpp 2015-02-05 14:39:41.000000000 +0000 @@ -0,0 +1,320 @@ +/* + * This file is part of signon + * + * Copyright (C) 2014 Canonical Ltd. + * + * Contact: Alberto Mardegan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include "accesscontrolmanagerhelper.h" +#include "credentialsaccessmanager.h" +#include "credentialsdb.h" + +using namespace SignOn; +using namespace SignonDaemonNS; + +// mock AbstractAccessControlManager { +class AcmPlugin: public SignOn::AbstractAccessControlManager +{ + Q_OBJECT + +public: + AcmPlugin(QObject *parent = 0): + SignOn::AbstractAccessControlManager(parent) {} + ~AcmPlugin() {} + + bool isPeerAllowedToAccess(const QDBusConnection &peerConnection, + const QDBusMessage &peerMessage, + const QString &securityContext) { + QStringList appPermissions = + m_permissions.value(appIdOfPeer(peerConnection, peerMessage)); + return appPermissions.contains(securityContext); + } + + QString appIdOfPeer(const QDBusConnection &peerConnection, + const QDBusMessage &peerMessage) { + Q_UNUSED(peerConnection); + return peerMessage.service(); + } + + QString keychainWidgetAppId() { return m_keychainWidgetAppId; } + + SignOn::AccessReply *handleRequest(const SignOn::AccessRequest &request) { + Q_UNUSED(request); + return 0; + } + +private: + friend class AccessControlManagerHelperTest; + QMap m_permissions; + QString m_keychainWidgetAppId; +}; +// } mock AbstractAccessControlManager + +class AccessControlManagerHelperTest: public QObject +{ + Q_OBJECT + +public: + AccessControlManagerHelperTest(); + +private Q_SLOTS: + void init(); + void testOwnership_data(); + void testOwnership(); + void testIdentityAccess_data(); + void testIdentityAccess(); + +public: + static AccessControlManagerHelperTest *instance() { return m_instance; } + SignonDaemonNS::CredentialsDB *credentialsDB() { return &m_db; } + +private: + void setDbOwners(const QStringList &owners) { + if (owners.contains("db-error")) { + m_dbOwners = QStringList(); + m_dbLastError = CredentialsDBError("DB error!", + CredentialsDBError::ConnectionError); + } else { + m_dbOwners = owners; + } + } + + void setDbAcl(const QStringList &acl) { + if (acl.contains("db-error")) { + m_dbAcl = QStringList(); + m_dbLastError = CredentialsDBError("DB error!", + CredentialsDBError::ConnectionError); + } else { + m_dbAcl = acl; + } + } + +private: + friend class SignonDaemonNS::CredentialsDB; + static AccessControlManagerHelperTest *m_instance; + AcmPlugin m_acmPlugin; + SignonDaemonNS::CredentialsDB m_db; + SignOn::CredentialsDBError m_dbLastError; + QStringList m_dbAcl; + QStringList m_dbOwners; + QDBusConnection m_conn; +}; + +AccessControlManagerHelperTest *AccessControlManagerHelperTest::m_instance = 0; + +namespace SignonDaemonNS { +// mock CredentialsDB { +CredentialsDB::CredentialsDB(const QString &metaDataDbName, + SignOn::AbstractSecretsStorage *secretsStorage): + QObject() +{ + Q_UNUSED(metaDataDbName); + Q_UNUSED(secretsStorage); +} + +CredentialsDB::~CredentialsDB() +{ +} + +SignOn::CredentialsDBError CredentialsDB::lastError() const +{ + return AccessControlManagerHelperTest::instance()->m_dbLastError; +} + +QStringList CredentialsDB::accessControlList(const quint32 identityId) +{ + Q_UNUSED(identityId); + return AccessControlManagerHelperTest::instance()->m_dbAcl; +} + +QStringList CredentialsDB::ownerList(const quint32 identityId) +{ + Q_UNUSED(identityId); + return AccessControlManagerHelperTest::instance()->m_dbOwners; +} +// } mock CredentialsDB + +// mock CredentialsAccessManager { +CredentialsDB *CredentialsAccessManager::credentialsDB() const { + return AccessControlManagerHelperTest::instance()->credentialsDB(); +} +CredentialsAccessManager *CredentialsAccessManager::instance() { + return 0; +} +} // namespace +// } mock CredentialsAccessManager + +AccessControlManagerHelperTest::AccessControlManagerHelperTest(): + QObject(), + m_db(QString(), 0), + m_conn(QLatin1String("test-connection")) +{ + m_instance = this; +} + +void AccessControlManagerHelperTest::init() +{ + m_dbOwners = QStringList(); + m_dbAcl = QStringList(); + m_dbLastError = CredentialsDBError(); +} + +void AccessControlManagerHelperTest::testOwnership_data() +{ + QTest::addColumn("peer"); + QTest::addColumn("ownerList"); + QTest::addColumn("expectedOwnership"); + + QTest::newRow("DB error") << + "tom" << + (QStringList() << "db-error") << + int(AccessControlManagerHelper::ApplicationIsNotOwner); + + QTest::newRow("empty") << + "tom" << + QStringList() << + int(AccessControlManagerHelper::IdentityDoesNotHaveOwner); + + QTest::newRow("is only owner") << + "tom" << + (QStringList() << "tom") << + int(AccessControlManagerHelper::ApplicationIsOwner); + + QTest::newRow("is co-owner") << + "tom" << + (QStringList() << "Bob" << "tom" << "harry") << + int(AccessControlManagerHelper::ApplicationIsOwner); +} + +void AccessControlManagerHelperTest::testOwnership() +{ + QFETCH(QString, peer); + QFETCH(QStringList, ownerList); + QFETCH(int, expectedOwnership); + + setDbOwners(ownerList); + + m_acmPlugin.m_permissions["tom"] = QStringList() << "tom" << "Tom"; + + /* forge a QDBusMessage */ + QDBusMessage msg = + QDBusMessage::createMethodCall(peer, "/", "interface", "hi"); + + SignonDaemonNS::AccessControlManagerHelper helper(&m_acmPlugin); + + AccessControlManagerHelper::IdentityOwnership ownership = + helper.isPeerOwnerOfIdentity(m_conn, msg, 3); + + QCOMPARE(int(ownership), expectedOwnership); +} + +void AccessControlManagerHelperTest::testIdentityAccess_data() +{ + QTest::addColumn("peer"); + QTest::addColumn("ownerList"); + QTest::addColumn("acl"); + QTest::addColumn("expectedIsAllowed"); + + QTest::newRow("DB error") << + "tom" << + (QStringList() << "tom") << + (QStringList() << "db-error") << + false; + + QTest::newRow("is owner, ACL empty") << + "tom" << + (QStringList() << "tom") << + QStringList() << + true; + + QTest::newRow("is owner, not in ACL") << + "tom" << + (QStringList() << "tom") << + (QStringList() << "bob") << + true; + + QTest::newRow("is owner, in ACL") << + "tom" << + (QStringList() << "tom") << + (QStringList() << "bob" << "tom" << "harry") << + true; + + QTest::newRow("is owner, ACL=*") << + "tom" << + (QStringList() << "tom") << + (QStringList() << "*") << + true; + + QTest::newRow("not owner, ACL empty") << + "tom" << + (QStringList() << "bob") << + QStringList() << + false; + + QTest::newRow("not owner, not in ACL") << + "tom" << + (QStringList() << "bob") << + (QStringList() << "bob") << + false; + + QTest::newRow("not owner, in ACL") << + "tom" << + (QStringList() << "bob") << + (QStringList() << "bob" << "tom" << "harry") << + true; + + QTest::newRow("not owner, ACL=*") << + "tom" << + (QStringList() << "bob") << + (QStringList() << "*") << + true; +} + +void AccessControlManagerHelperTest::testIdentityAccess() +{ + QFETCH(QString, peer); + QFETCH(QStringList, ownerList); + QFETCH(QStringList, acl); + QFETCH(bool, expectedIsAllowed); + + setDbOwners(ownerList); + setDbAcl(acl); + + m_acmPlugin.m_permissions["tom"] = QStringList() << "tom" << "Tom"; + + /* forge a QDBusMessage */ + QDBusMessage msg = + QDBusMessage::createMethodCall(peer, "/", "interface", "hi"); + + SignonDaemonNS::AccessControlManagerHelper helper(&m_acmPlugin); + + bool isAllowed = helper.isPeerAllowedToUseIdentity(m_conn, msg, 3); + + QCOMPARE(isAllowed, expectedIsAllowed); +} + +QTEST_MAIN(AccessControlManagerHelperTest) +#include "tst_access_control_manager_helper.moc" diff -Nru signon-8.57+14.10.20141006/tests/signond-tests/tst_access_control_manager_helper.pro signon-8.57+15.04.20150205~rtm/tests/signond-tests/tst_access_control_manager_helper.pro --- signon-8.57+14.10.20141006/tests/signond-tests/tst_access_control_manager_helper.pro 1970-01-01 00:00:00.000000000 +0000 +++ signon-8.57+15.04.20150205~rtm/tests/signond-tests/tst_access_control_manager_helper.pro 2015-02-05 14:39:41.000000000 +0000 @@ -0,0 +1,13 @@ +TARGET = tst_access_control_manager_helper + +include(signond-tests.pri) + +SOURCES = \ + $${SIGNOND_SRC}/accesscontrolmanagerhelper.cpp \ + tst_access_control_manager_helper.cpp + +HEADERS = \ + $${SIGNOND_SRC}/accesscontrolmanagerhelper.h \ + $${SIGNOND_SRC}/credentialsdb.h + +check.commands = "./$$TARGET"