mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-06 20:20:41 +02:00
Compare commits
10 Commits
0.8.3
...
remote-api
Author | SHA1 | Date | |
---|---|---|---|
|
4cdfd81fb5 | ||
|
1bae47da51 | ||
|
6bf471ff13 | ||
|
65e51944c2 | ||
|
571f5c7e7d | ||
|
5e0ae4fda1 | ||
|
aebc8bcb8a | ||
|
ea8fec15d3 | ||
|
33473d469a | ||
|
1529d2e5d4 |
@@ -107,7 +107,15 @@ INCLUDE_DIRECTORIES(
|
||||
)
|
||||
|
||||
IF( QXTWEB_FOUND )
|
||||
LIST(APPEND tomahawkSources web/Api_v1.cpp)
|
||||
LIST(APPEND tomahawkSources
|
||||
web/Api_v1.cpp
|
||||
web/Api_v2.cpp
|
||||
web/Api_v2_0.cpp
|
||||
web/Api2HttpsServerConnector.cpp
|
||||
web/Api2User.cpp
|
||||
web/apiv2/ACLItemDelegate.cpp
|
||||
web/apiv2/ACLJobStatusItem.cpp
|
||||
)
|
||||
LIST(APPEND LINK_LIBRARIES ${QXTWEB_LIBRARIES})
|
||||
INCLUDE_DIRECTORIES(${QXTWEB_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.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
|
||||
@@ -38,6 +39,8 @@
|
||||
#include "network/Servent.h"
|
||||
#include "network/DbSyncConnection.h"
|
||||
#include "web/Api_v1.h"
|
||||
#include "web/Api_v2.h"
|
||||
#include "web/Api2HttpsServerConnector.h"
|
||||
#include "SourceList.h"
|
||||
#include "ViewManager.h"
|
||||
#include "ShortcutHandler.h"
|
||||
@@ -112,6 +115,11 @@
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QTranslator>
|
||||
#include <QUuid>
|
||||
|
||||
#include <QtCrypto>
|
||||
#include <QSslKey>
|
||||
#include <QxtNetwork/QxtSslServer>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -490,36 +498,98 @@ TomahawkApp::initHTTP()
|
||||
delete m_httpv1_session.data();
|
||||
if ( !m_httpv1_connector.isNull() )
|
||||
delete m_httpv1_connector.data();
|
||||
if ( !m_httpv2_session.isNull() )
|
||||
delete m_httpv2_session.data();
|
||||
if ( !m_httpv2_connector.isNull() )
|
||||
delete m_httpv2_connector.data();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_httpv1_session )
|
||||
{
|
||||
tLog() << "HTTPd session already exists, returning";
|
||||
return;
|
||||
tLog() << "HTTPd session for API v1.0 already exists, not starting again";
|
||||
}
|
||||
|
||||
m_httpv1_session = QPointer< QxtHttpSessionManager >( new QxtHttpSessionManager() );
|
||||
m_httpv1_connector = QPointer< QxtHttpServerConnector >( new QxtHttpServerConnector );
|
||||
if ( m_httpv1_session.isNull() || m_httpv1_connector.isNull() )
|
||||
else
|
||||
{
|
||||
if ( !m_httpv1_session.isNull() )
|
||||
delete m_httpv1_session.data();
|
||||
if ( !m_httpv1_connector.isNull() )
|
||||
delete m_httpv1_connector.data();
|
||||
tLog() << "Failed to start HTTPd, could not create object";
|
||||
return;
|
||||
m_httpv1_session = QPointer< QxtHttpSessionManager >( new QxtHttpSessionManager() );
|
||||
m_httpv1_connector = QPointer< QxtHttpServerConnector >( new QxtHttpServerConnector );
|
||||
if ( m_httpv1_session.isNull() || m_httpv1_connector.isNull() )
|
||||
{
|
||||
if ( !m_httpv1_session.isNull() )
|
||||
delete m_httpv1_session.data();
|
||||
if ( !m_httpv1_connector.isNull() )
|
||||
delete m_httpv1_connector.data();
|
||||
tLog() << "Failed to start HTTPd for API v1.0, could not create object";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_httpv1_session.data()->setPort( 60210 ); //TODO config
|
||||
m_httpv1_session.data()->setListenInterface( QHostAddress::LocalHost );
|
||||
m_httpv1_session.data()->setConnector( m_httpv1_connector.data() );
|
||||
|
||||
Api_v1* api = new Api_v1( m_httpv1_session.data() );
|
||||
m_httpv1_session.data()->setStaticContentService( api );
|
||||
|
||||
tLog() << "Starting HTTPd for API v1.0 on" << m_httpv1_session.data()->listenInterface().toString() << m_httpv1_session.data()->port();
|
||||
m_httpv1_session.data()->start();
|
||||
}
|
||||
}
|
||||
|
||||
m_httpv1_session.data()->setPort( 60210 ); //TODO config
|
||||
m_httpv1_session.data()->setListenInterface( QHostAddress::LocalHost );
|
||||
m_httpv1_session.data()->setConnector( m_httpv1_connector.data() );
|
||||
if ( !m_httpv2_session.isNull() )
|
||||
{
|
||||
tLog() << "HTTPd session for API v2.0 already exists, not starting again";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_httpv2_session = QPointer< QxtHttpSessionManager >( new QxtHttpSessionManager( this ) );
|
||||
m_httpv2_connector = QPointer< QxtHttpsServerConnector >( new Api2HttpsServerConnector( this ) );
|
||||
if ( m_httpv2_session.isNull() || m_httpv2_connector.isNull() )
|
||||
{
|
||||
if ( !m_httpv2_session.isNull() )
|
||||
delete m_httpv2_session.data();
|
||||
if ( !m_httpv2_connector.isNull() )
|
||||
delete m_httpv2_connector.data();
|
||||
tLog() << "Failed to start HTTPd for API v2.0, could not create object";
|
||||
}
|
||||
else
|
||||
{
|
||||
m_httpv2_session->setPort( 60211 ); //TODO config
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
|
||||
m_httpv2_session.data()->setListenInterface( QHostAddress::Any );
|
||||
#else
|
||||
m_httpv2_session.data()->setListenInterface( QHostAddress::AnyIPv6 );
|
||||
#endif
|
||||
|
||||
Api_v1* api = new Api_v1( m_httpv1_session.data() );
|
||||
m_httpv1_session.data()->setStaticContentService( api );
|
||||
m_httpv2_session->setConnector( m_httpv2_connector.data() );
|
||||
|
||||
tLog() << "Starting HTTPd on" << m_httpv1_session.data()->listenInterface().toString() << m_httpv1_session.data()->port();
|
||||
m_httpv1_session.data()->start();
|
||||
Api_v2* api = new Api_v2( m_httpv2_session.data() );
|
||||
m_httpv2_session->setStaticContentService( api );
|
||||
QCA::KeyGenerator generator;
|
||||
QCA::PrivateKey key = generator.createRSA( 4096 );
|
||||
// TODO: Store and load this key with qtkeychain
|
||||
QCA::CertificateOptions certOpts;
|
||||
QCA::CertificateInfo certInfo;
|
||||
certInfo.insert( QCA::CommonName, QString( "tomahawk-%1" ).arg( Database::instance()->impl()->dbid() ) );
|
||||
certInfo.insert( QCA::Organization, "Tomahawk Player" );
|
||||
certInfo.insert( QCA::OrganizationalUnit, "HTTP API" );
|
||||
certOpts.setInfo( certInfo );
|
||||
certOpts.setSerialNumber( QCA::BigInteger( QCA::SecureArray( QUuid::createUuid().toByteArray() ) ) );
|
||||
// TODO: Check for validity of ceritifcate and renew if needed
|
||||
certOpts.setValidityPeriod( QDateTime::currentDateTime(), QDateTime::currentDateTime().addYears( 3 ) );
|
||||
QCA::Certificate cert( certOpts, key );
|
||||
QSslCertificate qcert( cert.toDER(), QSsl::Der);
|
||||
QSslKey qkey( key.toDER().toByteArray(), QSsl::Rsa, QSsl::Der );
|
||||
QxtSslServer* sslServer = m_httpv2_connector->tcpServer();
|
||||
sslServer->setPrivateKey(qkey);
|
||||
sslServer->setLocalCertificate(qcert);
|
||||
|
||||
tLog() << "Starting HTTPd for API v2.0 on" << m_httpv2_session->listenInterface().toString() << m_httpv2_session->port();
|
||||
if ( !m_httpv2_session->start() )
|
||||
{
|
||||
tLog() << "Failed to start HTTPd for API v2.0, could not bind to interface/port";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -150,6 +150,8 @@ private:
|
||||
|
||||
QPointer< QxtHttpServerConnector > m_httpv1_connector;
|
||||
QPointer< QxtHttpSessionManager > m_httpv1_session;
|
||||
QPointer< QxtHttpsServerConnector > m_httpv2_connector;
|
||||
QPointer< QxtHttpSessionManager > m_httpv2_session;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( PairList )
|
||||
|
53
src/tomahawk/web/Api2HttpsServerConnector.cpp
Normal file
53
src/tomahawk/web/Api2HttpsServerConnector.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/* === 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 "Api2HttpsServerConnector.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QSslSocket>
|
||||
|
||||
|
||||
Api2HttpsServerConnector::Api2HttpsServerConnector( QObject *parent )
|
||||
: QxtHttpsServerConnector( parent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api2HttpsServerConnector::sslErrors( const QList<QSslError>& errors )
|
||||
{
|
||||
QList<QSslError> toIgnore;
|
||||
QSslSocket* socket = static_cast<QSslSocket*>( sender() );
|
||||
foreach ( QSslError error, errors )
|
||||
{
|
||||
if ( error.error() == QSslError::SelfSignedCertificate )
|
||||
{
|
||||
toIgnore.append( error );
|
||||
}
|
||||
else if ( error.error() == QSslError::CertificateUntrusted )
|
||||
{
|
||||
toIgnore.append( error );
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Not ignoring SSL error" << error << error.error();
|
||||
}
|
||||
}
|
||||
socket->ignoreSslErrors( toIgnore );
|
||||
}
|
42
src/tomahawk/web/Api2HttpsServerConnector.h
Normal file
42
src/tomahawk/web/Api2HttpsServerConnector.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* === 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 API2HTTPSSERVERCONNECTOR_H
|
||||
#define API2HTTPSSERVERCONNECTOR_H
|
||||
|
||||
#include <QxtWeb/QxtHttpServerConnector>
|
||||
|
||||
class Api2HttpsServerConnector : public QxtHttpsServerConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Api2HttpsServerConnector( QObject* parent );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* We want to handle ourselves which SSL certificates are trusted.
|
||||
*
|
||||
* Ignore errors about untrusted and self-signed certificates.
|
||||
*
|
||||
* Already a slot in QxtHttpsServerConnector
|
||||
*/
|
||||
void sslErrors( const QList<QSslError>& errors );
|
||||
|
||||
};
|
||||
|
||||
#endif // API2HTTPSSERVERCONNECTOR_H
|
81
src/tomahawk/web/Api2User.cpp
Normal file
81
src/tomahawk/web/Api2User.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/* === 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 "Api2User.h"
|
||||
|
||||
Api2User::Api2User( const QString& name )
|
||||
: QObject( 0 )
|
||||
, m_aclDecision( None )
|
||||
, m_name( name )
|
||||
{
|
||||
}
|
||||
|
||||
Api2User::ACLDecision
|
||||
Api2User::aclDecision() const
|
||||
{
|
||||
return m_aclDecision;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Api2User::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
|
||||
QSslKey
|
||||
Api2User::pubkey() const
|
||||
{
|
||||
return m_pubkey;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api2User::setPubkey( const QSslKey &pubkey )
|
||||
{
|
||||
m_pubkey = pubkey;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Api2User::clientDescription() const
|
||||
{
|
||||
return m_clientDescription;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api2User::setClientDescription( const QString& clientDescription )
|
||||
{
|
||||
m_clientDescription = clientDescription;
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
Api2User::clientName() const
|
||||
{
|
||||
return m_clientName;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api2User::setClientName( const QString& clientName )
|
||||
{
|
||||
m_clientName = clientName;
|
||||
}
|
62
src/tomahawk/web/Api2User.h
Normal file
62
src/tomahawk/web/Api2User.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* === 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 API2USER_H
|
||||
#define API2USER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSslKey>
|
||||
|
||||
class Api2User : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Api2User( const QString& name );
|
||||
|
||||
enum ACLDecision {
|
||||
None, Deny, FullAccess
|
||||
};
|
||||
|
||||
ACLDecision aclDecision() const;
|
||||
void setAclDecision( ACLDecision decision );
|
||||
|
||||
QString clientDescription() const;
|
||||
void setClientDescription( const QString& clientDescription );
|
||||
|
||||
QString clientName() const;
|
||||
void setClientName( const QString& clientName );
|
||||
|
||||
QString name() const;
|
||||
|
||||
QSslKey pubkey() const;
|
||||
void setPubkey( const QSslKey& pubkey );
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
ACLDecision m_aclDecision;
|
||||
QString m_clientDescription;
|
||||
QString m_clientName;
|
||||
QString m_name;
|
||||
QSslKey m_pubkey;
|
||||
|
||||
};
|
||||
|
||||
#endif // API2USER_H
|
107
src/tomahawk/web/Api_v2.cpp
Normal file
107
src/tomahawk/web/Api_v2.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/* === 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 "Api_v2.h"
|
||||
|
||||
#include <QxtWeb/QxtWebPageEvent>
|
||||
|
||||
Api_v2::Api_v2( QxtAbstractWebSessionManager* sm, QObject* parent )
|
||||
: QxtWebSlotService( sm, parent )
|
||||
, m_apiv2_0( this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2::sendJsonOk( QxtWebRequestEvent* event )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, "{ result: \"ok\" }" );
|
||||
e->contentType = "application/json";
|
||||
postEvent( e );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2::sendJsonError( QxtWebRequestEvent* event, const QString& message )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, QString( "{ result: \"error\", error: \"%1\" }" ).arg( message ).toUtf8().constData() );
|
||||
e->contentType = "application/json";
|
||||
e->status = 500;
|
||||
e->statusMessage = "Method call failed.";
|
||||
postEvent( e );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2::apiCallFailed( QxtWebRequestEvent* event, const QString& method )
|
||||
{
|
||||
sendPlain404( event, QString( "Method \"%1\" for API 2.0 not found" ).arg( method ), "Method in API 2.0 not found" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2::api( QxtWebRequestEvent* event, const QString& version, const QString& method, const QString& arg1, const QString& arg2, const QString& arg3 )
|
||||
{
|
||||
if ( version == "2.0" )
|
||||
{
|
||||
if ( !arg3.isEmpty() )
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( &m_apiv2_0, method.toAscii().constData(), Q_ARG( QxtWebRequestEvent*, event ), Q_ARG( QString, arg1 ), Q_ARG( QString, arg2 ), Q_ARG( QString, arg3 ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
}
|
||||
}
|
||||
else if ( !arg2.isEmpty() )
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( &m_apiv2_0, method.toAscii().constData(), Q_ARG( QxtWebRequestEvent*, event ), Q_ARG( QString, arg1 ), Q_ARG( QString, arg2 ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
}
|
||||
}
|
||||
else if ( !arg1.isEmpty() )
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( &m_apiv2_0, method.toAscii().constData(), Q_ARG( QxtWebRequestEvent*, event ), Q_ARG( QString, arg1 ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !QMetaObject::invokeMethod( &m_apiv2_0, method.toAscii().constData(), Q_ARG( QxtWebRequestEvent*, event ) ) )
|
||||
{
|
||||
apiCallFailed(event, method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sendPlain404( event, QString( "Unknown API version %1" ).arg( version ), "API version not found" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2::sendPlain404( QxtWebRequestEvent* event, const QString& message, const QString& statusmessage )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, message.toUtf8() );
|
||||
e->contentType = "text/plain";
|
||||
e->status = 404;
|
||||
e->statusMessage = statusmessage.toAscii().constData();
|
||||
postEvent( e );
|
||||
}
|
54
src/tomahawk/web/Api_v2.h
Normal file
54
src/tomahawk/web/Api_v2.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* === 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 API_V2_H
|
||||
#define API_V2_H
|
||||
|
||||
#include "Api_v2_0.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <QxtWeb/QxtWebSlotService>
|
||||
|
||||
class Api_v2 : public QxtWebSlotService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Api_v2( QxtAbstractWebSessionManager* sm, QObject* parent = 0 );
|
||||
|
||||
void sendJsonOk( QxtWebRequestEvent* event );
|
||||
void sendJsonError( QxtWebRequestEvent* event, const QString& message );
|
||||
void sendPlain404( QxtWebRequestEvent* event, const QString& message, const QString& statusmessage );
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* All api (non-UI) calls with go to /api/<version>/method
|
||||
*/
|
||||
void api( QxtWebRequestEvent* event, const QString& version, const QString& method, const QString& arg1 = QString(), const QString& arg2 = QString(), const QString& arg3 = QString() );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Method call failed, report failure.
|
||||
*/
|
||||
void apiCallFailed( QxtWebRequestEvent* event, const QString& method);
|
||||
Api_v2_0 m_apiv2_0;
|
||||
};
|
||||
|
||||
#endif // API_V2_H
|
187
src/tomahawk/web/Api_v2_0.cpp
Normal file
187
src/tomahawk/web/Api_v2_0.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* === 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 "Api_v2_0.h"
|
||||
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "jobview/JobStatusModel.h"
|
||||
#include "jobview/JobStatusView.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "web/apiv2/ACLJobStatusItem.h"
|
||||
|
||||
#include "Api_v2.h"
|
||||
#include "Query.h"
|
||||
|
||||
#include <QSslKey>
|
||||
#include <QxtWeb/QxtWebPageEvent>
|
||||
#include <QxtWeb/QxtWebSlotService>
|
||||
|
||||
// Assumptions: QxtWebRequestEvent instance is called event and result is true on success
|
||||
#define JSON_REPLY( result, message ) jsonReply( event, Q_FUNC_INFO, message, !result )
|
||||
|
||||
Api_v2_0::Api_v2_0( Api_v2* parent )
|
||||
: QObject( parent )
|
||||
, m_service( parent )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Api_v2_0::ping( QxtWebRequestEvent* event )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, "pong" );
|
||||
e->contentType = "text/plain";
|
||||
m_service->postEvent( e );
|
||||
}
|
||||
|
||||
void
|
||||
Api_v2_0::playback( QxtWebRequestEvent* event, const QString& command )
|
||||
{
|
||||
if ( !checkAuthentication( event ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( command == "next")
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "next", Qt::QueuedConnection ) , "Skipping to the next track failed." );
|
||||
}
|
||||
else if ( command == "previous" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "previous", Qt::QueuedConnection ), "Rewinding to the previous track failed." );
|
||||
}
|
||||
else if ( command == "playpause" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "playpause", Qt::QueuedConnection ), "Play/Pause failed." );
|
||||
}
|
||||
else if ( command == "play" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "play", Qt::QueuedConnection ), "Starting the playback failed." );
|
||||
}
|
||||
else if ( command == "pause" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "pause", Qt::QueuedConnection ), "Pausing the current track failed." );
|
||||
}
|
||||
else if ( command == "stop" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "stop", Qt::QueuedConnection ), "Stopping the current track failed." );
|
||||
}
|
||||
else if ( command == "lowervolume" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "lowerVolume", Qt::QueuedConnection ), "Lowering volume failed." );
|
||||
}
|
||||
else if ( command == "raisevolume" )
|
||||
{
|
||||
JSON_REPLY( QMetaObject::invokeMethod( AudioEngine::instance(), "raiseVolume", Qt::QueuedConnection ), "Raising volume failed." );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_service->sendJsonError( event, "No such playback command." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2_0::requestauth( QxtWebRequestEvent *event )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO;
|
||||
if ( checkAuthentication( event ) )
|
||||
{
|
||||
// A decision was already made.
|
||||
m_service->sendJsonOk( event );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( event->isSecure && !event->clientCertificate.isNull() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO;
|
||||
QSslCertificate certificate = event->clientCertificate;
|
||||
QString clientName = certificate.subjectInfo( QSslCertificate::CommonName );
|
||||
|
||||
if ( m_users.contains( clientName ) && m_users.value( clientName )->aclDecision() == Api2User::Deny )
|
||||
{
|
||||
// Access was already denied
|
||||
jsonUnauthenticated( event );
|
||||
return;
|
||||
}
|
||||
|
||||
QSharedPointer<Api2User> user( new Api2User( clientName ) );
|
||||
user->setClientDescription( certificate.subjectInfo( QSslCertificate::OrganizationalUnitName ) );
|
||||
user->setClientName( certificate.subjectInfo( QSslCertificate::Organization ) );
|
||||
user->setPubkey( certificate.publicKey() );
|
||||
// TODO: Do not readd users
|
||||
m_users[ clientName ] = user;
|
||||
// TODO: ACL decision
|
||||
Tomahawk::APIv2::ACLJobStatusItem* job = new Tomahawk::APIv2::ACLJobStatusItem( user );
|
||||
JobStatusView::instance()->model()->addJob( job );
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2_0::jsonReply( QxtWebRequestEvent* event, const char* funcInfo, const QString& errorMessage, bool isError )
|
||||
{
|
||||
if ( isError )
|
||||
{
|
||||
tLog( LOGVERBOSE ) << funcInfo << errorMessage;
|
||||
m_service->sendJsonError( event, errorMessage );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_service->sendJsonOk( event );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Api_v2_0::jsonUnauthenticated( QxtWebRequestEvent *event )
|
||||
{
|
||||
QxtWebPageEvent * e = new QxtWebPageEvent( event->sessionID, event->requestID, "{ result: \"error\", error: \"Method call needs to be authenticated.\" }" );
|
||||
e->contentType = "application/json";
|
||||
e->status = 401;
|
||||
e->statusMessage = "Method call needs to be authenticated.";
|
||||
m_service->postEvent( e );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Api_v2_0::checkAuthentication( QxtWebRequestEvent* event )
|
||||
{
|
||||
if ( event->isSecure && !event->clientCertificate.isNull() )
|
||||
{
|
||||
// Using SSL Certificate authentication
|
||||
QString clientName = event->clientCertificate.subjectInfo( QSslCertificate::CommonName );
|
||||
QSslKey pubkey = event->clientCertificate.publicKey();
|
||||
if ( m_users.contains( clientName ) )
|
||||
{
|
||||
const QSharedPointer<Api2User> user = m_users.value( clientName );
|
||||
if ( user->aclDecision() == Api2User::FullAccess && user->pubkey() == pubkey )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Auth!
|
||||
// * Shared secret between two clients when talking via SSL
|
||||
// * sth else when connecting without httpS
|
||||
// * a more secure version of digest auth
|
||||
return false;
|
||||
}
|
86
src/tomahawk/web/Api_v2_0.h
Normal file
86
src/tomahawk/web/Api_v2_0.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* === 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 API_V2_0_H
|
||||
#define API_V2_0_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "Api2User.h"
|
||||
|
||||
class Api_v2;
|
||||
class QxtWebRequestEvent;
|
||||
class QxtWebSlotService;
|
||||
|
||||
class Api_v2_0 : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Api_v2_0( Api_v2* parent = 0 );
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Simple test to check for API 2.0 support.
|
||||
*
|
||||
* This call needs no authentication.
|
||||
*/
|
||||
void ping( QxtWebRequestEvent* event );
|
||||
|
||||
/**
|
||||
* Control playback.
|
||||
*
|
||||
* This call needs to be authenticated.
|
||||
*/
|
||||
void playback( QxtWebRequestEvent* event, const QString& command );
|
||||
|
||||
/**
|
||||
* Request that the client should be authorized.
|
||||
*
|
||||
* The request can be made via 2 methods:
|
||||
* - If using SSL, the client sends his certificate as a standard peercerificate and supplies a shared secret.
|
||||
* - Without SSL, the client encrypts a shared secret with the certificate from the server and signs it with its secret.
|
||||
* The client certificate is supplied as another parameter
|
||||
*/
|
||||
void requestauth( QxtWebRequestEvent* event );
|
||||
private:
|
||||
/**
|
||||
* Check the current HTTP request is correctly authenticated via any of the possible authentication schemes.
|
||||
*/
|
||||
bool checkAuthentication( QxtWebRequestEvent* event );
|
||||
|
||||
/**
|
||||
* Send a simple reply to a (write-only) method call.
|
||||
*
|
||||
* On failure send a custom error message.
|
||||
*/
|
||||
void jsonReply( QxtWebRequestEvent* event, const char* funcInfo, const QString& errorMessage, bool isError );
|
||||
|
||||
/**
|
||||
* Send a reply that the made call lacks the needed authentication
|
||||
*/
|
||||
void jsonUnauthenticated( QxtWebRequestEvent* event );
|
||||
|
||||
Api_v2* m_service;
|
||||
QMap< QString, QSharedPointer< Api2User > > m_users;
|
||||
};
|
||||
|
||||
#endif // API_V2_0_H
|
146
src/tomahawk/web/apiv2/ACLItemDelegate.cpp
Normal file
146
src/tomahawk/web/apiv2/ACLItemDelegate.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
/* === 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 "ACLItemDelegate.h"
|
||||
|
||||
#include "jobview/JobStatusModel.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "ACLJobStatusItem.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace APIv2 {
|
||||
|
||||
#define PADDING 2
|
||||
|
||||
ACLItemDelegate::ACLItemDelegate( QObject *parent )
|
||||
: QStyledItemDelegate( parent )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
ACLItemDelegate::~ACLItemDelegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ACLItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
ACLJobStatusItem* item = dynamic_cast< ACLJobStatusItem* >( index.data( JobStatusModel::JobDataRole ).value< JobStatusItem* >() );
|
||||
if ( !item )
|
||||
return;
|
||||
QStyleOptionViewItemV4 opt = option;
|
||||
initStyleOption( &opt, index );
|
||||
QFontMetrics fm( opt.font );
|
||||
|
||||
opt.state &= ~QStyle::State_MouseOver;
|
||||
QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget );
|
||||
|
||||
painter->setRenderHint( QPainter::Antialiasing );
|
||||
painter->fillRect( opt.rect, Qt::lightGray );
|
||||
|
||||
QString mainText = QString( tr( "%An instance of\n%1\nwants to control this player:" ) ).arg( item->user()->clientName() );
|
||||
|
||||
const QRect rRect( opt.rect.left() + PADDING, opt.rect.top() + 4*PADDING, opt.rect.width() - 2*PADDING, opt.rect.height() - 2*PADDING );
|
||||
painter->drawText( rRect, Qt::AlignHCenter, mainText );
|
||||
|
||||
int totalwidth = opt.rect.width();
|
||||
int thirds = totalwidth/3;
|
||||
QRect allowBtnRect;
|
||||
painter->setPen( Qt::white );
|
||||
|
||||
QString allowBtnText = tr( "See Details & Decide" );
|
||||
int allowBtnWidth = fm.width( allowBtnText ) + 2 * PADDING;
|
||||
allowBtnRect = QRect( opt.rect.left() + thirds - allowBtnWidth / 2, opt.rect.bottom() - fm.height() - 4 * PADDING, allowBtnWidth + 2 * PADDING, fm.height() + 2 * PADDING );
|
||||
|
||||
|
||||
drawRoundedButton( painter, allowBtnRect, allowBtnRect.contains( m_savedHoverPos ) );
|
||||
painter->drawText( allowBtnRect, Qt::AlignCenter, allowBtnText );
|
||||
m_savedAcceptRect = allowBtnRect;
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
ACLItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
QSize size( QStyledItemDelegate::sizeHint( option, index ).width(), ( TomahawkUtils::defaultFontHeight() + 6 ) * 4.5 );
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ACLItemDelegate::emitSizeHintChanged( const QModelIndex& index )
|
||||
{
|
||||
emit sizeHintChanged( index );
|
||||
}
|
||||
|
||||
void
|
||||
ACLItemDelegate::drawRoundedButton( QPainter *painter, const QRect& btnRect, bool red ) const
|
||||
{
|
||||
//FIXME const colors
|
||||
if ( !red )
|
||||
TomahawkUtils::drawRoundedButton( painter, btnRect, QColor( 54, 127, 211 ), QColor( 43, 104, 182 ), QColor( 34, 85, 159 ), QColor( 35, 79, 147 ) );
|
||||
else
|
||||
TomahawkUtils::drawRoundedButton( painter, btnRect, QColor( 206, 63, 63 ), QColor( 170, 52, 52 ), QColor( 150, 50, 50 ), QColor( 130, 40, 40 ) );
|
||||
}
|
||||
|
||||
bool
|
||||
ACLItemDelegate::editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
Q_UNUSED( option )
|
||||
Q_UNUSED( model )
|
||||
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
if ( event->type() != QEvent::MouseButtonPress &&
|
||||
event->type() != QEvent::MouseButtonRelease &&
|
||||
event->type() != QEvent::MouseButtonDblClick &&
|
||||
event->type() != QEvent::MouseMove )
|
||||
return false;
|
||||
|
||||
if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
m_savedHoverPos = me->pos();
|
||||
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Setting position to " << m_savedHoverPos;
|
||||
emit update( index );
|
||||
return true;
|
||||
}
|
||||
|
||||
/* TODO
|
||||
if ( event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonDblClick )
|
||||
{
|
||||
QMouseEvent* me = static_cast< QMouseEvent* >( event );
|
||||
if ( m_savedAcceptRect.contains( me->pos() ) )
|
||||
emit aclResult( Tomahawk::ACLStatus::Stream );
|
||||
else if ( m_savedDenyRect.contains( me->pos() ) )
|
||||
emit aclResult( Tomahawk::ACLStatus::Deny );
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace APIv2
|
||||
} // namespace Tomahawk
|
60
src/tomahawk/web/apiv2/ACLItemDelegate.h
Normal file
60
src/tomahawk/web/apiv2/ACLItemDelegate.h
Normal file
@@ -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_APIV2_ACLITEMDELEGATE_H
|
||||
#define TOMAHAWK_APIV2_ACLITEMDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#include "web/Api2User.h"
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace APIv2 {
|
||||
|
||||
class ACLItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ACLItemDelegate ( QObject* parent = 0 );
|
||||
virtual ~ACLItemDelegate();
|
||||
|
||||
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
|
||||
virtual void emitSizeHintChanged( const QModelIndex &index );
|
||||
|
||||
signals:
|
||||
void update( const QModelIndex& idx );
|
||||
void aclResult( Api2User::ACLDecision aclDecision );
|
||||
|
||||
protected:
|
||||
virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
|
||||
private:
|
||||
void drawRoundedButton( QPainter* painter, const QRect& btnRect, bool red = false ) const;
|
||||
|
||||
QPoint m_savedHoverPos;
|
||||
mutable QRect m_savedAcceptRect;
|
||||
};
|
||||
|
||||
} // namespace APIv2
|
||||
} // namespace Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_APIV2_ACLITEMDELEGATE_H
|
56
src/tomahawk/web/apiv2/ACLJobStatusItem.cpp
Normal file
56
src/tomahawk/web/apiv2/ACLJobStatusItem.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/* === 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 "ACLJobStatusItem.h"
|
||||
|
||||
#include "infosystem/InfoSystem.h"
|
||||
#include "ACLItemDelegate.h"
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace APIv2 {
|
||||
|
||||
ACLJobStatusItem::ACLJobStatusItem( const QSharedPointer<Api2User>& user )
|
||||
: JobStatusItem()
|
||||
{
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
|
||||
ACLJobStatusItem::~ACLJobStatusItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ACLJobStatusItem::createDelegate( QObject *parent )
|
||||
{
|
||||
if ( m_delegate )
|
||||
return;
|
||||
|
||||
m_delegate = new ACLItemDelegate( parent );
|
||||
|
||||
// Display a system notification so that the user sees that he has to make a decision.
|
||||
Tomahawk::InfoSystem::InfoPushData pushData( "ACLJobStatusItem", Tomahawk::InfoSystem::InfoNotifyUser, tr( "Tomahawk needs you to decide whether an app is allowed to connect via the HTTP API." ), Tomahawk::InfoSystem::PushNoFlag );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
|
||||
}
|
||||
|
||||
} // namespace APIv2
|
||||
} // namespace Tomahawk
|
||||
|
67
src/tomahawk/web/apiv2/ACLJobStatusItem.h
Normal file
67
src/tomahawk/web/apiv2/ACLJobStatusItem.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* === 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_APIV2_ACLJOBSTATUSITEM_H
|
||||
#define TOMAHAWK_APIV2_ACLJOBSTATUSITEM_H
|
||||
|
||||
#include "jobview/JobStatusItem.h"
|
||||
#include "web/Api2User.h"
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
namespace Tomahawk {
|
||||
namespace APIv2 {
|
||||
|
||||
class ACLJobStatusItem : public JobStatusItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ACLJobStatusItem( const QSharedPointer<Api2User>& user );
|
||||
virtual ~ACLJobStatusItem();
|
||||
|
||||
virtual int weight() const { return 99; }
|
||||
|
||||
virtual QString rightColumnText() const { return QString(); }
|
||||
virtual QString mainText() const { return QString(); }
|
||||
virtual QPixmap icon() const { return QPixmap(); }
|
||||
virtual QString type() const { return "apiv2-acljob"; }
|
||||
|
||||
virtual int concurrentJobLimit() const { return 3; }
|
||||
|
||||
virtual bool hasCustomDelegate() const { return true; }
|
||||
virtual void createDelegate( QObject* parent = 0 );
|
||||
virtual QStyledItemDelegate* customDelegate() const { return m_delegate; }
|
||||
|
||||
virtual QSharedPointer<Api2User> user() const { return m_user; }
|
||||
virtual QString name() const { return m_user->name(); }
|
||||
|
||||
signals:
|
||||
// void userDecision( QSharedPointer<Api2User> user );
|
||||
|
||||
public slots:
|
||||
// void aclResult( Api2User::ACLDecision );
|
||||
|
||||
private:
|
||||
QStyledItemDelegate* m_delegate;
|
||||
QSharedPointer<Api2User> m_user;
|
||||
};
|
||||
|
||||
} // namespace APIv2
|
||||
} // namespace Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_APIV2_ACLJOBSTATUSITEM_H
|
Reference in New Issue
Block a user