1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-04-21 16:31:58 +02:00

Encapsulate ACL requests/decisions to move logic out of Connection

This commit is contained in:
Uwe L. Korn 2013-08-25 12:00:41 +02:00
parent 0da448c5a7
commit d93a9c1a4b
10 changed files with 272 additions and 23 deletions

@ -319,6 +319,7 @@ list(APPEND libSources
filemetadata/MetadataEditor.cpp
network/acl/AclRegistry.cpp
network/acl/AclRequest.cpp
network/BufferIoDevice.cpp
network/Msg.cpp
network/MsgProcessor.cpp
@ -365,6 +366,7 @@ list(APPEND libSources
utils/TomahawkCache.cpp
utils/GuiHelpers.cpp
utils/WeakObjectHash.cpp
utils/WeakObjectList.cpp
utils/PluginLoader.cpp
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp

@ -247,6 +247,16 @@ namespace Tomahawk
typedef QPointer< InfoPlugin > InfoPluginPtr;
}
namespace Network
{
namespace ACL
{
class AclRequest;
typedef QSharedPointer<AclRequest> aclrequest_ptr;
typedef QWeakPointer<AclRequest> aclrequest_wptr;
}
}
} // ns
typedef int AudioErrorCode;

@ -21,6 +21,7 @@
#include "Connection_p.h"
#include "network/acl/AclRegistry.h"
#include "network/acl/AclRequest.h"
#include "network/Servent.h"
#include "network/Msg.h"
#include "utils/Logger.h"
@ -339,11 +340,10 @@ Connection::checkACL()
return;
}
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Checking ACL for" << name();
connect( ACLRegistry::instance(), SIGNAL( aclResult( QString, QString, Tomahawk::ACLStatus::Type ) ),
this, SLOT( checkACLResult( QString, QString, Tomahawk::ACLStatus::Type ) ),
Qt::QueuedConnection );
QMetaObject::invokeMethod( ACLRegistry::instance(), "isAuthorizedUser", Qt::QueuedConnection, Q_ARG( QString, d->nodeid ), Q_ARG( QString, bareName() ), Q_ARG( Tomahawk::ACLStatus::Type, Tomahawk::ACLStatus::NotFound ) );
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Checking ACL for" << name();
d->aclRequest = Tomahawk::Network::ACL::aclrequest_ptr( new Tomahawk::Network::ACL::AclRequest( d->nodeid, bareName(), Tomahawk::ACLStatus::NotFound ) );
connect( d->aclRequest.data(), SIGNAL( decision( Tomahawk::ACLStatus::Type ) ), SLOT( aclDecision( Tomahawk::ACLStatus::Type ) ), Qt::QueuedConnection );
ACLRegistry::instance()->isAuthorizedRequest( d->aclRequest );
}
@ -354,30 +354,19 @@ Connection::bareName() const
}
void
Connection::checkACLResult( const QString &nodeid, const QString &username, Tomahawk::ACLStatus::Type peerStatus )
Connection::aclDecision( Tomahawk::ACLStatus::Type status )
{
Q_D( Connection );
QReadLocker nodeidLocker( &d->nodeidLock );
if ( nodeid != d->nodeid )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << QString( "nodeid (%1) not ours (%2) for user %3" ).arg( nodeid ).arg( d->nodeid ).arg( username );
return;
}
if ( username != bareName() )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "username not our barename";
return;
}
disconnect( ACLRegistry::instance(), SIGNAL( aclResult( QString, QString, Tomahawk::ACLStatus::Type ) ) );
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << QString( "ACL status for user %1 is" ).arg( username ) << peerStatus;
if ( peerStatus == Tomahawk::ACLStatus::Stream )
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "ACL decision for" << name() << ":" << status;
if ( status == Tomahawk::ACLStatus::Stream )
{
QTimer::singleShot( 0, this, SLOT( doSetup() ) );
return;
}
// We have a decision, free memory.
d->aclRequest->deleteLater();
shutdown();
}

@ -116,7 +116,7 @@ private slots:
void readyRead();
void doSetup();
void checkACL();
void checkACLResult( const QString &nodeid, const QString &username, Tomahawk::ACLStatus::Type peerStatus );
void aclDecision( Tomahawk::ACLStatus::Type status );
void bytesWritten( qint64 );
void calcStats();

@ -52,6 +52,7 @@ public:
, stats_rx_bytes_per_sec( 0 )
, rx_bytes_last( 0 )
, tx_bytes_last( 0 )
, aclRequest( 0 )
{
}
Connection* q_ptr;
@ -88,6 +89,8 @@ private:
MsgProcessor msgprocessor_in;
MsgProcessor msgprocessor_out;
Tomahawk::Network::ACL::aclrequest_ptr aclRequest;
};

@ -94,6 +94,9 @@ ACLRegistry::ACLRegistry( QObject* parent )
qRegisterMetaType< Tomahawk::ACLStatus::Type >( "Tomahawk::ACLStatus::Type" );
qRegisterMetaType< ACLRegistry::User >( "ACLRegistry::User" );
qRegisterMetaTypeStreamOperators< ACLRegistry::User >( "ACLRegistry::User" );
connect( this, SIGNAL( aclResult( QString, QString, Tomahawk::ACLStatus::Type ) ),
SLOT( aclResultForRequest(QString,QString,Tomahawk::ACLStatus::Type ) ) );
}
@ -102,11 +105,49 @@ ACLRegistry::~ACLRegistry()
}
void
ACLRegistry::isAuthorizedRequest( const Tomahawk::Network::ACL::aclrequest_ptr& request )
{
m_aclRequests.insert( request );
// Ensure that we calling the registry in its own function and do not block the caller thread.
QMetaObject::invokeMethod( this, "isAuthorizedUser", Qt::QueuedConnection,
Q_ARG( QString, request->nodeid() ),
Q_ARG( QString, request->username() ),
Q_ARG( Tomahawk::ACLStatus::Type, request->status() ) );
}
void
ACLRegistry::load()
{
}
void
ACLRegistry::aclResultForRequest( QString nodeid, QString username, Tomahawk::ACLStatus::Type peerStatus )
{
QMutableListIterator<Tomahawk::Network::ACL::aclrequest_wptr> iter = m_aclRequests.iter();
while ( iter.hasNext() )
{
Tomahawk::Network::ACL::aclrequest_wptr wptr = iter.next();
// Remove dangling objects
if ( wptr.isNull() )
{
iter.remove();
continue;
}
// Try to (greedy) match all possible AclRequests
Tomahawk::Network::ACL::aclrequest_ptr request = wptr.toStrongRef();
if ( request->nodeid() == nodeid && request->username() == username )
{
QMetaObject::invokeMethod( request.data(), "emitDecision", Q_ARG( Tomahawk::ACLStatus::Type, peerStatus ) );
// We made a decision, so strip this request from the queue
iter.remove();
}
}
}
void
ACLRegistry::save()

@ -20,6 +20,9 @@
#ifndef TOMAHAWK_ACLREGISTRY_H
#define TOMAHAWK_ACLREGISTRY_H
#include "network/acl/AclRequest.h"
#include "utils/WeakObjectList.h"
#include "DllMacro.h"
#include "Typedefs.h"
@ -82,6 +85,17 @@ public:
ACLRegistry( QObject *parent = 0 );
virtual ~ACLRegistry();
/**
* @brief Check if the request is authorized to access via our instance via network.
*
* Checking is done asynchronously and will not block the calling thread. This function
* can be called from any thread. It will ensure itself that the underlying logic is run
* in the correct thread.
*
* @param request The connection request which should be authorized.
*/
virtual void isAuthorizedRequest( const Tomahawk::Network::ACL::aclrequest_ptr& request );
signals:
void aclResult( QString nodeid, QString username, Tomahawk::ACLStatus::Type peerStatus );
@ -109,6 +123,12 @@ protected:
QList< ACLRegistry::User > m_cache;
static ACLRegistry* s_instance;
private slots:
void aclResultForRequest( QString nodeid, QString username, Tomahawk::ACLStatus::Type peerStatus );
private:
Tomahawk::Utils::WeakObjectList<Tomahawk::Network::ACL::AclRequest> m_aclRequests;
};
Q_DECLARE_METATYPE( ACLRegistry::User )

@ -0,0 +1,69 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AclRequest_p.h"
namespace Tomahawk {
namespace Network {
namespace ACL {
AclRequest::AclRequest( const QString& nodeid, const QString& username, Tomahawk::ACLStatus::Type defaultStatus )
: d_ptr( new AclRequestPrivate( this, nodeid, username, defaultStatus ) )
{
}
AclRequest::~AclRequest()
{
}
QString
AclRequest::nodeid() const
{
Q_D( const AclRequest );
return d->nodeid;
}
QString
AclRequest::username() const
{
Q_D( const AclRequest );
return d->username;
}
ACLStatus::Type
AclRequest::status() const
{
Q_D( const AclRequest );
return d->status;
}
void
AclRequest::emitDecision( ACLStatus::Type status )
{
emit decision( status );
}
} // namespace ACL
} // namespace Network
} // namespace Tomahawk

@ -0,0 +1,60 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TOMAHAWK_NETWORK_ACL_ACLREQUEST_H
#define TOMAHAWK_NETWORK_ACL_ACLREQUEST_H
#include "Typedefs.h"
#include <QObject>
namespace Tomahawk {
namespace Network {
namespace ACL {
class AclRequestPrivate;
class AclRequest : public QObject
{
Q_OBJECT
public:
explicit AclRequest( const QString& nodeid, const QString& username, Tomahawk::ACLStatus::Type defaultStatus = Tomahawk::ACLStatus::NotFound );
virtual ~AclRequest();
QString nodeid() const;
QString username() const;
Tomahawk::ACLStatus::Type status() const;
public slots:
void emitDecision( Tomahawk::ACLStatus::Type status );
signals:
void decision( Tomahawk::ACLStatus::Type status );
protected:
QScopedPointer<AclRequestPrivate> d_ptr;
private:
Q_DECLARE_PRIVATE( AclRequest )
};
} // namespace ACL
} // namespace Network
} // namespace Tomahawk
#endif // TOMAHAWK_NETWORK_ACL_ACLREQUEST_H

@ -0,0 +1,55 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACLREQUEST_P_H
#define ACLREQUEST_P_H
#include "AclRequest.h"
namespace Tomahawk {
namespace Network {
namespace ACL {
class AclRequestPrivate
{
public:
AclRequestPrivate( AclRequest* q, const QString& _nodeid, const QString& _username, Tomahawk::ACLStatus::Type _status )
: q_ptr( q )
, nodeid( _nodeid )
, username( _username )
, status( _status )
{
}
virtual ~AclRequestPrivate()
{
}
AclRequest* q_ptr;
Q_DECLARE_PUBLIC( AclRequest )
private:
QString nodeid;
QString username;
Tomahawk::ACLStatus::Type status;
};
}
}
}
#endif // ACLREQUEST_P_H