1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-11 08:34:34 +02:00

ConfigStorage is now in charge of initializing its own account credentials in CredentialsManager.

This commit is contained in:
Teo Mrnjavac
2013-06-11 18:08:45 +02:00
parent e4fbe9bffb
commit 08158ca405
9 changed files with 118 additions and 51 deletions

View File

@@ -219,6 +219,7 @@ list(APPEND libSources
accounts/AccountFactoryWrapper.cpp accounts/AccountFactoryWrapper.cpp
accounts/AccountFactoryWrapperDelegate.cpp accounts/AccountFactoryWrapperDelegate.cpp
accounts/AccountConfigWidget.cpp accounts/AccountConfigWidget.cpp
accounts/ConfigStorage.cpp
accounts/LocalConfigStorage.cpp accounts/LocalConfigStorage.cpp
accounts/spotify/SpotifyAccount.cpp accounts/spotify/SpotifyAccount.cpp

View File

@@ -286,19 +286,13 @@ void
AccountManager::loadFromConfig() AccountManager::loadFromConfig()
{ {
m_creds = new CredentialsManager( this ); m_creds = new CredentialsManager( this );
ConfigStorage* configStorage;
configStorage = new LocalConfigStorage( this ); //registers with CredentialsManager in the ctor ConfigStorage* configStorage = new LocalConfigStorage( this ); //registers with CredentialsManager in the ctor
m_configStorageById.insert( configStorage->id(), configStorage ); m_configStorageById.insert( configStorage->id(), configStorage );
QStringList accountIds; //TODO: when we get more than one CS, hook them all up to continue with account loading
foreach ( ConfigStorage* cs, m_configStorageById ) NewClosure( configStorage, SIGNAL( ready() ),
accountIds << cs->accountIds();
qDebug() << "LOADING ALL CREDENTIALS" << accountIds;
NewClosure( m_creds, SIGNAL( ready() ),
this, SLOT( finishLoadingFromConfig() ) ); this, SLOT( finishLoadingFromConfig() ) );
m_creds->loadCredentials();
} }

View File

@@ -0,0 +1,41 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ConfigStorage.h"
namespace Tomahawk
{
namespace Accounts
{
ConfigStorage::ConfigStorage( QObject* parent )
: QObject( parent )
{
}
ConfigStorage::~ConfigStorage()
{
}
} //ns
} //ns

View File

@@ -29,14 +29,13 @@ namespace Tomahawk
namespace Accounts namespace Accounts
{ {
class ConfigStorage : public QObject class DLLEXPORT ConfigStorage : public QObject
{ {
Q_OBJECT
public: public:
explicit ConfigStorage( QObject* parent ) explicit ConfigStorage( QObject* parent = 0 );
: QObject( parent )
{}
virtual ~ConfigStorage() {} virtual ~ConfigStorage();
virtual QString id() const = 0; virtual QString id() const = 0;
@@ -46,6 +45,8 @@ public:
virtual void load( const QString& accountId, Account::Configuration& cfg ) = 0; virtual void load( const QString& accountId, Account::Configuration& cfg ) = 0;
virtual void remove( const QString& accountId ) = 0; virtual void remove( const QString& accountId ) = 0;
signals:
void ready(); //emit this when done with whatever it is that needs to be initialized
}; };
} //namespace Accounts } //namespace Accounts

View File

@@ -71,44 +71,53 @@ CredentialsManager::addService( const QString& service , const QStringList& acco
if ( m_services.contains( service ) ) if ( m_services.contains( service ) )
m_services.remove( service ); m_services.remove( service );
m_services.insert( service, accountIds ); m_services.insert( service, accountIds );
loadCredentials( service );
} }
void void
CredentialsManager::loadCredentials() CredentialsManager::loadCredentials( const QString &service )
{ {
for ( QHash< QString, QStringList >::const_iterator it = m_services.constBegin();
it != m_services.constEnd(); ++it ) const QStringList& accountIds = m_services.value( service );
tDebug() << Q_FUNC_INFO << "keys for service" << service << ":" << accountIds;
foreach ( QString key, accountIds )
{ {
const QString& svcName = it.key(); QKeychain::ReadPasswordJob* j = new QKeychain::ReadPasswordJob( service, this );
const QStringList& accountIds = it.value(); j->setKey( key );
tDebug() << Q_FUNC_INFO << "keys for service" << svcName << ":" << accountIds; j->setAutoDelete( false );
foreach ( QString key, accountIds )
{
QKeychain::ReadPasswordJob* j = new QKeychain::ReadPasswordJob( svcName, this );
j->setKey( key );
j->setAutoDelete( false );
#if defined( Q_OS_UNIX ) && !defined( Q_OS_MAC ) #if defined( Q_OS_UNIX ) && !defined( Q_OS_MAC )
j->setInsecureFallback( true ); j->setInsecureFallback( true );
#endif #endif
connect( j, SIGNAL( finished( QKeychain::Job* ) ), connect( j, SIGNAL( finished( QKeychain::Job* ) ),
SLOT( keychainJobFinished( QKeychain::Job* ) ) ); SLOT( keychainJobFinished( QKeychain::Job* ) ) );
m_readJobs << j; m_readJobs[ service ] << j;
j->start(); j->start();
tDebug() << "Launching QtKeychain readJob for" << key; tDebug() << "Launching QtKeychain readJob for" << key;
}
} }
} }
QList< CredentialsStorageKey > QStringList
CredentialsManager::keys() const CredentialsManager::keys( const QString& service ) const
{ {
QList< CredentialsStorageKey > keys = m_credentials.keys(); QStringList keys;
foreach ( const CredentialsStorageKey& k, m_credentials.keys() )
{
if ( k.service() == service )
keys << k.key();
}
return keys; return keys;
} }
QStringList
CredentialsManager::services() const
{
return m_services.keys();
}
QVariantHash QVariantHash
CredentialsManager::credentials( const CredentialsStorageKey& key ) const CredentialsManager::credentials( const CredentialsStorageKey& key ) const
{ {
@@ -197,11 +206,11 @@ CredentialsManager::keychainJobFinished( QKeychain::Job* j )
tDebug() << "QtKeychain readJob for" << readJob->key() << "finished with error:" << j->error() << j->errorString(); tDebug() << "QtKeychain readJob for" << readJob->key() << "finished with error:" << j->error() << j->errorString();
} }
m_readJobs.removeOne( readJob ); m_readJobs[ readJob->service() ].removeOne( readJob );
if ( m_readJobs.isEmpty() ) if ( m_readJobs[ readJob->service() ].isEmpty() )
{ {
emit ready(); emit serviceReady( readJob->service() );
} }
} }
else if ( QKeychain::WritePasswordJob* writeJob = qobject_cast< QKeychain::WritePasswordJob* >( j ) ) else if ( QKeychain::WritePasswordJob* writeJob = qobject_cast< QKeychain::WritePasswordJob* >( j ) )

View File

@@ -55,10 +55,6 @@ private:
/** /**
* @brief The CredentialsManager class holds an in-memory cache of whatever credentials are stored * @brief The CredentialsManager class holds an in-memory cache of whatever credentials are stored
* in the system's QtKeychain-accessible credentials storage. * in the system's QtKeychain-accessible credentials storage.
* After instantiating the class, loadCredentials should be called, and this is the only time a read
* operation from QtKeychain is performed. When CredentialsManager emits ready(), it can be used for
* all other operations. The only QtKeychain operations performed at any time after startup are
* write and delete.
* This ensures an illusion of synchronous operations for Tomahawk's Account classes, even though all * This ensures an illusion of synchronous operations for Tomahawk's Account classes, even though all
* QtKeychain jobs are async. * QtKeychain jobs are async.
*/ */
@@ -70,25 +66,28 @@ public:
void addService( const QString& service, const QStringList& accountIds ); void addService( const QString& service, const QStringList& accountIds );
void loadCredentials(); QStringList keys( const QString& service ) const;
QStringList services() const;
QList< CredentialsStorageKey > keys() const;
QVariantHash credentials( const CredentialsStorageKey& key ) const;
QVariantHash credentials( const QString& serviceName, const QString& key ) const; QVariantHash credentials( const QString& serviceName, const QString& key ) const;
void setCredentials( const CredentialsStorageKey& key, const QVariantHash& value );
void setCredentials( const QString& serviceName, const QString& key, const QVariantHash& value ); void setCredentials( const QString& serviceName, const QString& key, const QVariantHash& value );
signals: signals:
void ready(); void serviceReady( const QString& service );
private slots: private slots:
void loadCredentials( const QString& service );
void keychainJobFinished( QKeychain::Job* ); void keychainJobFinished( QKeychain::Job* );
protected:
QVariantHash credentials( const CredentialsStorageKey& key ) const;
void setCredentials( const CredentialsStorageKey& key, const QVariantHash& value );
private: private:
QHash< QString, QStringList > m_services; QHash< QString, QStringList > m_services;
QHash< CredentialsStorageKey, QVariantHash > m_credentials; QHash< CredentialsStorageKey, QVariantHash > m_credentials;
QList< QKeychain::ReadPasswordJob* > m_readJobs; QHash< QString, QList< QKeychain::ReadPasswordJob* > > m_readJobs;
QMutex m_mutex; QMutex m_mutex;
}; };

View File

@@ -21,6 +21,7 @@
#include "Account.h" #include "Account.h"
#include "AccountManager.h" #include "AccountManager.h"
#include "CredentialsManager.h" #include "CredentialsManager.h"
#include "utils/Logger.h"
namespace Tomahawk namespace Tomahawk
{ {
@@ -36,9 +37,27 @@ LocalConfigStorage::LocalConfigStorage( QObject* parent )
m_accountIds = TomahawkSettings::instance()->accounts(); m_accountIds = TomahawkSettings::instance()->accounts();
// tell CredentialsManager which account ids it will be writing credentials for and in which svc // tell CredentialsManager which account ids it will be writing credentials for and in which svc
// so it can preload them when we call CM::loadCredentials()
CredentialsManager* cm = AccountManager::instance()->credentialsManager();
connect( cm, SIGNAL( serviceReady( QString ) ),
this, SLOT( onCredentialsManagerReady( QString ) ) );
AccountManager::instance()->credentialsManager()->addService( m_credentialsServiceName, AccountManager::instance()->credentialsManager()->addService( m_credentialsServiceName,
m_accountIds ); m_accountIds );
tDebug() << Q_FUNC_INFO << "LOADING ALL CREDENTIALS FOR SERVICE" << m_credentialsServiceName << m_accountIds;
}
void
LocalConfigStorage::onCredentialsManagerReady( const QString& service )
{
if ( service != m_credentialsServiceName )
return;
//no need to listen for it any more
disconnect( this, SLOT( onCredentialsManagerReady( QString ) ) );
emit ready();
} }

View File

@@ -41,6 +41,10 @@ public:
virtual void load( const QString& accountId, Account::Configuration& cfg ); virtual void load( const QString& accountId, Account::Configuration& cfg );
virtual void remove( const QString& accountId ); virtual void remove( const QString& accountId );
private slots:
void onCredentialsManagerReady( const QString& service );
private: private:
const QString m_credentialsServiceName; const QString m_credentialsServiceName;
QStringList m_accountIds; QStringList m_accountIds;

View File

@@ -37,7 +37,6 @@ TelepathyConfigStorage::TelepathyConfigStorage( QObject* parent )
{ {
tDebug() << Q_FUNC_INFO; tDebug() << Q_FUNC_INFO;
// tell CredentialsManager which account ids it will be writing credentials for and in which svc // tell CredentialsManager which account ids it will be writing credentials for and in which svc
// so it can preload them when we call CM::loadCredentials() // so it can preload them when we call CM::loadCredentials()
AccountManager::instance()->credentialsManager()->addService( m_credentialsServiceName, AccountManager::instance()->credentialsManager()->addService( m_credentialsServiceName,