mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-06 20:20:41 +02:00
Compare commits
16 Commits
0.5.4
...
qtkeychain
Author | SHA1 | Date | |
---|---|---|---|
|
3999a98514 | ||
|
1210665e56 | ||
|
59cd8e5b80 | ||
|
3f75db64eb | ||
|
6ac1545a09 | ||
|
eb65f7ca39 | ||
|
f9c58dda1e | ||
|
bebac92763 | ||
|
7130151949 | ||
|
44aa299099 | ||
|
ed48f4a5f2 | ||
|
8febff6030 | ||
|
e5933b775d | ||
|
a968f3e92b | ||
|
7fbcf653d3 | ||
|
fc5bdae520 |
@@ -159,6 +159,17 @@ SET( LIBPORTFWD_LIBRARY tomahawk_portfwd )
|
||||
SET( LIBPORTFWD_LIBRARIES ${LIBPORTFWD_LIBRARY} )
|
||||
ADD_SUBDIRECTORY( ${THIRDPARTY_DIR}/libportfwd )
|
||||
|
||||
### qtkeychain
|
||||
SET( QTKEYCHAIN_INCLUDE_DIRS ${THIRDPARTY_DIR}/qtkeychain )
|
||||
SET( QTKEYCHAIN_LIBRARY qtkeychain )
|
||||
SET( QTKEYCHAIN_LIBRARIES ${QTKEYCHAIN_LIBRARY} )
|
||||
ADD_SUBDIRECTORY( ${THIRDPARTY_DIR}/qtkeychain/qtkeychain )
|
||||
|
||||
if( NOT QTKEYCHAIN_INCLUDE_DIRS OR NOT QTKEYCHAIN_LIBRARIES )
|
||||
macro_optional_find_package(QtKeychain)
|
||||
macro_log_feature(QTKEYCHAIN_FOUND "QtKeychain" "Provides support for secure password storage" "https://github.com/frankosterfeld/qtkeychain" TRUE "" "")
|
||||
endif()
|
||||
|
||||
# we need pthreads too
|
||||
#macro_optional_find_package(Threads)
|
||||
#macro_log_feature(THREADS_FOUND "Threads" "Threading Library" "" TRUE "" "Platform specific library for threading")
|
||||
|
@@ -53,6 +53,8 @@ TwitterAccount::TwitterAccount( const QString &accountId )
|
||||
setAccountServiceName( "Twitter" );
|
||||
setTypes( AccountTypes( StatusPushType | SipType ) );
|
||||
|
||||
connect( this, SIGNAL( credentialsLoaded( QVariantHash ) ), this, SLOT( onCredentialsLoaded( QVariantHash ) ) );
|
||||
|
||||
qDebug() << "Got cached peers:" << configuration() << configuration()[ "cachedpeers" ];
|
||||
|
||||
m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
|
||||
@@ -73,13 +75,41 @@ TwitterAccount::configDialogAuthedSignalSlot( bool authed )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
m_isAuthenticated = authed;
|
||||
if ( !credentials()[ "username" ].toString().isEmpty() )
|
||||
setAccountFriendlyName( QString( "@%1" ).arg( credentials()[ "username" ].toString() ) );
|
||||
if ( !m_credentials[ "username" ].toString().isEmpty() )
|
||||
setAccountFriendlyName( QString( "@%1" ).arg( m_credentials[ "username" ].toString() ) );
|
||||
syncConfig();
|
||||
emit configurationChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwitterAccount::onCredentialsLoaded( const QVariantHash &credentials )
|
||||
{
|
||||
// Credentials loaded
|
||||
bool reload = false;
|
||||
if ( !credentials[ "oauthtoken" ].toString().isEmpty() && !credentials[ "oauthtokensecret" ].toString().isEmpty() &&
|
||||
( m_credentials[ "oauthtoken" ] != credentials[ "oauthtoken"] || m_credentials[ "oauthtokensecret" ] != credentials[ "oauthtokensecret" ] ) )
|
||||
reload = true;
|
||||
|
||||
m_credentials = credentials;
|
||||
|
||||
if ( reload && enabled() )
|
||||
{
|
||||
qDebug() << "Twitter account got async load of credentials, authenticating now!";
|
||||
authenticate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwitterAccount::setCredentials( const QVariantHash &credentials )
|
||||
{
|
||||
m_credentials = credentials;
|
||||
|
||||
saveCredentials( credentials );
|
||||
}
|
||||
|
||||
|
||||
Account::ConnectionState
|
||||
TwitterAccount::connectionState() const
|
||||
{
|
||||
@@ -139,9 +169,9 @@ TwitterAccount::authenticateSlot()
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "credentials: " << credentials().keys();
|
||||
tDebug() << Q_FUNC_INFO << "credentials: " << m_credentials.keys();
|
||||
|
||||
if ( credentials()[ "oauthtoken" ].toString().isEmpty() || credentials()[ "oauthtokensecret" ].toString().isEmpty() )
|
||||
if ( m_credentials[ "oauthtoken" ].toString().isEmpty() || m_credentials[ "oauthtokensecret" ].toString().isEmpty() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "TwitterSipPlugin has empty Twitter credentials; not connecting";
|
||||
return;
|
||||
@@ -191,8 +221,8 @@ TwitterAccount::refreshTwitterAuth()
|
||||
if( m_twitterAuth.isNull() )
|
||||
return false;
|
||||
|
||||
m_twitterAuth.data()->setOAuthToken( credentials()[ "oauthtoken" ].toString().toLatin1() );
|
||||
m_twitterAuth.data()->setOAuthTokenSecret( credentials()[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
m_twitterAuth.data()->setOAuthToken( m_credentials[ "oauthtoken" ].toString().toLatin1() );
|
||||
m_twitterAuth.data()->setOAuthTokenSecret( m_credentials[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -79,11 +79,16 @@ public:
|
||||
bool refreshTwitterAuth();
|
||||
TomahawkOAuthTwitter* twitterAuth() const { return m_twitterAuth.data(); }
|
||||
|
||||
QVariantHash credentials() const { return m_credentials; }
|
||||
void setCredentials( const QVariantHash& creds );
|
||||
|
||||
signals:
|
||||
void nowAuthenticated( const QWeakPointer< TomahawkOAuthTwitter >&, const QTweetUser &user );
|
||||
void nowDeauthenticated();
|
||||
|
||||
private slots:
|
||||
void onCredentialsLoaded( const QVariantHash& credentials );
|
||||
|
||||
void authenticateSlot();
|
||||
void configDialogAuthedSignalSlot( bool authed );
|
||||
void connectAuthVerifyReply( const QTweetUser &user );
|
||||
@@ -92,6 +97,7 @@ private:
|
||||
QIcon m_icon;
|
||||
bool m_isAuthenticated;
|
||||
bool m_isAuthenticating;
|
||||
QVariantHash m_credentials;
|
||||
QWeakPointer< TomahawkOAuthTwitter > m_twitterAuth;
|
||||
QWeakPointer< TwitterConfigWidget > m_configWidget;
|
||||
QWeakPointer< TwitterSipPlugin > m_twitterSipPlugin;
|
||||
|
@@ -58,6 +58,17 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare
|
||||
m_ui->twitterTweetComboBox->setCurrentIndex( 0 );
|
||||
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
|
||||
|
||||
}
|
||||
|
||||
TwitterConfigWidget::~TwitterConfigWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwitterConfigWidget::loadConfig()
|
||||
{
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
|
||||
if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
|
||||
@@ -79,13 +90,8 @@ TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *pare
|
||||
|
||||
emit twitterAuthed( true );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TwitterConfigWidget::~TwitterConfigWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void
|
||||
TwitterConfigWidget::authDeauthTwitter()
|
||||
@@ -159,11 +165,7 @@ void
|
||||
TwitterConfigWidget::deauthenticateTwitter()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
credentials[ "oauthtoken" ] = QString();
|
||||
credentials[ "oauthtokensecret" ] = QString();
|
||||
credentials[ "username" ] = QString();
|
||||
m_account->setCredentials( credentials );
|
||||
m_account->setCredentials( QVariantHash() );
|
||||
|
||||
m_ui->twitterStatusLabel->setText(tr("Status: No saved credentials"));
|
||||
m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
|
||||
@@ -232,7 +234,7 @@ TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &use
|
||||
return;
|
||||
}
|
||||
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
const QVariantHash credentials = m_account->credentials();
|
||||
twitAuth->setOAuthToken( credentials[ "oauthtoken" ].toString().toLatin1() );
|
||||
twitAuth->setOAuthTokenSecret( credentials[ "oauthtokensecret" ].toString().toLatin1() );
|
||||
if ( m_postGTtype != "Direct Message" )
|
||||
@@ -291,6 +293,14 @@ TwitterConfigWidget::postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode
|
||||
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your status -- sorry!") );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwitterConfigWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
loadConfig();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -50,11 +50,17 @@ class ACCOUNTDLLEXPORT TwitterConfigWidget : public QWidget
|
||||
public:
|
||||
explicit TwitterConfigWidget( TwitterAccount* account = 0, QWidget *parent = 0 );
|
||||
virtual ~TwitterConfigWidget();
|
||||
|
||||
void loadConfig();
|
||||
|
||||
signals:
|
||||
void twitterAuthed( bool authed );
|
||||
|
||||
void sizeHintChanged();
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent* event );
|
||||
|
||||
|
||||
private slots:
|
||||
void authDeauthTwitter();
|
||||
|
@@ -40,7 +40,10 @@ XmppAccountFactory::createAccount( const QString& accountId )
|
||||
|
||||
XmppAccount::XmppAccount( const QString &accountId )
|
||||
: Account( accountId )
|
||||
, m_credentialsLoading( true )
|
||||
{
|
||||
connect( this, SIGNAL( credentialsLoaded( QVariantHash ) ), this, SLOT( onCredentialsLoaded( QVariantHash ) ) );
|
||||
|
||||
setAccountServiceName( "Jabber (XMPP)" );
|
||||
setTypes( SipType );
|
||||
|
||||
@@ -57,7 +60,7 @@ XmppAccount::~XmppAccount()
|
||||
void
|
||||
XmppAccount::authenticate()
|
||||
{
|
||||
if ( connectionState() != Account::Connected )
|
||||
if ( connectionState() != Account::Connected && !m_credentialsLoading )
|
||||
sipPlugin()->connectPlugin();
|
||||
}
|
||||
|
||||
@@ -90,6 +93,25 @@ XmppAccount::saveConfig()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmppAccount::onCredentialsLoaded( const QVariantHash& credentials )
|
||||
{
|
||||
m_credentials = credentials;
|
||||
m_credentialsLoading = false;
|
||||
if ( !m_xmppSipPlugin.isNull() )
|
||||
m_xmppSipPlugin.data()->configurationChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmppAccount::setCredentials( const QVariantHash &credentials )
|
||||
{
|
||||
m_credentials = credentials;
|
||||
|
||||
saveCredentials( credentials );
|
||||
}
|
||||
|
||||
|
||||
InfoSystem::InfoPluginPtr
|
||||
XmppAccount::infoPlugin()
|
||||
{
|
||||
|
@@ -77,12 +77,21 @@ public:
|
||||
QWidget* aclWidget() { return 0; }
|
||||
void saveConfig();
|
||||
|
||||
QVariantHash credentials() const { return m_credentials; }
|
||||
void setCredentials( const QVariantHash& credentials );
|
||||
|
||||
virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const;
|
||||
|
||||
private slots:
|
||||
void onCredentialsLoaded( const QVariantHash& credentials );
|
||||
|
||||
protected:
|
||||
QWeakPointer< QWidget > m_configWidget; // so the google wrapper can change the config dialog a bit
|
||||
QWeakPointer< XmppSipPlugin > m_xmppSipPlugin;
|
||||
QWeakPointer< Tomahawk::InfoSystem::XmppInfoPlugin > m_xmppInfoPlugin;
|
||||
|
||||
QVariantHash m_credentials;
|
||||
bool m_credentialsLoading;
|
||||
};
|
||||
|
||||
};
|
||||
|
@@ -38,14 +38,9 @@ XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget *parent ) :
|
||||
m_account( account )
|
||||
{
|
||||
m_ui->setupUi( this );
|
||||
|
||||
m_ui->xmppUsername->setText( account->credentials().contains( "username" ) ? account->credentials()[ "username" ].toString() : QString() );
|
||||
m_ui->xmppPassword->setText( account->credentials().contains( "password" ) ? account->credentials()[ "password" ].toString() : QString() );
|
||||
m_ui->xmppServer->setText( account->configuration().contains( "server" ) ? account->configuration()[ "server" ].toString() : QString() );
|
||||
m_ui->xmppPort->setValue( account->configuration().contains( "port" ) ? account->configuration()[ "port" ].toInt() : 5222 );
|
||||
m_ui->xmppPublishTracksCheckbox->setChecked( account->configuration().contains( "publishtracks" ) ? account->configuration()[ "publishtracks" ].toBool() : true);
|
||||
m_ui->xmppEnforceSecureCheckbox->setChecked( account->configuration().contains( "enforcesecure" ) ? account->configuration()[ "enforcesecure" ].toBool() : false);
|
||||
m_ui->jidExistsLabel->hide();
|
||||
|
||||
loadFromConfig();
|
||||
|
||||
connect( m_ui->xmppUsername, SIGNAL( textChanged( QString ) ), SLOT( onCheckJidExists( QString ) ) );
|
||||
}
|
||||
@@ -70,27 +65,52 @@ XmppConfigWidget::saveConfig()
|
||||
configuration[ "enforcesecure"] = m_ui->xmppEnforceSecureCheckbox->isChecked();
|
||||
|
||||
m_account->setAccountFriendlyName( m_ui->xmppUsername->text() );
|
||||
m_account->setCredentials( credentials );
|
||||
m_account->setConfiguration( configuration);
|
||||
m_account->sync();
|
||||
|
||||
m_account->setCredentials( credentials );
|
||||
|
||||
static_cast< XmppSipPlugin* >( m_account->sipPlugin() )->checkSettings();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmppConfigWidget::showEvent(QShowEvent* event)
|
||||
{
|
||||
loadFromConfig();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XmppConfigWidget::loadFromConfig()
|
||||
{
|
||||
m_ui->xmppUsername->setText( m_account->credentials().contains( "username" ) ? m_account->credentials()[ "username" ].toString() : QString() );
|
||||
m_ui->xmppPassword->setText( m_account->credentials().contains( "password" ) ? m_account->credentials()[ "password" ].toString() : QString() );
|
||||
m_ui->xmppServer->setText( m_account->configuration().contains( "server" ) ? m_account->configuration()[ "server" ].toString() : QString() );
|
||||
m_ui->xmppPort->setValue( m_account->configuration().contains( "port" ) ? m_account->configuration()[ "port" ].toInt() : 5222 );
|
||||
m_ui->xmppPublishTracksCheckbox->setChecked( m_account->configuration().contains( "publishtracks" ) ? m_account->configuration()[ "publishtracks" ].toBool() : true);
|
||||
m_ui->xmppEnforceSecureCheckbox->setChecked( m_account->configuration().contains( "enforcesecure" ) ? m_account->configuration()[ "enforcesecure" ].toBool() : false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
XmppConfigWidget::onCheckJidExists( QString jid )
|
||||
{
|
||||
QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType );
|
||||
const QList< Tomahawk::Accounts::Account* > accounts = Tomahawk::Accounts::AccountManager::instance()->accounts( Tomahawk::Accounts::SipType );
|
||||
foreach( Tomahawk::Accounts::Account* account, accounts )
|
||||
{
|
||||
if ( account->accountId() == m_account->accountId() )
|
||||
continue;
|
||||
XmppAccount* xmppAccount = qobject_cast< XmppAccount* >( account );
|
||||
if ( !xmppAccount )
|
||||
continue;
|
||||
|
||||
QString savedUsername = account->credentials()[ "username" ].toString();
|
||||
QStringList savedSplitUsername = account->credentials()[ "username" ].toString().split("@");
|
||||
QString savedServer = account->configuration()[ "server" ].toString();
|
||||
int savedPort = account->configuration()[ "port" ].toInt();
|
||||
// Check if any other xmpp account already uses the given name/settings
|
||||
QString savedUsername = xmppAccount->credentials()[ "username" ].toString();
|
||||
QStringList savedSplitUsername = xmppAccount->credentials()[ "username" ].toString().split("@");
|
||||
QString savedServer = xmppAccount->configuration()[ "server" ].toString();
|
||||
int savedPort = xmppAccount->configuration()[ "port" ].toInt();
|
||||
|
||||
if ( ( savedUsername == jid || savedSplitUsername.contains( jid ) ) &&
|
||||
savedServer == m_ui->xmppServer->text() &&
|
||||
|
@@ -48,10 +48,15 @@ public:
|
||||
virtual ~XmppConfigWidget();
|
||||
|
||||
void saveConfig();
|
||||
|
||||
void loadFromConfig();
|
||||
|
||||
signals:
|
||||
void dataError( bool exists );
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent* event );
|
||||
|
||||
private slots:
|
||||
void onCheckJidExists( QString jid );
|
||||
|
||||
|
@@ -43,7 +43,7 @@ GoogleWrapperFactory::icon() const
|
||||
return QPixmap( ":/gmail-logo.png" );
|
||||
}
|
||||
|
||||
GoogleWrapperSip::GoogleWrapperSip( Account* account )
|
||||
GoogleWrapperSip::GoogleWrapperSip( GoogleWrapper *account )
|
||||
: XmppSipPlugin( account )
|
||||
{
|
||||
|
||||
|
@@ -44,11 +44,13 @@ public:
|
||||
virtual Account* createAccount( const QString& pluginId );
|
||||
};
|
||||
|
||||
class GoogleWrapper;
|
||||
|
||||
class ACCOUNTDLLEXPORT GoogleWrapperSip : public XmppSipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GoogleWrapperSip( Tomahawk::Accounts::Account* account );
|
||||
GoogleWrapperSip( Tomahawk::Accounts::GoogleWrapper* account );
|
||||
virtual ~GoogleWrapperSip();
|
||||
|
||||
public slots:
|
||||
|
@@ -50,6 +50,8 @@
|
||||
#include <accounts/AccountManager.h>
|
||||
#include <TomahawkSettings.h>
|
||||
|
||||
#include "../XmppAccount.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QtGui/QInputDialog>
|
||||
#include <QtGui/QLineEdit>
|
||||
@@ -90,8 +92,9 @@ JreenMessageHandler( QtMsgType type, const char *msg )
|
||||
}
|
||||
|
||||
|
||||
XmppSipPlugin::XmppSipPlugin( Account* account )
|
||||
XmppSipPlugin::XmppSipPlugin( XmppAccount *account )
|
||||
: SipPlugin( account )
|
||||
, m_xmppAccount( account )
|
||||
, m_state( Account::Disconnected )
|
||||
#ifndef ENABLE_HEADLESS
|
||||
, m_menu( 0 )
|
||||
@@ -221,7 +224,7 @@ XmppSipPlugin::connectPlugin()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_account->configuration().contains( "enforcesecure" ) && m_account->configuration().value( "enforcesecure" ).toBool() )
|
||||
if ( m_xmppAccount->configuration().contains( "enforcesecure" ) && m_xmppAccount->configuration().value( "enforcesecure" ).toBool() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Enforcing secure connection...";
|
||||
m_client->setFeatureConfig( Jreen::Client::Encryption, Jreen::Client::Force );
|
||||
@@ -510,7 +513,7 @@ XmppSipPlugin::showAddFriendDialog()
|
||||
void
|
||||
XmppSipPlugin::publishTune( const QUrl& url, const InfoSystem::InfoStringHash& trackInfo )
|
||||
{
|
||||
if ( m_account->configuration().value("publishtracks").toBool() == false )
|
||||
if ( m_xmppAccount->configuration().value("publishtracks").toBool() == false )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_client->jid().full() << "Not publishing now playing info (disabled in account config)";
|
||||
return;
|
||||
@@ -578,6 +581,7 @@ XmppSipPlugin::configurationChanged()
|
||||
server = readServer();
|
||||
port = readPort();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Configuration changed in SIP plugin:" << username << password << server << port << m_account->accountFriendlyName();
|
||||
if ( m_currentUsername != username )
|
||||
{
|
||||
m_currentUsername = username;
|
||||
@@ -602,19 +606,21 @@ XmppSipPlugin::configurationChanged()
|
||||
if ( !m_currentUsername.contains( '@' ) )
|
||||
{
|
||||
m_currentUsername += defaultSuffix();
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
QVariantHash credentials = m_xmppAccount->credentials();
|
||||
credentials[ "username" ] = m_currentUsername;
|
||||
m_account->setCredentials( credentials );
|
||||
m_account->sync();
|
||||
m_xmppAccount->saveCredentials( credentials );
|
||||
}
|
||||
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "reconnecting?" << reconnect << "enabled?" << m_account->enabled() << m_account->accountFriendlyName();
|
||||
if ( reconnect )
|
||||
setupClientHelper();
|
||||
|
||||
if ( reconnect && m_account->enabled() )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Reconnecting jreen plugin...";
|
||||
disconnectPlugin();
|
||||
|
||||
setupClientHelper();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Updated settings";
|
||||
connectPlugin();
|
||||
}
|
||||
@@ -1035,23 +1041,21 @@ XmppSipPlugin::readXmlConsoleEnabled()
|
||||
QString
|
||||
XmppSipPlugin::readUsername()
|
||||
{
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
return credentials.contains( "username" ) ? credentials[ "username" ].toString() : QString();
|
||||
return m_xmppAccount->credentials().value( "username" ).toString();
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
XmppSipPlugin::readPassword()
|
||||
{
|
||||
QVariantHash credentials = m_account->credentials();
|
||||
return credentials.contains( "password" ) ? credentials[ "password" ].toString() : QString();
|
||||
return m_xmppAccount->credentials().value( "password" ).toString();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XmppSipPlugin::readPort()
|
||||
{
|
||||
QVariantHash configuration = m_account->configuration();
|
||||
QVariantHash configuration = m_xmppAccount->configuration();
|
||||
return configuration.contains( "port" ) ? configuration[ "port" ].toInt() : 5222;
|
||||
}
|
||||
|
||||
@@ -1059,7 +1063,7 @@ XmppSipPlugin::readPort()
|
||||
QString
|
||||
XmppSipPlugin::readServer()
|
||||
{
|
||||
QVariantHash configuration = m_account->configuration();
|
||||
QVariantHash configuration = m_xmppAccount->configuration();
|
||||
return configuration.contains( "server" ) ? configuration[ "server" ].toString() : QString();
|
||||
}
|
||||
|
||||
|
@@ -52,6 +52,13 @@
|
||||
|
||||
#include "../XmppInfoPlugin.h"
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace Accounts {
|
||||
class XmppAccount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ACCOUNTDLLEXPORT XmppSipPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -59,7 +66,7 @@ class ACCOUNTDLLEXPORT XmppSipPlugin : public SipPlugin
|
||||
friend class Tomahawk::InfoSystem::XmppInfoPlugin;
|
||||
|
||||
public:
|
||||
XmppSipPlugin( Tomahawk::Accounts::Account* account );
|
||||
XmppSipPlugin( Tomahawk::Accounts::XmppAccount* account );
|
||||
virtual ~XmppSipPlugin();
|
||||
|
||||
//FIXME: Make this more correct
|
||||
@@ -131,6 +138,7 @@ private:
|
||||
int m_currentPort;
|
||||
QString m_currentResource;
|
||||
|
||||
Tomahawk::Accounts::XmppAccount* m_xmppAccount;
|
||||
QWeakPointer< Tomahawk::InfoSystem::XmppInfoPlugin > m_infoPlugin;
|
||||
Tomahawk::Accounts::Account::ConnectionState m_state;
|
||||
|
||||
|
@@ -327,6 +327,8 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
|
||||
${LIBECHONEST_INCLUDE_DIR}/..
|
||||
${CLUCENE_INCLUDE_DIRS}
|
||||
${PHONON_INCLUDES}
|
||||
${QTKEYCHAIN_INCLUDE_DIRS}
|
||||
${QTKEYCHAIN_INCLUDE_DIRS}/..
|
||||
${CMAKE_BINARY_DIR}/thirdparty/liblastfm2/src
|
||||
|
||||
playlist
|
||||
@@ -357,14 +359,14 @@ ENDIF( UNIX AND NOT APPLE )
|
||||
IF( WIN32 )
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
# System
|
||||
# System
|
||||
"iphlpapi.a"
|
||||
"ws2_32.dll"
|
||||
"dnsapi.dll"
|
||||
"dsound.dll"
|
||||
"winmm.dll"
|
||||
"advapi32.dll"
|
||||
"shlwapi.dll"
|
||||
"shlwapi.dll"
|
||||
)
|
||||
ENDIF( WIN32 )
|
||||
|
||||
@@ -388,7 +390,7 @@ IF( APPLE )
|
||||
${COREAUDIO_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${FOUNDATION_LIBRARY}
|
||||
${SCRIPTINGBRIDGE_LIBRARY}
|
||||
${SCRIPTINGBRIDGE_LIBRARY}
|
||||
|
||||
/System/Library/Frameworks/AppKit.framework
|
||||
/System/Library/Frameworks/Security.framework
|
||||
@@ -437,6 +439,7 @@ TARGET_LINK_LIBRARIES( tomahawklib
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${LINK_LIBRARIES}
|
||||
${QTKEYCHAIN_LIBRARIES}
|
||||
)
|
||||
|
||||
INSTALL( TARGETS tomahawklib
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "TomahawkSettings.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <qtkeychain/keychain.h>
|
||||
|
||||
#include "Source.h"
|
||||
#include "sip/SipHandler.h"
|
||||
@@ -589,6 +590,37 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
|
||||
createSpotifyAccount();
|
||||
}
|
||||
}
|
||||
else if ( oldVersion == 12 )
|
||||
{
|
||||
const QStringList accounts = value( "accounts/allaccounts" ).toStringList();
|
||||
//Move storage of Credentials from QSettings to QtKeychain
|
||||
foreach ( const QString& account, accounts )
|
||||
{
|
||||
beginGroup( QString( "accounts/%1" ).arg( account ) );
|
||||
const QVariantHash creds = value( "credentials" ).toHash();
|
||||
|
||||
if ( !creds.isEmpty() )
|
||||
{
|
||||
QKeychain::WritePasswordJob* j = new QKeychain::WritePasswordJob( QLatin1String( "tomahawkaccounts" ), this );
|
||||
j->setKey( account );
|
||||
j->setAutoDelete( false );
|
||||
|
||||
QByteArray data;
|
||||
QDataStream ds( &data, QIODevice::WriteOnly );
|
||||
ds << creds;
|
||||
|
||||
j->setBinaryData( data );
|
||||
// connect( j, SIGNAL( finished( QKeychain::Job* ) ), this, SLOT( keychainJobFinished( QKeychain::Job* ) ) );
|
||||
j->start();
|
||||
|
||||
qDebug() << "Migrating account credentials for account:" << account;
|
||||
}
|
||||
|
||||
remove( "credentials" );
|
||||
|
||||
endGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <QtNetwork/QNetworkProxy>
|
||||
#include <QStringList>
|
||||
|
||||
#define TOMAHAWK_SETTINGS_VERSION 12
|
||||
#define TOMAHAWK_SETTINGS_VERSION 13
|
||||
|
||||
/**
|
||||
* Convenience wrapper around QSettings for tomahawk-specific config
|
||||
|
@@ -20,6 +20,9 @@
|
||||
#include "Account.h"
|
||||
|
||||
#include "TomahawkSettings.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <qtkeychain/keychain.h>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -115,6 +118,50 @@ Account::onError( int errorCode, const QString& error )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Account::keychainJobFinished( QKeychain::Job* j )
|
||||
{
|
||||
if ( j->error() == QKeychain::NoError )
|
||||
{
|
||||
if ( QKeychain::ReadPasswordJob* readJob = qobject_cast< QKeychain::ReadPasswordJob* >( j ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "readJob finished without errors";
|
||||
|
||||
QVariantHash credentials;
|
||||
QDataStream dataStream( readJob->binaryData() );
|
||||
dataStream >> credentials;
|
||||
|
||||
tLog() << Q_FUNC_INFO << readJob->key();
|
||||
|
||||
emit credentialsLoaded( credentials );
|
||||
}
|
||||
else if ( QKeychain::WritePasswordJob* writeJob = qobject_cast< QKeychain::WritePasswordJob* >( j ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "writeJob finished";
|
||||
}
|
||||
else if ( QKeychain::DeletePasswordJob* deleteJob = qobject_cast< QKeychain::DeletePasswordJob* >( j ) )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "deleteJob finished";
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Job finished with error: " << j->error() << " " << j->errorString();
|
||||
}
|
||||
|
||||
j->deleteLater();
|
||||
|
||||
m_workingKeychainJobs.removeAll( j );
|
||||
if ( !m_queuedKeychainJobs.isEmpty() )
|
||||
{
|
||||
QKeychain::Job* j = m_queuedKeychainJobs.dequeue();
|
||||
j->start();
|
||||
m_workingKeychainJobs << j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Account::onConnectionStateChanged( Account::ConnectionState )
|
||||
{
|
||||
@@ -129,7 +176,6 @@ Account::syncConfig()
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
s->setValue( "accountfriendlyname", m_accountFriendlyName );
|
||||
s->setValue( "enabled", m_enabled );
|
||||
s->setValue( "credentials", m_credentials );
|
||||
s->setValue( "configuration", m_configuration );
|
||||
s->setValue( "acl", m_acl );
|
||||
s->setValue( "types", m_types );
|
||||
@@ -138,6 +184,63 @@ Account::syncConfig()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Account::syncType()
|
||||
{
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
s->setValue( "types", m_types );
|
||||
s->endGroup();
|
||||
s->sync();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Account::saveCredentials( const QVariantHash &creds )
|
||||
{
|
||||
QByteArray data;
|
||||
{
|
||||
QDataStream ds( &data, QIODevice::WriteOnly );
|
||||
ds << creds;
|
||||
}
|
||||
|
||||
QKeychain::WritePasswordJob* j = new QKeychain::WritePasswordJob( QLatin1String( "tomahawkaccounts" ), this );
|
||||
j->setKey( m_accountId );
|
||||
j->setAutoDelete( false );
|
||||
j->setBinaryData( data );
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
|
||||
j->setInsecureFallback( true );
|
||||
#endif
|
||||
connect( j, SIGNAL( finished( QKeychain::Job* ) ), this, SLOT( keychainJobFinished( QKeychain::Job* ) ) );
|
||||
j->start();
|
||||
|
||||
m_workingKeychainJobs << j;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Account::loadCredentials() const
|
||||
{
|
||||
QKeychain::ReadPasswordJob* j = new QKeychain::ReadPasswordJob( QLatin1String( "tomahawkaccounts" ), const_cast<Account*>( this ) );
|
||||
j->setKey( m_accountId );
|
||||
j->setAutoDelete( false );
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
|
||||
j->setInsecureFallback( true );
|
||||
#endif
|
||||
connect( j, SIGNAL( finished( QKeychain::Job* ) ), this, SLOT( keychainJobFinished( QKeychain::Job* ) ) );
|
||||
|
||||
|
||||
if ( !m_workingKeychainJobs.isEmpty() )
|
||||
{
|
||||
m_queuedKeychainJobs.enqueue( j );
|
||||
}
|
||||
else
|
||||
{
|
||||
j->start();
|
||||
m_workingKeychainJobs << j;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Account::loadFromConfig( const QString& accountId )
|
||||
{
|
||||
@@ -146,11 +249,12 @@ Account::loadFromConfig( const QString& accountId )
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
m_accountFriendlyName = s->value( "accountfriendlyname", QString() ).toString();
|
||||
m_enabled = s->value( "enabled", false ).toBool();
|
||||
m_credentials = s->value( "credentials", QVariantHash() ).toHash();
|
||||
m_configuration = s->value( "configuration", QVariantHash() ).toHash();
|
||||
m_acl = s->value( "acl", QVariantMap() ).toMap();
|
||||
m_types = s->value( "types", QStringList() ).toStringList();
|
||||
s->endGroup();
|
||||
|
||||
loadCredentials();
|
||||
}
|
||||
|
||||
|
||||
@@ -161,12 +265,23 @@ Account::removeFromConfig()
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
s->remove( "accountfriendlyname" );
|
||||
s->remove( "enabled" );
|
||||
s->remove( "credentials" );
|
||||
//s->remove( "credentials" );
|
||||
s->remove( "configuration" );
|
||||
s->remove( "acl" );
|
||||
s->remove( "types" );
|
||||
s->endGroup();
|
||||
s->remove( "accounts/" + m_accountId );
|
||||
|
||||
QKeychain::DeletePasswordJob* j = new QKeychain::DeletePasswordJob( QLatin1String( "tomahawk" ), this );
|
||||
j->setKey( m_accountId );
|
||||
j->setAutoDelete( false );
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
|
||||
j->setInsecureFallback( true );
|
||||
#endif
|
||||
connect( j, SIGNAL( finished( QKeychain::Job* ) ), this, SLOT( keychainJobFinished( QKeychain::Job* ) ) );
|
||||
j->start();
|
||||
|
||||
m_workingKeychainJobs << j;
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +298,8 @@ Account::setTypes( AccountTypes types )
|
||||
m_types << "ResolverType";
|
||||
if ( types & StatusPushType )
|
||||
m_types << "StatusPushType";
|
||||
syncConfig();
|
||||
//syncConfig();
|
||||
syncType();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -20,12 +20,13 @@
|
||||
#ifndef ACCOUNT_H
|
||||
#define ACCOUNT_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QVariantMap>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUuid>
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
#include <QWidget>
|
||||
#include <QIcon>
|
||||
#include <QString>
|
||||
#include <QUuid>
|
||||
#include <QQueue>
|
||||
#include <QMutex>
|
||||
|
||||
#include "Typedefs.h"
|
||||
@@ -35,6 +36,11 @@
|
||||
|
||||
class SipPlugin;
|
||||
|
||||
namespace QKeychain
|
||||
{
|
||||
class Job;
|
||||
}
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
@@ -79,6 +85,13 @@ public:
|
||||
|
||||
QVariantHash configuration() const { QMutexLocker locker( &m_mutex ); return m_configuration; }
|
||||
|
||||
// Starts the asynchronous loading of the credentials.
|
||||
// Will emit credentialsChanged() when they are successfully loaded
|
||||
void loadCredentials() const;
|
||||
|
||||
// Asynchronously save credentials to storage
|
||||
void saveCredentials( const QVariantHash& credentials );
|
||||
|
||||
/**
|
||||
* Configuration widgets can have a "dataError( bool )" signal to enable/disable the OK button in their wrapper dialogs.
|
||||
*/
|
||||
@@ -87,8 +100,6 @@ public:
|
||||
|
||||
virtual void saveConfig() {} // called when the widget has been edited. save values from config widget, call sync() to write to disk account generic settings
|
||||
|
||||
QVariantHash credentials() const { QMutexLocker locker( &m_mutex ); return m_credentials; }
|
||||
|
||||
QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; }
|
||||
virtual QWidget* aclWidget() = 0;
|
||||
|
||||
@@ -112,12 +123,11 @@ public:
|
||||
void setAccountFriendlyName( const QString &friendlyName ) { QMutexLocker locker( &m_mutex ); m_accountFriendlyName = friendlyName; }
|
||||
void setEnabled( bool enabled ) { QMutexLocker locker( &m_mutex ); m_enabled = enabled; }
|
||||
void setAccountId( const QString &accountId ) { QMutexLocker locker( &m_mutex ); m_accountId = accountId; }
|
||||
void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; }
|
||||
void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; }
|
||||
void setAcl( const QVariantMap &acl ) { QMutexLocker locker( &m_mutex ); m_acl = acl; }
|
||||
void setTypes( AccountTypes types );
|
||||
|
||||
void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); };
|
||||
void sync() { QMutexLocker locker( &m_mutex ); syncConfig(); }
|
||||
|
||||
/**
|
||||
* Removes all the settings held in the config file for this account instance
|
||||
@@ -136,24 +146,32 @@ signals:
|
||||
|
||||
void configurationChanged();
|
||||
|
||||
void credentialsLoaded( const QVariantHash& credentials );
|
||||
|
||||
protected:
|
||||
virtual void loadFromConfig( const QString &accountId );
|
||||
virtual void syncConfig();
|
||||
virtual void syncType();
|
||||
|
||||
private slots:
|
||||
void onConnectionStateChanged( Tomahawk::Accounts::Account::ConnectionState );
|
||||
void onError( int, const QString& );
|
||||
|
||||
void keychainJobFinished( QKeychain::Job* );
|
||||
|
||||
private:
|
||||
QString m_accountServiceName;
|
||||
QString m_accountFriendlyName;
|
||||
QString m_cachedError;
|
||||
bool m_enabled;
|
||||
QString m_accountId;
|
||||
QVariantHash m_credentials;
|
||||
QVariantHash m_configuration;
|
||||
QVariantMap m_acl;
|
||||
QStringList m_types;
|
||||
|
||||
mutable QList< QKeychain::Job* > m_workingKeychainJobs;
|
||||
mutable QQueue< QKeychain::Job* > m_queuedKeychainJobs;
|
||||
|
||||
mutable QMutex m_mutex;
|
||||
};
|
||||
|
||||
|
@@ -416,6 +416,9 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
|
||||
if ( role == CheckboxClickedRole )
|
||||
{
|
||||
Account* acct = 0;
|
||||
|
||||
Qt::CheckState checkState = static_cast< Qt::CheckState >( value.toInt() );
|
||||
|
||||
switch ( node->type )
|
||||
{
|
||||
case AccountModelNode::UniqueFactoryType:
|
||||
@@ -453,9 +456,11 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
|
||||
state = AtticaManager::Uninstalled;
|
||||
}
|
||||
|
||||
if ( state == AtticaManager::Installed )
|
||||
// Don't install if we're unchecking. This happens if e.g. the user deletes his config file
|
||||
// and opens tomahawk
|
||||
if ( state == AtticaManager::Installed || checkState == Qt::Unchecked )
|
||||
{
|
||||
qDebug() << "Already installed with resolver, just enabling";
|
||||
qDebug() << "Already installed with resolver, or unchecking, just enabling/disabling";
|
||||
acct = node->atticaAccount;
|
||||
break;
|
||||
}
|
||||
@@ -491,13 +496,10 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
|
||||
|
||||
if ( node->type == AccountModelNode::FactoryType )
|
||||
{
|
||||
// Turn on or off all accounts for this factory
|
||||
|
||||
Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
|
||||
|
||||
// Turn on or off all accounts for this factory\
|
||||
foreach ( Account* acct, node->accounts )
|
||||
{
|
||||
state == Qt::Checked ? AccountManager::instance()->enableAccount( acct )
|
||||
checkState == Qt::Checked ? AccountManager::instance()->enableAccount( acct )
|
||||
: AccountManager::instance()->disableAccount( acct );
|
||||
}
|
||||
|
||||
|
@@ -55,6 +55,8 @@ LastFmAccountFactory::icon() const
|
||||
LastFmAccount::LastFmAccount( const QString& accountId )
|
||||
: CustomAtticaAccount( accountId )
|
||||
{
|
||||
connect( this, SIGNAL( credentialsLoaded( QVariantHash ) ), this, SLOT( onCredentialsLoaded( QVariantHash ) ) );
|
||||
|
||||
setAccountFriendlyName( "Last.Fm" );
|
||||
m_icon.load( RESPATH "images/lastfm-icon.png" );
|
||||
|
||||
@@ -152,7 +154,7 @@ LastFmAccount::configurationWidget()
|
||||
Account::ConnectionState
|
||||
LastFmAccount::connectionState() const
|
||||
{
|
||||
return (!m_resolver.isNull() && m_resolver.data()->running()) ? Account::Connected : Account::Disconnected;
|
||||
return ( !m_resolver.isNull() && m_resolver.data()->running() ) ? Account::Connected : Account::Disconnected;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,57 +191,66 @@ LastFmAccount::saveConfig()
|
||||
setScrobble( m_configWidget.data()->scrobble() );
|
||||
}
|
||||
|
||||
sync();
|
||||
saveCredentials( m_credentials );
|
||||
}
|
||||
|
||||
if ( m_infoPlugin )
|
||||
QTimer::singleShot( 0, m_infoPlugin.data(), SLOT( settingsChanged() ) );
|
||||
|
||||
void
|
||||
LastFmAccount::onCredentialsLoaded(const QVariantHash &credentials)
|
||||
{
|
||||
m_credentials = credentials;
|
||||
if ( !m_infoPlugin.isNull() )
|
||||
m_infoPlugin.data()->settingsChanged();
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
LastFmAccount::password() const
|
||||
{
|
||||
return credentials().value( "password" ).toString();
|
||||
return m_credentials.value( "password" ).toString();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmAccount::setPassword( const QString& password )
|
||||
LastFmAccount::setPassword( const QString& password, bool immediate )
|
||||
{
|
||||
QVariantHash creds = credentials();
|
||||
creds[ "password" ] = password;
|
||||
setCredentials( creds );
|
||||
m_credentials[ "password" ] = password;
|
||||
|
||||
if ( immediate )
|
||||
saveCredentials( m_credentials );
|
||||
}
|
||||
|
||||
QString
|
||||
LastFmAccount::sessionKey() const
|
||||
{
|
||||
return credentials().value( "sessionkey" ).toString();
|
||||
return m_credentials.value( "sessionkey" ).toString();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmAccount::setSessionKey( const QString& sessionkey )
|
||||
LastFmAccount::setSessionKey( const QString& sessionkey, bool immediate )
|
||||
{
|
||||
QVariantHash creds = credentials();
|
||||
creds[ "sessionkey" ] = sessionkey;
|
||||
setCredentials( creds );
|
||||
m_credentials[ "sessionkey" ] = sessionkey;
|
||||
|
||||
if ( immediate )
|
||||
saveCredentials( m_credentials );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
LastFmAccount::username() const
|
||||
{
|
||||
return credentials().value( "username" ).toString();
|
||||
return m_credentials.value( "username" ).toString();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmAccount::setUsername( const QString& username )
|
||||
LastFmAccount::setUsername( const QString& username, bool immediate )
|
||||
{
|
||||
QVariantHash creds = credentials();
|
||||
creds[ "username" ] = username;
|
||||
setCredentials( creds );
|
||||
m_credentials[ "username" ] = username;
|
||||
|
||||
if ( immediate )
|
||||
saveCredentials( m_credentials );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -84,11 +84,11 @@ public:
|
||||
virtual void saveConfig();
|
||||
|
||||
QString username() const;
|
||||
void setUsername( const QString& );
|
||||
void setUsername( const QString&, bool immediate = false );
|
||||
QString password() const;
|
||||
void setPassword( const QString& );
|
||||
void setPassword( const QString&, bool immediate = false );
|
||||
QString sessionKey() const;
|
||||
void setSessionKey( const QString& );
|
||||
void setSessionKey( const QString&, bool immediate = false );
|
||||
bool scrobble() const;
|
||||
void setScrobble( bool scrobble );
|
||||
|
||||
@@ -100,12 +100,18 @@ private slots:
|
||||
void resolverInstalled( const QString& resolverId );
|
||||
|
||||
void resolverChanged();
|
||||
|
||||
void onCredentialsLoaded( const QVariantHash& credentials );
|
||||
|
||||
private:
|
||||
void hookupResolver();
|
||||
|
||||
QWeakPointer<Tomahawk::ExternalResolverGui> m_resolver;
|
||||
QWeakPointer<Tomahawk::InfoSystem::LastFmInfoPlugin> m_infoPlugin;
|
||||
QWeakPointer<LastFmConfig> m_configWidget;
|
||||
|
||||
QVariantHash m_credentials;
|
||||
|
||||
QPixmap m_icon;
|
||||
};
|
||||
|
||||
|
@@ -40,14 +40,10 @@ LastFmConfig::LastFmConfig( LastFmAccount* account )
|
||||
m_ui = new Ui_LastFmConfig;
|
||||
m_ui->setupUi( this );
|
||||
|
||||
m_ui->progressBar->hide();
|
||||
connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), this, SLOT( testLogin() ) );
|
||||
|
||||
m_ui->username->setText( m_account->username() );
|
||||
m_ui->password->setText( m_account->password() );
|
||||
m_ui->enable->setChecked( m_account->scrobble() );
|
||||
|
||||
connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), SLOT( testLogin() ) );
|
||||
connect( m_ui->importHistory, SIGNAL( clicked( bool ) ), SLOT( loadHistory() ) );
|
||||
connect( m_ui->username, SIGNAL( textChanged( QString ) ), this, SLOT( enableButton() ) );
|
||||
connect( m_ui->password, SIGNAL( textChanged( QString ) ), this, SLOT( enableButton() ) );
|
||||
|
||||
connect( m_ui->username, SIGNAL( textChanged( QString ) ), SLOT( enableButton() ) );
|
||||
connect( m_ui->password, SIGNAL( textChanged( QString ) ), SLOT( enableButton() ) );
|
||||
@@ -68,6 +64,15 @@ LastFmConfig::scrobble() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmConfig::loadFromConfig()
|
||||
{
|
||||
m_ui->username->setText( m_account->username() );
|
||||
m_ui->password->setText( m_account->password() );
|
||||
m_ui->enable->setChecked( m_account->scrobble() );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
LastFmConfig::username() const
|
||||
{
|
||||
@@ -232,3 +237,10 @@ LastFmConfig::onLastFmFinished()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmConfig::showEvent(QShowEvent* event)
|
||||
{
|
||||
loadFromConfig();
|
||||
}
|
||||
|
@@ -38,10 +38,15 @@ public:
|
||||
QString username() const;
|
||||
QString password() const;
|
||||
bool scrobble() const;
|
||||
|
||||
void loadFromConfig();
|
||||
|
||||
public slots:
|
||||
void testLogin();
|
||||
void onLastFmFinished();
|
||||
|
||||
protected:
|
||||
void showEvent( QShowEvent* event );
|
||||
|
||||
private slots:
|
||||
void enableButton();
|
||||
|
@@ -853,7 +853,7 @@ LastFmInfoPlugin::settingsChanged()
|
||||
m_scrobbler = 0;
|
||||
}
|
||||
|
||||
m_account.data()->setSessionKey( QString() );
|
||||
m_account.data()->setSessionKey( QString(), true );
|
||||
createScrobbler();
|
||||
}
|
||||
}
|
||||
@@ -876,13 +876,13 @@ LastFmInfoPlugin::onAuthenticated()
|
||||
if ( lfm.children( "error" ).size() > 0 )
|
||||
{
|
||||
tLog() << "Error from authenticating with Last.fm service:" << lfm.text();
|
||||
m_account.data()->setSessionKey( QByteArray() );
|
||||
m_account.data()->setSessionKey( QString(), true );
|
||||
}
|
||||
else
|
||||
{
|
||||
lastfm::ws::SessionKey = lfm[ "session" ][ "key" ].text();
|
||||
|
||||
m_account.data()->setSessionKey( lastfm::ws::SessionKey.toLatin1() );
|
||||
m_account.data()->setSessionKey( lastfm::ws::SessionKey, true );
|
||||
|
||||
// qDebug() << "Got session key from last.fm";
|
||||
if ( m_account.data()->scrobble() )
|
||||
|
@@ -100,6 +100,8 @@ SpotifyAccount::~SpotifyAccount()
|
||||
void
|
||||
SpotifyAccount::init()
|
||||
{
|
||||
connect( this, SIGNAL( credentialsLoaded( QVariantHash ) ), this, SLOT( onCredentialsLoaded( QVariantHash ) ) );
|
||||
|
||||
setAccountFriendlyName( "Spotify" );
|
||||
setAccountServiceName( "spotify" );
|
||||
|
||||
@@ -182,6 +184,22 @@ SpotifyAccount::hookupResolver()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SpotifyAccount::onCredentialsLoaded( const QVariantHash &credentials )
|
||||
{
|
||||
m_credentials = credentials;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SpotifyAccount::setCredentials(const QVariantHash &creds)
|
||||
{
|
||||
m_credentials = creds;
|
||||
|
||||
saveCredentials( creds );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SpotifyAccount::checkForResolver()
|
||||
{
|
||||
@@ -455,14 +473,12 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
|
||||
{
|
||||
if ( msgType == "credentials" )
|
||||
{
|
||||
QVariantHash creds = credentials();
|
||||
m_credentials[ "username" ] = msg.value( "username" );
|
||||
m_credentials[ "password" ] = msg.value( "password" );
|
||||
m_credentials[ "highQuality" ] = msg.value( "highQuality" );
|
||||
saveCredentials( m_credentials );
|
||||
|
||||
creds[ "username" ] = msg.value( "username" );
|
||||
creds[ "password" ] = msg.value( "password" );
|
||||
creds[ "highQuality" ] = msg.value( "highQuality" );
|
||||
setCredentials( creds );
|
||||
|
||||
qDebug() << "Set creds:" << creds.value( "username" ) << creds.value( "password" ) << msg.value( "username" ) << msg.value( "password" );
|
||||
qDebug() << "Set creds:" << m_credentials.value( "username" ) << m_credentials.value( "password" ) << msg.value( "username" ) << msg.value( "password" );
|
||||
|
||||
QVariantHash config = configuration();
|
||||
config[ "hasMigrated" ] = true;
|
||||
@@ -613,12 +629,10 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
|
||||
}
|
||||
else if ( msgType == "loginResponse" )
|
||||
{
|
||||
QVariantHash creds = credentials();
|
||||
creds[ "username" ] = msg.value( "username" ).toString();
|
||||
creds[ "password" ] = msg.value( "password" ).toString();
|
||||
creds[ "highQuality" ] = msg.value( "highQuality" ).toString();
|
||||
setCredentials( creds );
|
||||
sync();
|
||||
m_credentials[ "username" ] = msg.value( "username" ).toString();
|
||||
m_credentials[ "password" ] = msg.value( "password" ).toString();
|
||||
m_credentials[ "highQuality" ] = msg.value( "highQuality" ).toString();
|
||||
saveCredentials( m_credentials );
|
||||
|
||||
const bool success = msg.value( "success" ).toBool();
|
||||
|
||||
@@ -725,15 +739,14 @@ SpotifyAccount::saveConfig()
|
||||
if ( m_configWidget.isNull() )
|
||||
return;
|
||||
|
||||
QVariantHash creds = credentials();
|
||||
if ( creds.value( "username" ).toString() != m_configWidget.data()->username() ||
|
||||
creds.value( "password" ).toString() != m_configWidget.data()->password() ||
|
||||
creds.value( "highQuality" ).toBool() != m_configWidget.data()->highQuality() )
|
||||
if ( m_credentials.value( "username" ).toString() != m_configWidget.data()->username() ||
|
||||
m_credentials.value( "password" ).toString() != m_configWidget.data()->password() ||
|
||||
m_credentials.value( "highQuality" ).toBool() != m_configWidget.data()->highQuality() )
|
||||
{
|
||||
creds[ "username" ] = m_configWidget.data()->username();
|
||||
creds[ "password" ] = m_configWidget.data()->password();
|
||||
creds[ "highQuality" ] = m_configWidget.data()->highQuality();
|
||||
setCredentials( creds );
|
||||
m_credentials[ "username" ] = m_configWidget.data()->username();
|
||||
m_credentials[ "password" ] = m_configWidget.data()->password();
|
||||
m_credentials[ "highQuality" ] = m_configWidget.data()->highQuality();
|
||||
saveCredentials( m_credentials );
|
||||
|
||||
}
|
||||
|
||||
|
@@ -102,12 +102,17 @@ public:
|
||||
|
||||
void setManualResolverPath( const QString& resolverPath );
|
||||
|
||||
QVariantHash credentials() const { return m_credentials; }
|
||||
void setCredentials( const QVariantHash& creds );
|
||||
|
||||
public slots:
|
||||
void aboutToShow( QAction* action, const Tomahawk::playlist_ptr& playlist );
|
||||
void syncActionTriggered( bool );
|
||||
void atticaLoaded(Attica::Content::List);
|
||||
|
||||
private slots:
|
||||
void onCredentialsLoaded( const QVariantHash& credentials );
|
||||
|
||||
void resolverChanged();
|
||||
void resolverInstalled( const QString& resolverId );
|
||||
|
||||
@@ -143,6 +148,8 @@ private:
|
||||
QWeakPointer<QWidget> m_aboutWidget;
|
||||
QWeakPointer<ScriptResolver> m_spotifyResolver;
|
||||
|
||||
QVariantHash m_credentials;
|
||||
|
||||
QMap<QString, QPair<QObject*, QString> > m_qidToSlotMap;
|
||||
|
||||
// List of synced spotify playlists in config UI
|
||||
|
@@ -34,6 +34,7 @@ SipPlugin::SipPlugin( Tomahawk::Accounts::Account *account, QObject* parent )
|
||||
{
|
||||
connect( this, SIGNAL( peerOnline( QString ) ), this, SLOT( onPeerOnline( QString ) ) );
|
||||
connect( this, SIGNAL( peerOffline( QString ) ), this, SLOT( onPeerOffline( QString ) ) );
|
||||
connect( m_account, SIGNAL( credentialsChanged( ) ), this, SLOT( configurationChanged( ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -261,7 +261,18 @@ Api_v1::resolve( QxtWebRequestEvent* event )
|
||||
else
|
||||
qid = uuid();
|
||||
|
||||
query_ptr qry = Query::get( QUrl::fromPercentEncoding( event->url.queryItemValue( "artist" ).toUtf8() ), QUrl::fromPercentEncoding( event->url.queryItemValue( "track" ).toUtf8() ), QUrl::fromPercentEncoding( event->url.queryItemValue( "album" ).toUtf8() ), qid, false );
|
||||
const QString track = event->url.queryItemValue( "track" );
|
||||
const QString artist = event->url.queryItemValue( "artist" );
|
||||
const QString album = event->url.queryItemValue( "album" );
|
||||
|
||||
if ( track.isEmpty() && artist.isEmpty() )
|
||||
{
|
||||
qDebug() << "HTTP API asked to resolve empty track/artist!";
|
||||
send404( event );
|
||||
return;
|
||||
}
|
||||
|
||||
query_ptr qry = Query::get( QUrl::fromPercentEncoding( artist.toUtf8() ), QUrl::fromPercentEncoding( track.toUtf8() ), QUrl::fromPercentEncoding( album.toUtf8() ), qid, false );
|
||||
Pipeline::instance()->resolve( qry, true, true );
|
||||
|
||||
QVariantMap r;
|
||||
|
105
thirdparty/qtkeychain/qtkeychain/CMakeLists.txt
vendored
Normal file
105
thirdparty/qtkeychain/qtkeychain/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(qtkeychain)
|
||||
|
||||
###
|
||||
|
||||
set(QTKEYCHAIN_VERSION 0)
|
||||
set(QTKEYCHAIN_SOVERSION 0)
|
||||
|
||||
###
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/cmake/Modules")
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Qt4 COMPONENTS QtCore QtDBus REQUIRED)
|
||||
else()
|
||||
find_package(Qt4 COMPONENTS QtCore REQUIRED)
|
||||
endif()
|
||||
|
||||
include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
list(APPEND qtkeychain_LIBRARIES ${QT_QTCORE_LIBRARY})
|
||||
set(qtkeychain_SOURCES
|
||||
keychain.cpp
|
||||
)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND qtkeychain_SOURCES keychain_win.cpp)
|
||||
list(APPEND qtkeychain_LIBRARIES crypt32)
|
||||
#FIXME: mingw bug; otherwise getting undefined refs to RtlSecureZeroMemory there
|
||||
if(MINGW)
|
||||
add_definitions( -O2 )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND qtkeychain_SOURCES keychain_mac.cpp)
|
||||
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
list(APPEND qtkeychain_LIBRARIES ${COREFOUNDATION_LIBRARY})
|
||||
|
||||
find_library(SECURITY_LIBRARY Security)
|
||||
list(APPEND qtkeychain_LIBRARIES ${SECURITY_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
list(APPEND qtkeychain_SOURCES keychain_dbus.cpp)
|
||||
qt4_add_dbus_interface(qtkeychain_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.KWallet.xml kwallet_interface KWalletInterface)
|
||||
list(APPEND qtkeychain_LIBRARIES ${QT_QTDBUS_LIBRARY})
|
||||
endif()
|
||||
|
||||
QT4_WRAP_CPP(qtkeychain_MOC_OUTFILES keychain.h keychain_p.h)
|
||||
|
||||
if(NOT QTKEYCHAIN_STATIC)
|
||||
add_library(qtkeychain SHARED ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES})
|
||||
set_target_properties(qtkeychain PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_BUILD_QKEYCHAIN_LIB)
|
||||
target_link_libraries(qtkeychain ${qtkeychain_LIBRARIES})
|
||||
else()
|
||||
add_library(qtkeychain STATIC ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES})
|
||||
set_target_properties(qtkeychain PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_STATICLIB)
|
||||
endif()
|
||||
|
||||
set_target_properties(qtkeychain PROPERTIES
|
||||
VERSION ${QTKEYCHAIN_VERSION}
|
||||
SOVERSION ${QTKEYCHAIN_SOVERSION}
|
||||
)
|
||||
|
||||
#install(FILES keychain.h qkeychain_export.h
|
||||
# DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/qtkeychain/
|
||||
#)
|
||||
|
||||
#install(TARGETS qtkeychain
|
||||
# EXPORT QtKeychainLibraryDepends
|
||||
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
#)
|
||||
|
||||
#add_executable( testclient testclient.cpp )
|
||||
#target_link_libraries( testclient qtkeychain)
|
||||
|
||||
|
||||
###
|
||||
### CMake config file
|
||||
###
|
||||
|
||||
export(TARGETS qtkeychain FILE "${PROJECT_BINARY_DIR}/QtKeychainLibraryDepends.cmake")
|
||||
export(PACKAGE QtKeychain)
|
||||
|
||||
configure_file(QtKeychainBuildTreeSettings.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/QtKeychainBuildTreeSettings.cmake" @ONLY)
|
||||
configure_file(QtKeychainConfig.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/QtKeychainConfig.cmake" @ONLY)
|
||||
configure_file(QtKeychainConfigVersion.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/QtKeychainConfigVersion.cmake" @ONLY)
|
||||
|
||||
#install(EXPORT QtKeychainLibraryDepends
|
||||
# DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/QtKeychain"
|
||||
#)
|
||||
|
||||
#install(FILES ${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfig.cmake
|
||||
# ${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfigVersion.cmake
|
||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QtKeychain
|
||||
#)
|
20
thirdparty/qtkeychain/qtkeychain/COPYING
vendored
Normal file
20
thirdparty/qtkeychain/qtkeychain/COPYING
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
4
thirdparty/qtkeychain/qtkeychain/QtKeychainBuildTreeSettings.cmake.in
vendored
Normal file
4
thirdparty/qtkeychain/qtkeychain/QtKeychainBuildTreeSettings.cmake.in
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
set(QTKEYCHAIN_INCLUDE_DIRS
|
||||
"@PROJECT_SOURCE_DIR@"
|
||||
"@PROJECT_BINARY_DIR@"
|
||||
)
|
20
thirdparty/qtkeychain/qtkeychain/QtKeychainConfig.cmake.in
vendored
Normal file
20
thirdparty/qtkeychain/qtkeychain/QtKeychainConfig.cmake.in
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# - Config file for the FooBar package
|
||||
# It defines the following variables
|
||||
# FOOBAR_INCLUDE_DIRS - include directories for FooBar
|
||||
# FOOBAR_LIBRARIES - libraries to link against
|
||||
# FOOBAR_EXECUTABLE - the bar executable
|
||||
|
||||
# Compute paths
|
||||
get_filename_component(QTKEYCHAIN_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
if(EXISTS "${QTKEYCHAIN_CMAKE_DIR}/CMakeCache.txt")
|
||||
# In build tree
|
||||
include("${QTKEYCHAIN_CMAKE_DIR}/QtKeychainBuildTreeSettings.cmake")
|
||||
else()
|
||||
set(QTKEYCHAIN_INCLUDE_DIRS "${QTKEYCHAIN_CMAKE_DIR}/../../")
|
||||
endif()
|
||||
|
||||
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||
include("${QTKEYCHAIN_CMAKE_DIR}/QtKeychainLibraryDepends.cmake")
|
||||
|
||||
# These are IMPORTED targets created by FooBarLibraryDepends.cmake
|
||||
set(QTKEYCHAIN_LIBRARIES qtkeychain)
|
11
thirdparty/qtkeychain/qtkeychain/QtKeychainConfigVersion.cmake.in
vendored
Normal file
11
thirdparty/qtkeychain/qtkeychain/QtKeychainConfigVersion.cmake.in
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
set(PACKAGE_VERSION "@QTKEYCHAIN_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
1
thirdparty/qtkeychain/qtkeychain/ReadMe.markdown
vendored
Symbolic link
1
thirdparty/qtkeychain/qtkeychain/ReadMe.markdown
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
ReadMe.txt
|
16
thirdparty/qtkeychain/qtkeychain/ReadMe.txt
vendored
Normal file
16
thirdparty/qtkeychain/qtkeychain/ReadMe.txt
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
QtKeychain
|
||||
==========
|
||||
|
||||
QtKeychain is a Qt API to store passwords and other secret data securely. How the data is stored depends on the platform:
|
||||
|
||||
* **Mac OS X:** Passwords are stored in the OS X Keychain.
|
||||
|
||||
* **Linux/Unix:** If running, KWallet (via D-Bus) is used.
|
||||
Support for the GNOME Keyring via freedesktop.org's
|
||||
[Secret Storage D-Bus specification](http://freedesktop.org/wiki/Specifications/secret-storage-spec "Secret Storage specification") is planned but not yet implemented.
|
||||
|
||||
* **Windows:** Windows does not provide a service for secure storage. QtKeychain uses the Windows API function [CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function") to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings.
|
||||
|
||||
In unsupported environments QtKeychain will report an error. It will never store any data unencrypted.
|
||||
|
||||
**License:** QtKeychain is available under the [Modified BSD License](http://www.gnu.org/licenses/license-list.html#ModifiedBSD). See the file COPYING for details.
|
188
thirdparty/qtkeychain/qtkeychain/cmake/Modules/GNUInstallDirs.cmake
vendored
Normal file
188
thirdparty/qtkeychain/qtkeychain/cmake/Modules/GNUInstallDirs.cmake
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
# - Define GNU standard installation directories
|
||||
# Provides install directory variables as defined for GNU software:
|
||||
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
# Inclusion of this module defines the following variables:
|
||||
# CMAKE_INSTALL_<dir> - destination for files of a given type
|
||||
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
|
||||
# where <dir> is one of:
|
||||
# BINDIR - user executables (bin)
|
||||
# SBINDIR - system admin executables (sbin)
|
||||
# LIBEXECDIR - program executables (libexec)
|
||||
# SYSCONFDIR - read-only single-machine data (etc)
|
||||
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
|
||||
# LOCALSTATEDIR - modifiable single-machine data (var)
|
||||
# LIBDIR - object code libraries (lib or lib64 or lib/<multiarch-tuple> on Debian)
|
||||
# INCLUDEDIR - C header files (include)
|
||||
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
|
||||
# DATAROOTDIR - read-only architecture-independent data root (share)
|
||||
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
|
||||
# INFODIR - info documentation (DATAROOTDIR/info)
|
||||
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
|
||||
# MANDIR - man documentation (DATAROOTDIR/man)
|
||||
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
|
||||
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
|
||||
# install() commands for the corresponding file type. If the includer does
|
||||
# not define a value the above-shown default will be used and the value will
|
||||
# appear in the cache for editing by the user.
|
||||
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
|
||||
# from the corresponding destination by prepending (if necessary) the value
|
||||
# of CMAKE_INSTALL_PREFIX.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
|
||||
# Copyright 2011 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Installation directories
|
||||
#
|
||||
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
|
||||
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
|
||||
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
|
||||
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
|
||||
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
|
||||
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(_LIBDIR_DEFAULT "lib")
|
||||
# Override this default 'lib' with 'lib64' iff:
|
||||
# - we are on Linux system but NOT cross-compiling
|
||||
# - we are NOT on debian
|
||||
# - we are on a 64 bits system
|
||||
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
|
||||
# For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
|
||||
# CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
|
||||
# See http://wiki.debian.org/Multiarch
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
|
||||
AND NOT CMAKE_CROSSCOMPILING)
|
||||
if (EXISTS "/etc/debian_version") # is this a debian system ?
|
||||
if(CMAKE_LIBRARY_ARCHITECTURE)
|
||||
set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
|
||||
endif()
|
||||
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
|
||||
message(AUTHOR_WARNING
|
||||
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
|
||||
"Please enable at least one language before including GNUInstallDirs.")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(_LIBDIR_DEFAULT "lib64")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
|
||||
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
|
||||
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
|
||||
# the cache and store the defaults in local variables if the cache values are
|
||||
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
|
||||
|
||||
if(NOT CMAKE_INSTALL_DATADIR)
|
||||
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
|
||||
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_INFODIR)
|
||||
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
|
||||
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_LOCALEDIR)
|
||||
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
|
||||
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_MANDIR)
|
||||
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
|
||||
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_DOCDIR)
|
||||
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
|
||||
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
mark_as_advanced(
|
||||
CMAKE_INSTALL_BINDIR
|
||||
CMAKE_INSTALL_SBINDIR
|
||||
CMAKE_INSTALL_LIBEXECDIR
|
||||
CMAKE_INSTALL_SYSCONFDIR
|
||||
CMAKE_INSTALL_SHAREDSTATEDIR
|
||||
CMAKE_INSTALL_LOCALSTATEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_OLDINCLUDEDIR
|
||||
CMAKE_INSTALL_DATAROOTDIR
|
||||
CMAKE_INSTALL_DATADIR
|
||||
CMAKE_INSTALL_INFODIR
|
||||
CMAKE_INSTALL_LOCALEDIR
|
||||
CMAKE_INSTALL_MANDIR
|
||||
CMAKE_INSTALL_DOCDIR
|
||||
)
|
||||
|
||||
# Result directories
|
||||
#
|
||||
foreach(dir
|
||||
BINDIR
|
||||
SBINDIR
|
||||
LIBEXECDIR
|
||||
SYSCONFDIR
|
||||
SHAREDSTATEDIR
|
||||
LOCALSTATEDIR
|
||||
LIBDIR
|
||||
INCLUDEDIR
|
||||
OLDINCLUDEDIR
|
||||
DATAROOTDIR
|
||||
DATADIR
|
||||
INFODIR
|
||||
LOCALEDIR
|
||||
MANDIR
|
||||
DOCDIR
|
||||
)
|
||||
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
|
||||
endif()
|
||||
endforeach()
|
173
thirdparty/qtkeychain/qtkeychain/keychain.cpp
vendored
Normal file
173
thirdparty/qtkeychain/qtkeychain/keychain.cpp
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain.h"
|
||||
#include "keychain_p.h"
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
Job::Job( const QString& service, QObject *parent )
|
||||
: QObject( parent )
|
||||
, d ( new Private( service ) ) {
|
||||
}
|
||||
|
||||
Job::~Job() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString Job::service() const {
|
||||
return d->service;
|
||||
}
|
||||
|
||||
QSettings* Job::settings() const {
|
||||
return d->settings;
|
||||
}
|
||||
|
||||
void Job::setSettings( QSettings* settings ) {
|
||||
d->settings = settings;
|
||||
}
|
||||
|
||||
void Job::start() {
|
||||
QMetaObject::invokeMethod( this, "doStart", Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
bool Job::autoDelete() const {
|
||||
return d->autoDelete;
|
||||
}
|
||||
|
||||
void Job::setAutoDelete( bool autoDelete ) {
|
||||
d->autoDelete = autoDelete;
|
||||
}
|
||||
|
||||
bool Job::insecureFallback() const {
|
||||
return d->insecureFallback;
|
||||
}
|
||||
|
||||
void Job::setInsecureFallback( bool insecureFallback ) {
|
||||
d->insecureFallback = insecureFallback;
|
||||
}
|
||||
|
||||
void Job::emitFinished() {
|
||||
emit finished( this );
|
||||
if ( d->autoDelete )
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void Job::emitFinishedWithError( Error error, const QString& errorString ) {
|
||||
d->error = error;
|
||||
d->errorString = errorString;
|
||||
emitFinished();
|
||||
}
|
||||
|
||||
Error Job::error() const {
|
||||
return d->error;
|
||||
}
|
||||
|
||||
QString Job::errorString() const {
|
||||
return d->errorString;
|
||||
}
|
||||
|
||||
void Job::setError( Error error ) {
|
||||
d->error = error;
|
||||
}
|
||||
|
||||
void Job::setErrorString( const QString& errorString ) {
|
||||
d->errorString = errorString;
|
||||
}
|
||||
|
||||
ReadPasswordJob::ReadPasswordJob( const QString& service, QObject* parent )
|
||||
: Job( service, parent )
|
||||
, d( new Private( this ) )
|
||||
{}
|
||||
|
||||
ReadPasswordJob::~ReadPasswordJob() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString ReadPasswordJob::textData() const {
|
||||
return QString::fromUtf8( d->data );
|
||||
}
|
||||
|
||||
QByteArray ReadPasswordJob::binaryData() const {
|
||||
return d->data;
|
||||
}
|
||||
|
||||
QString ReadPasswordJob::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
void ReadPasswordJob::setKey( const QString& key ) {
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void ReadPasswordJob::doStart() {
|
||||
d->doStart();
|
||||
}
|
||||
|
||||
WritePasswordJob::WritePasswordJob( const QString& service, QObject* parent )
|
||||
: Job( service, parent )
|
||||
, d( new Private( this ) ) {
|
||||
}
|
||||
|
||||
WritePasswordJob::~WritePasswordJob() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString WritePasswordJob::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
void WritePasswordJob::setKey( const QString& key ) {
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void WritePasswordJob::setBinaryData( const QByteArray& data ) {
|
||||
d->binaryData = data;
|
||||
d->mode = Private::Binary;
|
||||
}
|
||||
|
||||
void WritePasswordJob::setTextData( const QString& data ) {
|
||||
d->textData = data;
|
||||
d->mode = Private::Text;
|
||||
}
|
||||
|
||||
void WritePasswordJob::doStart() {
|
||||
d->doStart();
|
||||
}
|
||||
|
||||
DeletePasswordJob::DeletePasswordJob( const QString& service, QObject* parent )
|
||||
: Job( service, parent )
|
||||
, d( new Private( this ) ) {
|
||||
}
|
||||
|
||||
DeletePasswordJob::~DeletePasswordJob() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
void DeletePasswordJob::doStart() {
|
||||
//Internally, to delete a password we just execute a write job with no data set (null byte array).
|
||||
//In all current implementations, this deletes the entry so this is sufficient
|
||||
WritePasswordJob* job = new WritePasswordJob( service(), this );
|
||||
connect( job, SIGNAL(finished(QKeychain::Job*)), d, SLOT(jobFinished(QKeychain::Job*)) );
|
||||
job->setKey( d->key );
|
||||
job->start();
|
||||
}
|
||||
|
||||
QString DeletePasswordJob::key() const {
|
||||
return d->key;
|
||||
}
|
||||
|
||||
void DeletePasswordJob::setKey( const QString& key ) {
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void DeletePasswordJob::Private::jobFinished( Job* job ) {
|
||||
q->setError( job->error() );
|
||||
q->setErrorString( job->errorString() );
|
||||
q->emitFinished();
|
||||
}
|
132
thirdparty/qtkeychain/qtkeychain/keychain.h
vendored
Normal file
132
thirdparty/qtkeychain/qtkeychain/keychain.h
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#ifndef KEYCHAIN_H
|
||||
#define KEYCHAIN_H
|
||||
|
||||
#include "qkeychain_export.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
|
||||
class QSettings;
|
||||
|
||||
namespace QKeychain {
|
||||
|
||||
/**
|
||||
* Error codes
|
||||
*/
|
||||
enum Error {
|
||||
NoError=0, /**< No error occurred, operation was successful */
|
||||
EntryNotFound, /**< For the given key no data was found */
|
||||
CouldNotDeleteEntry, /**< Could not delete existing secret data */
|
||||
AccessDeniedByUser, /**< User denied access to keychain */
|
||||
AccessDenied, /**< Access denied for other reasons */
|
||||
NoBackendAvailable, /**< No platform-specific keychain service available */
|
||||
NotImplemented, /**< Not implemented on platform */
|
||||
OtherError /**< Something else went wrong (errorString() might provide details) */
|
||||
};
|
||||
|
||||
class QKEYCHAIN_EXPORT Job : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Job( const QString& service, QObject* parent=0 );
|
||||
~Job();
|
||||
|
||||
QSettings* settings() const;
|
||||
void setSettings( QSettings* settings );
|
||||
|
||||
void start();
|
||||
|
||||
QString service() const;
|
||||
|
||||
Error error() const;
|
||||
QString errorString() const;
|
||||
|
||||
bool autoDelete() const;
|
||||
void setAutoDelete( bool autoDelete );
|
||||
|
||||
bool insecureFallback() const;
|
||||
void setInsecureFallback( bool insecureFallback );
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished( QKeychain::Job* );
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE virtual void doStart() = 0;
|
||||
|
||||
void setError( Error error );
|
||||
void setErrorString( const QString& errorString );
|
||||
void emitFinished();
|
||||
void emitFinishedWithError(Error, const QString& errorString);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* const d;
|
||||
};
|
||||
|
||||
class QKEYCHAIN_EXPORT ReadPasswordJob : public Job {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ReadPasswordJob( const QString& service, QObject* parent=0 );
|
||||
~ReadPasswordJob();
|
||||
|
||||
QString key() const;
|
||||
void setKey( const QString& key );
|
||||
|
||||
QByteArray binaryData() const;
|
||||
QString textData() const;
|
||||
|
||||
protected:
|
||||
void doStart();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* const d;
|
||||
};
|
||||
|
||||
class QKEYCHAIN_EXPORT WritePasswordJob : public Job {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WritePasswordJob( const QString& service, QObject* parent=0 );
|
||||
~WritePasswordJob();
|
||||
|
||||
QString key() const;
|
||||
void setKey( const QString& key );
|
||||
|
||||
void setBinaryData( const QByteArray& data );
|
||||
void setTextData( const QString& data );
|
||||
|
||||
protected:
|
||||
void doStart();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* const d;
|
||||
};
|
||||
|
||||
class QKEYCHAIN_EXPORT DeletePasswordJob : public Job {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeletePasswordJob( const QString& service, QObject* parent=0 );
|
||||
~DeletePasswordJob();
|
||||
|
||||
QString key() const;
|
||||
void setKey( const QString& key );
|
||||
|
||||
protected:
|
||||
void doStart();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* const d;
|
||||
};
|
||||
|
||||
} // namespace QtKeychain
|
||||
|
||||
#endif
|
160
thirdparty/qtkeychain/qtkeychain/keychain_dbus.cpp
vendored
Normal file
160
thirdparty/qtkeychain/qtkeychain/keychain_dbus.cpp
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <auto_ptr.h>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
void ReadPasswordJob::Private::doStart() {
|
||||
iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this );
|
||||
const QDBusPendingReply<int> reply = iface->open( QLatin1String("kdewallet"), 0, q->service() );
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
|
||||
connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void ReadPasswordJob::Private::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
const QDBusPendingReply<int> reply = *watcher;
|
||||
if ( reply.isError() ) {
|
||||
const QDBusError err = reply.error();
|
||||
|
||||
if ( q->insecureFallback() ) {
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
|
||||
data = actual->value( key ).toByteArray();
|
||||
|
||||
q->emitFinished();
|
||||
} else {
|
||||
if ( err.type() == QDBusError::ServiceUnknown ) //KWalletd not running
|
||||
q->emitFinishedWithError( NoBackendAvailable, tr("No keychain service available") );
|
||||
else
|
||||
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
walletHandle = reply.value();
|
||||
|
||||
if ( walletHandle < 0 ) {
|
||||
q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") );
|
||||
return;
|
||||
}
|
||||
|
||||
const QDBusPendingReply<int> nextReply = iface->entryType( walletHandle, q->service(), key, q->service() );
|
||||
QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this );
|
||||
connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletEntryTypeFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void ReadPasswordJob::Private::kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
if ( watcher->isError() ) {
|
||||
const QDBusError err = watcher->error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not determine data type: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
const QDBusPendingReply<int> reply = *watcher;
|
||||
|
||||
dataType = reply.value() == 1/*Password*/ ? Text : Binary;
|
||||
|
||||
const QDBusPendingCall nextReply = dataType == Text
|
||||
? QDBusPendingCall( iface->readPassword( walletHandle, q->service(), key, q->service() ) )
|
||||
: QDBusPendingCall( iface->readEntry( walletHandle, q->service(), key, q->service() ) );
|
||||
QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this );
|
||||
connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletReadFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void ReadPasswordJob::Private::kwalletReadFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
if ( watcher->isError() ) {
|
||||
const QDBusError err = watcher->error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not read password: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dataType == Binary ) {
|
||||
QDBusPendingReply<QByteArray> reply = *watcher;
|
||||
data = reply.value();
|
||||
} else {
|
||||
QDBusPendingReply<QString> reply = *watcher;
|
||||
data = reply.value().toUtf8();
|
||||
}
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
void WritePasswordJob::Private::doStart() {
|
||||
iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this );
|
||||
const QDBusPendingReply<int> reply = iface->open( QLatin1String("kdewallet"), 0, q->service() );
|
||||
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
|
||||
connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void WritePasswordJob::Private::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
if ( reply.isError() ) {
|
||||
if ( q->insecureFallback() ) {
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
|
||||
if ( mode == Delete ) {
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
|
||||
q->emitFinished();
|
||||
return;
|
||||
}
|
||||
const QByteArray data = mode == Binary ? binaryData : textData.toUtf8();
|
||||
actual->setValue( key, data );
|
||||
actual->sync();
|
||||
|
||||
q->emitFinished();
|
||||
} else {
|
||||
const QDBusError err = reply.error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const int handle = reply.value();
|
||||
|
||||
if ( handle < 0 ) {
|
||||
q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") );
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusPendingReply<int> nextReply;
|
||||
|
||||
if ( !textData.isEmpty() )
|
||||
nextReply = iface->writePassword( handle, q->service(), key, textData, q->service() );
|
||||
else if ( !binaryData.isEmpty() )
|
||||
nextReply = iface->writeEntry( handle, q->service(), key, binaryData, q->service() );
|
||||
else
|
||||
nextReply = iface->removeEntry( handle, q->service(), key, q->service() );
|
||||
|
||||
QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this );
|
||||
connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletWriteFinished(QDBusPendingCallWatcher*)) );
|
||||
}
|
||||
|
||||
void WritePasswordJob::Private::kwalletWriteFinished( QDBusPendingCallWatcher* watcher ) {
|
||||
watcher->deleteLater();
|
||||
QDBusPendingReply<int> reply = *watcher;
|
||||
if ( reply.isError() ) {
|
||||
const QDBusError err = reply.error();
|
||||
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
q->emitFinished();
|
||||
}
|
159
thirdparty/qtkeychain/qtkeychain/keychain_mac.cpp
vendored
Normal file
159
thirdparty/qtkeychain/qtkeychain/keychain_mac.cpp
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Security/Security.h>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
template <typename T>
|
||||
struct Releaser {
|
||||
explicit Releaser( const T& v ) : value( v ) {}
|
||||
~Releaser() {
|
||||
CFRelease( value );
|
||||
}
|
||||
|
||||
const T value;
|
||||
};
|
||||
|
||||
static QString strForStatus( OSStatus os ) {
|
||||
const Releaser<CFStringRef> str( SecCopyErrorMessageString( os, 0 ) );
|
||||
const char * const buf = CFStringGetCStringPtr( str.value, kCFStringEncodingUTF8 );
|
||||
if ( !buf )
|
||||
return QString();
|
||||
return QString::fromUtf8( buf, strlen( buf ) );
|
||||
}
|
||||
|
||||
static OSStatus readPw( QByteArray* pw,
|
||||
const QString& service,
|
||||
const QString& account,
|
||||
SecKeychainItemRef* ref ) {
|
||||
Q_ASSERT( pw );
|
||||
pw->clear();
|
||||
const QByteArray serviceData = service.toUtf8();
|
||||
const QByteArray accountData = account.toUtf8();
|
||||
|
||||
void* data = 0;
|
||||
UInt32 len = 0;
|
||||
|
||||
const OSStatus ret = SecKeychainFindGenericPassword( NULL, // default keychain
|
||||
serviceData.size(),
|
||||
serviceData.constData(),
|
||||
accountData.size(),
|
||||
accountData.constData(),
|
||||
&len,
|
||||
&data,
|
||||
ref );
|
||||
if ( ret == noErr ) {
|
||||
*pw = QByteArray( reinterpret_cast<const char*>( data ), len );
|
||||
const OSStatus ret2 = SecKeychainItemFreeContent ( 0, data );
|
||||
if ( ret2 != noErr )
|
||||
qWarning() << "Could not free item content: " << strForStatus( ret2 );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ReadPasswordJob::Private::doStart()
|
||||
{
|
||||
QString errorString;
|
||||
Error error = NoError;
|
||||
const OSStatus ret = readPw( &data, q->service(), q->key(), 0 );
|
||||
|
||||
switch ( ret ) {
|
||||
case noErr:
|
||||
break;
|
||||
case errSecItemNotFound:
|
||||
errorString = tr("Password not found");
|
||||
error = EntryNotFound;
|
||||
break;
|
||||
default:
|
||||
errorString = strForStatus( ret );
|
||||
error = OtherError;
|
||||
break;
|
||||
}
|
||||
q->emitFinishedWithError( error, errorString );
|
||||
}
|
||||
|
||||
|
||||
static QKeychain::Error deleteEntryImpl( const QString& service, const QString& account, QString* err ) {
|
||||
SecKeychainItemRef ref;
|
||||
QByteArray pw;
|
||||
const OSStatus ret1 = readPw( &pw, service, account, &ref );
|
||||
if ( ret1 == errSecItemNotFound )
|
||||
return NoError; // No item stored, we're done
|
||||
if ( ret1 != noErr ) {
|
||||
*err = strForStatus( ret1 );
|
||||
//TODO map error code, set errstr
|
||||
return OtherError;
|
||||
}
|
||||
const Releaser<SecKeychainItemRef> releaser( ref );
|
||||
|
||||
const OSStatus ret2 = SecKeychainItemDelete( ref );
|
||||
|
||||
if ( ret2 == noErr )
|
||||
return NoError;
|
||||
//TODO map error code
|
||||
*err = strForStatus( ret2 );
|
||||
return CouldNotDeleteEntry;
|
||||
}
|
||||
|
||||
static QKeychain::Error writeEntryImpl( const QString& service,
|
||||
const QString& account,
|
||||
const QByteArray& data,
|
||||
QString* err ) {
|
||||
Q_ASSERT( err );
|
||||
err->clear();
|
||||
const QByteArray serviceData = service.toUtf8();
|
||||
const QByteArray accountData = account.toUtf8();
|
||||
const OSStatus ret = SecKeychainAddGenericPassword( NULL, //default keychain
|
||||
serviceData.size(),
|
||||
serviceData.constData(),
|
||||
accountData.size(),
|
||||
accountData.constData(),
|
||||
data.size(),
|
||||
data.constData(),
|
||||
NULL //item reference
|
||||
);
|
||||
if ( ret != noErr ) {
|
||||
switch ( ret ) {
|
||||
case errSecDuplicateItem:
|
||||
{
|
||||
Error derr = deleteEntryImpl( service, account, err );
|
||||
if ( derr != NoError )
|
||||
return CouldNotDeleteEntry;
|
||||
else
|
||||
return writeEntryImpl( service, account, data, err );
|
||||
}
|
||||
default:
|
||||
*err = strForStatus( ret );
|
||||
return OtherError;
|
||||
}
|
||||
}
|
||||
|
||||
return NoError;
|
||||
}
|
||||
|
||||
void WritePasswordJob::Private::doStart()
|
||||
{
|
||||
QString errorString;
|
||||
Error error = NoError;
|
||||
|
||||
if ( mode == Delete ) {
|
||||
const Error derr = deleteEntryImpl( q->service(), key, &errorString );
|
||||
if ( derr != NoError )
|
||||
error = CouldNotDeleteEntry;
|
||||
q->emitFinishedWithError( error, errorString );
|
||||
return;
|
||||
}
|
||||
const QByteArray data = mode == Text ? textData.toUtf8() : binaryData;
|
||||
error = writeEntryImpl( q->service(), key, data, &errorString );
|
||||
q->emitFinishedWithError( error, errorString );
|
||||
}
|
122
thirdparty/qtkeychain/qtkeychain/keychain_p.h
vendored
Normal file
122
thirdparty/qtkeychain/qtkeychain/keychain_p.h
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#ifndef KEYCHAIN_P_H
|
||||
#define KEYCHAIN_P_H
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QSettings>
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_WS_MAC)
|
||||
|
||||
#include <QDBusPendingCallWatcher>
|
||||
|
||||
#include "kwallet_interface.h"
|
||||
#else
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
#endif
|
||||
|
||||
#include "keychain.h"
|
||||
|
||||
namespace QKeychain {
|
||||
|
||||
class Job::Private : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Private( const QString& service_ )
|
||||
: error( NoError )
|
||||
, service( service_ )
|
||||
, autoDelete( true )
|
||||
, insecureFallback( false ) {}
|
||||
|
||||
QKeychain::Error error;
|
||||
QString errorString;
|
||||
QString service;
|
||||
bool autoDelete;
|
||||
bool insecureFallback;
|
||||
QPointer<QSettings> settings;
|
||||
};
|
||||
|
||||
class ReadPasswordJob::Private : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Private( ReadPasswordJob* qq ) : q( qq ), walletHandle( 0 ), dataType( Text ) {}
|
||||
void doStart();
|
||||
ReadPasswordJob* const q;
|
||||
QByteArray data;
|
||||
QString key;
|
||||
int walletHandle;
|
||||
enum DataType {
|
||||
Binary,
|
||||
Text
|
||||
};
|
||||
DataType dataType;
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_WS_MAC)
|
||||
org::kde::KWallet* iface;
|
||||
|
||||
private Q_SLOTS:
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletReadFinished( QDBusPendingCallWatcher* watcher );
|
||||
#else //moc's too dumb to respect above macros, so just define empty slot implementations
|
||||
private Q_SLOTS:
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletEntryTypeFinished( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletReadFinished( QDBusPendingCallWatcher* ) {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
class WritePasswordJob::Private : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Private( WritePasswordJob* qq ) : q( qq ), mode( Delete ) {}
|
||||
void doStart();
|
||||
enum Mode {
|
||||
Delete,
|
||||
Text,
|
||||
Binary
|
||||
};
|
||||
WritePasswordJob* const q;
|
||||
Mode mode;
|
||||
QString key;
|
||||
QByteArray binaryData;
|
||||
QString textData;
|
||||
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_WS_MAC)
|
||||
org::kde::KWallet* iface;
|
||||
|
||||
private Q_SLOTS:
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
|
||||
void kwalletWriteFinished( QDBusPendingCallWatcher* watcher );
|
||||
#else
|
||||
private Q_SLOTS:
|
||||
void kwalletOpenFinished( QDBusPendingCallWatcher* ) {}
|
||||
void kwalletWriteFinished( QDBusPendingCallWatcher* ) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
class DeletePasswordJob::Private : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Private( DeletePasswordJob* qq ) : q( qq ) {}
|
||||
void doStart();
|
||||
DeletePasswordJob* const q;
|
||||
QString key;
|
||||
private Q_SLOTS:
|
||||
void jobFinished( QKeychain::Job* );
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // KEYCHAIN_P_H
|
107
thirdparty/qtkeychain/qtkeychain/keychain_win.cpp
vendored
Normal file
107
thirdparty/qtkeychain/qtkeychain/keychain_win.cpp
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
void ReadPasswordJob::Private::doStart() {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
|
||||
QByteArray encrypted = actual->value( key ).toByteArray();
|
||||
if ( encrypted.isNull() ) {
|
||||
q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
|
||||
return;
|
||||
}
|
||||
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
|
||||
blob_in.pbData = reinterpret_cast<BYTE*>( encrypted.data() );
|
||||
blob_in.cbData = encrypted.size();
|
||||
|
||||
const BOOL ret = CryptUnprotectData( &blob_in,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !ret ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Could not decrypt data") );
|
||||
return;
|
||||
}
|
||||
|
||||
data = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
SecureZeroMemory( blob_out.pbData, blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
void WritePasswordJob::Private::doStart() {
|
||||
if ( mode == Delete ) {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
const QString err = actual->status() == QSettings::AccessError
|
||||
? tr("Could not delete encrypted data from settings: access error")
|
||||
: tr("Could not delete encrypted data from settings: format error");
|
||||
q->emitFinishedWithError( OtherError, err );
|
||||
} else {
|
||||
q->emitFinished();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = mode == Binary ? binaryData : textData.toUtf8();
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
blob_in.pbData = reinterpret_cast<BYTE*>( data.data() );
|
||||
blob_in.cbData = data.size();
|
||||
const BOOL res = CryptProtectData( &blob_in,
|
||||
L"QKeychain-encrypted data",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !res ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Encryption failed") ); //TODO more details available?
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray encrypted( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
actual->setValue( key, encrypted );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
|
||||
const QString errorString = actual->status() == QSettings::AccessError
|
||||
? tr("Could not store encrypted data in settings: access error")
|
||||
: tr("Could not store encrypted data in settings: format error");
|
||||
q->emitFinishedWithError( OtherError, errorString );
|
||||
return;
|
||||
}
|
||||
|
||||
q->emitFinished();
|
||||
}
|
276
thirdparty/qtkeychain/qtkeychain/org.kde.KWallet.xml
vendored
Normal file
276
thirdparty/qtkeychain/qtkeychain/org.kde.KWallet.xml
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.kde.KWallet">
|
||||
<signal name="walletListDirty">
|
||||
</signal>
|
||||
<signal name="walletCreated">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletOpened">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletAsyncOpened">
|
||||
<arg name="tId" type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletDeleted">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletClosed">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="walletClosed">
|
||||
<arg name="handle" type="i" direction="out"/>
|
||||
</signal>
|
||||
<signal name="allWalletsClosed">
|
||||
</signal>
|
||||
<signal name="folderListUpdated">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="folderUpdated">
|
||||
<arg type="s" direction="out"/>
|
||||
<arg type="s" direction="out"/>
|
||||
</signal>
|
||||
<signal name="applicationDisconnected">
|
||||
<arg name="wallet" type="s" direction="out"/>
|
||||
<arg name="application" type="s" direction="out"/>
|
||||
</signal>
|
||||
<method name="isEnabled">
|
||||
<arg type="b" direction="out"/>
|
||||
</method>
|
||||
<method name="open">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="openPath">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="path" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="openAsync">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
<arg name="handleSession" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="openPathAsync">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="path" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
<arg name="handleSession" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="close">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="force" type="b" direction="in"/>
|
||||
</method>
|
||||
<method name="close">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="force" type="b" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="sync">
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||
</method>
|
||||
<method name="deleteWallet">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="isOpen">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="isOpen">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
</method>
|
||||
<method name="users">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="changePassword">
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="wId" type="x" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="wallets">
|
||||
<arg type="as" direction="out"/>
|
||||
</method>
|
||||
<method name="folderList">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="hasFolder">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="createFolder">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="removeFolder">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="entryList">
|
||||
<arg type="as" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readEntry">
|
||||
<arg type="ay" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readMap">
|
||||
<arg type="ay" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readPassword">
|
||||
<arg type="s" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readEntryList">
|
||||
<arg type="a{sv}" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readMapList">
|
||||
<arg type="a{sv}" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="readPasswordList">
|
||||
<arg type="a{sv}" direction="out"/>
|
||||
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="renameEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="oldName" type="s" direction="in"/>
|
||||
<arg name="newName" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writeEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="ay" direction="in"/>
|
||||
<arg name="entryType" type="i" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writeEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="ay" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writeMap">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="ay" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="writePassword">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="value" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="hasEntry">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="entryType">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="removeEntry">
|
||||
<arg type="i" direction="out"/>
|
||||
<arg name="handle" type="i" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
<arg name="appid" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="disconnectApplication">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="application" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="reconfigure">
|
||||
</method>
|
||||
<method name="folderDoesNotExist">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="keyDoesNotExist">
|
||||
<arg type="b" direction="out"/>
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="folder" type="s" direction="in"/>
|
||||
<arg name="key" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="closeAllWallets">
|
||||
</method>
|
||||
<method name="networkWallet">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="localWallet">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
<method name="pamOpen">
|
||||
<arg name="wallet" type="s" direction="in"/>
|
||||
<arg name="passwordHash" type="ay" direction="in"/>
|
||||
<arg name="sessionTimeout" type="i" direction="in"/>
|
||||
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
17
thirdparty/qtkeychain/qtkeychain/qkeychain_export.h
vendored
Normal file
17
thirdparty/qtkeychain/qtkeychain/qkeychain_export.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef QKEYCHAIN_EXPORT_H
|
||||
#define QKEYCHAIN_EXPORT_H
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
# ifdef QKEYCHAIN_STATICLIB
|
||||
# undef QKEYCHAIN_SHAREDLIB
|
||||
# define QKEYCHAIN_EXPORT
|
||||
# else
|
||||
# ifdef QKEYCHAIN_BUILD_QKEYCHAIN_LIB
|
||||
# define QKEYCHAIN_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QKEYCHAIN_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
98
thirdparty/qtkeychain/qtkeychain/testclient.cpp
vendored
Normal file
98
thirdparty/qtkeychain/qtkeychain/testclient.cpp
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program 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. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
|
||||
#include "keychain.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
static int printUsage() {
|
||||
std::cerr << "testclient store <account> <password>" << std::endl;
|
||||
std::cerr << "testclient restore <account>" << std::endl;
|
||||
std::cerr << "testclient delete <account>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main( int argc, char** argv ) {
|
||||
QCoreApplication app( argc, argv );
|
||||
const QStringList args = app.arguments();
|
||||
if ( args.count() < 2 )
|
||||
return printUsage();
|
||||
|
||||
QStringList::ConstIterator it = args.constBegin();
|
||||
++it;
|
||||
|
||||
if ( *it == QLatin1String("store") ) {
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString acc = *it;
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString pass = *it;
|
||||
if ( ++it != args.constEnd() )
|
||||
return printUsage();
|
||||
WritePasswordJob job( QLatin1String("qtkeychain-testclient") );
|
||||
job.setAutoDelete( false );
|
||||
job.setKey( acc );
|
||||
job.setTextData( pass );
|
||||
QEventLoop loop;
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.start();
|
||||
loop.exec();
|
||||
if ( job.error() ) {
|
||||
std::cerr << "Storing password failed: " << qPrintable(job.errorString()) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Password stored successfully" << std::endl;
|
||||
} else if ( *it == QLatin1String("restore") ) {
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString acc = *it;
|
||||
if ( ++it != args.constEnd() )
|
||||
return printUsage();
|
||||
ReadPasswordJob job( QLatin1String("qtkeychain-testclient") );
|
||||
job.setAutoDelete( false );
|
||||
job.setKey( acc );
|
||||
QEventLoop loop;
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
const QString pw = job.textData();
|
||||
if ( job.error() ) {
|
||||
std::cerr << "Restoring password failed: " << qPrintable(job.errorString()) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << qPrintable(pw) << std::endl;
|
||||
} else if ( *it == QLatin1String("delete") ) {
|
||||
if ( ++it == args.constEnd() )
|
||||
return printUsage();
|
||||
const QString acc = *it;
|
||||
if ( ++it != args.constEnd() )
|
||||
return printUsage();
|
||||
DeletePasswordJob job( QLatin1String("qtkeychain-testclient") );
|
||||
job.setAutoDelete( false );
|
||||
job.setKey( acc );
|
||||
QEventLoop loop;
|
||||
job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) );
|
||||
job.start();
|
||||
loop.exec();
|
||||
|
||||
if ( job.error() ) {
|
||||
std::cerr << "Deleting password failed: " << qPrintable(job.errorString()) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Password deleted successfully" << std::endl;
|
||||
} else {
|
||||
return printUsage();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user