diff --git a/src/libtomahawk/aclregistry.cpp b/src/libtomahawk/aclregistry.cpp index ae76ee3cd..f561490de 100644 --- a/src/libtomahawk/aclregistry.cpp +++ b/src/libtomahawk/aclregistry.cpp @@ -43,7 +43,7 @@ ACLRegistry::ACLRegistry( QObject* parent ) : QObject( parent ) { s_instance = this; - //qRegisterMetaType< QHash< QString, QHash< QString, ACL > > >("ACLRegistry::ACLCacheHash"); + qRegisterMetaType< ACLRegistry::ACL >("ACLRegistry::ACL"); m_cache = TomahawkSettings::instance()->aclEntries(); } @@ -54,11 +54,14 @@ ACLRegistry::~ACLRegistry() } -ACLRegistry::ACL +void ACLRegistry::isAuthorizedPeer( const QString& dbid, ACLRegistry::ACL globalType, const QString &username ) { if ( QThread::currentThread() != TOMAHAWK_APPLICATION::instance()->thread() ) - return globalType; + { + emit aclResult( dbid, globalType ); + return; + } qDebug() << "Current cache keys =" << m_cache.keys(); if( m_cache.contains( dbid ) ) @@ -67,17 +70,22 @@ ACLRegistry::isAuthorizedPeer( const QString& dbid, ACLRegistry::ACL globalType, if( peerHash.contains( "global" ) ) { registerAlias( dbid, username ); - return ACLRegistry::ACL( peerHash[ "global" ].toInt() ); + emit aclResult( dbid, ACLRegistry::ACL( peerHash[ "global" ].toInt() ) ); + return; } if ( globalType == ACLRegistry::NotFound ) - return globalType; + { + emit aclResult( dbid, globalType ); + return; + } peerHash[ "global" ] = int( globalType ); m_cache[ dbid ] = peerHash; save(); registerAlias( dbid, username ); - return globalType; + emit aclResult( dbid, globalType ); + return; } ACLRegistry::ACL acl = globalType; @@ -88,14 +96,18 @@ ACLRegistry::isAuthorizedPeer( const QString& dbid, ACLRegistry::ACL globalType, #endif if ( acl == ACLRegistry::NotFound || acl == ACLRegistry::AllowOnce || acl == ACLRegistry::DenyOnce ) - return acl; + { + emit aclResult( dbid, acl ); + return; + } QVariantHash peerHash; peerHash[ "global" ] = int( acl ); m_cache[ dbid ] = peerHash; save(); registerAlias( dbid, username ); - return acl; + emit aclResult( dbid, acl ); + return; } diff --git a/src/libtomahawk/aclregistry.h b/src/libtomahawk/aclregistry.h index 269c209e3..8d6e2fcda 100644 --- a/src/libtomahawk/aclregistry.h +++ b/src/libtomahawk/aclregistry.h @@ -48,17 +48,7 @@ public: ACLRegistry( QObject *parent = 0 ); ~ACLRegistry(); - - /** - * @brief Checks if peer is authorized; optionally, can authorize peer with given type if not found - * - * @param dbid DBID of peer - * @param globalType Global ACL to store if peer not found; if ACLRegistry::NotFound, does not store the peer Defaults to ACLRegistry::NotFound. - * @param username If not empty, will store the given username along with the new ACL value. Defaults to QString(). - * @return ACLRegistry::ACL - **/ - ACLRegistry::ACL isAuthorizedPeer( const QString &dbid, ACLRegistry::ACL globalType = ACLRegistry::NotFound, const QString &username = QString() ); - + /** * @brief Registers the global ACL value for this peer * @@ -87,6 +77,21 @@ public: **/ void registerAlias( const QString &dbid, const QString &username ); +signals: + void aclResult( QString nodeid, ACLRegistry::ACL peerStatus ); + +public slots: + /** + * @brief Checks if peer is authorized; optionally, can authorize peer with given type if not found + * + * @param dbid DBID of peer + * @param globalType Global ACL to store if peer not found; if ACLRegistry::NotFound, does not store the peer Defaults to ACLRegistry::NotFound. + * @param username If not empty, will store the given username along with the new ACL value. Defaults to QString(). + * @return ACLRegistry::ACL + **/ + void isAuthorizedPeer( const QString &dbid, ACLRegistry::ACL globalType = ACLRegistry::NotFound, const QString &username = QString() ); + + #ifndef ENABLE_HEADLESS ACLRegistry::ACL getUserDecision( const QString &username ); #endif diff --git a/src/libtomahawk/network/connection.cpp b/src/libtomahawk/network/connection.cpp index 0ad4ebf39..8da4c9418 100644 --- a/src/libtomahawk/network/connection.cpp +++ b/src/libtomahawk/network/connection.cpp @@ -184,7 +184,41 @@ Connection::start( QTcpSocket* sock ) m_name = QString( "peer[%1]" ).arg( m_sock->peerAddress().toString() ); } - QTimer::singleShot( 0, this, SLOT( doSetup() ) ); + QTimer::singleShot( 0, this, SLOT( checkACL() ) ); +} + + +void +Connection::checkACL() +{ + if ( !property( "nodeid" ).isValid() ) + { + QTimer::singleShot( 0, this, SLOT( doSetup() ) ); + return; + } + + QString nodeid = property( "nodeid" ).toString(); + tDebug( LOGVERBOSE ) << "Checking ACL for" << name(); + connect( ACLRegistry::instance(), SIGNAL( aclResult( QString, ACLRegistry::ACL ) ), this, SLOT( checkACLResult( QString, ACLRegistry::ACL ) ), Qt::QueuedConnection ); + QMetaObject::invokeMethod( ACLRegistry::instance(), "isAuthorizedPeer", Qt::QueuedConnection, Q_ARG( QString, nodeid ), Q_ARG( ACLRegistry::ACL, ACLRegistry::NotFound ), Q_ARG( QString, name() ) ); +} + + +void +Connection::checkACLResult( const QString &nodeid, ACLRegistry::ACL peerStatus ) +{ + if ( nodeid != property( "nodeid" ).toString() ) + return; + + disconnect( ACLRegistry::instance(), SIGNAL( aclResult( QString, ACLRegistry::ACL ) ) ); + tDebug( LOGVERBOSE ) << "ACL status is" << peerStatus; + if ( peerStatus == ACLRegistry::Allow || peerStatus == ACLRegistry::AllowOnce ) + { + QTimer::singleShot( 0, this, SLOT( doSetup() ) ); + return; + } + + shutdown(); } diff --git a/src/libtomahawk/network/connection.h b/src/libtomahawk/network/connection.h index 8ae04dca8..275688da7 100644 --- a/src/libtomahawk/network/connection.h +++ b/src/libtomahawk/network/connection.h @@ -38,6 +38,7 @@ #include "msg.h" #include "msgprocessor.h" +#include "libtomahawk/aclregistry.h" #include "dllmacro.h" @@ -118,6 +119,8 @@ private slots: void socketDisconnectedError( QAbstractSocket::SocketError ); void readyRead(); void doSetup(); + void checkACL(); + void checkACLResult( const QString &id, ACLRegistry::ACL peerStatus ); void authCheckTimeout(); void bytesWritten( qint64 ); void calcStats(); diff --git a/src/libtomahawk/network/servent.cpp b/src/libtomahawk/network/servent.cpp index a6444f78d..858998537 100644 --- a/src/libtomahawk/network/servent.cpp +++ b/src/libtomahawk/network/servent.cpp @@ -39,7 +39,6 @@ #include "portfwdthread.h" #include "tomahawksettings.h" -#include "libtomahawk/aclregistry.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" @@ -671,12 +670,9 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString if( !nodeid.isEmpty() ) { + // Used by the connection for the ACL check // If there isn't a nodeid it's not the first connection and will already have been stopped - if( !checkACL( conn, nodeid ) ) - { - tLog() << "Connection not allowed due to ACL"; - return NULL; - } + conn.data()->setProperty( "nodeid", nodeid ); } if( conn.data()->onceOnly() ) @@ -704,22 +700,6 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString } -bool -Servent::checkACL( const QWeakPointer< Connection > conn, const QString &nodeid ) const -{ - if ( conn.isNull() ) - return false; - - tDebug( LOGVERBOSE ) << "Checking ACL for" << conn.data()->name(); - ACLRegistry::ACL peerStatus = ACLRegistry::instance()->isAuthorizedPeer( nodeid, ACLRegistry::NotFound, conn.data()->name() ); - tDebug( LOGVERBOSE ) << "ACL status is" << peerStatus; - if ( peerStatus == ACLRegistry::Allow || peerStatus == ACLRegistry::AllowOnce ) - return true; - - return false; -} - - QSharedPointer Servent::remoteIODeviceFactory( const result_ptr& result ) { diff --git a/src/libtomahawk/network/servent.h b/src/libtomahawk/network/servent.h index 7a52fda2c..629b8f17d 100644 --- a/src/libtomahawk/network/servent.h +++ b/src/libtomahawk/network/servent.h @@ -155,7 +155,6 @@ private slots: private: bool isValidExternalIP( const QHostAddress& addr ) const; void handoverSocket( Connection* conn, QTcpSocketExtra* sock ); - bool checkACL( const QWeakPointer< Connection > conn, const QString &nodeid ) const; void printCurrentTransfers(); QJson::Parser parser; diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 8c7275811..06f4ed58a 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -252,8 +252,11 @@ PlaylistModel::trackResolved( bool ) return; } - m_waitingForResolved.removeAll( q ); - disconnect( q, SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); + if ( m_waitingForResolved.contains( q ) ) + { + m_waitingForResolved.removeAll( q ); + disconnect( q, SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); + } if ( m_waitingForResolved.isEmpty() ) { @@ -451,6 +454,7 @@ PlaylistModel::remove( const QModelIndex& index, bool moreToCome ) if ( item && m_waitingForResolved.contains( item->query().data() ) ) { + disconnect( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolved( bool ) ) ); m_waitingForResolved.removeAll( item->query().data() ); if ( m_waitingForResolved.isEmpty() ) emit loadingFinished();