2011-02-17 14:47:54 +01:00
/* This file is part of Clementine.
Copyright 2010 , David Sansome < me @ davidsansome . com >
Clementine 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 .
Clementine 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 Clementine . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "remoteconfig.h"
# include "ui_remoteconfig.h"
# include "ui/iconloader.h"
2011-02-19 19:24:11 +01:00
# include <QCoreApplication>
# include <QHostInfo>
2011-02-17 14:47:54 +01:00
# include <QMessageBox>
# include <QNetworkReply>
# include <QSettings>
const char * kClientLoginUrl = " https://www.google.com/accounts/ClientLogin " ;
2011-02-17 15:34:45 +01:00
const char * RemoteConfig : : kSettingsGroup = " Remote " ;
2011-02-17 14:47:54 +01:00
RemoteConfig : : RemoteConfig ( QWidget * parent )
: QWidget ( parent ) ,
ui_ ( new Ui_RemoteConfig ) ,
waiting_for_auth_ ( false ) ,
2011-02-17 15:34:45 +01:00
network_ ( new NetworkAccessManager ( this ) )
2011-02-17 14:47:54 +01:00
{
ui_ - > setupUi ( this ) ;
ui_ - > busy - > hide ( ) ;
2011-05-09 22:37:14 +02:00
ui_ - > icon - > setPixmap ( IconLoader : : Load ( " task-reject " ) . pixmap ( 16 ) ) ;
2011-02-17 14:47:54 +01:00
// Icons
ui_ - > sign_out - > setIcon ( IconLoader : : Load ( " list-remove " ) ) ;
2011-05-09 21:54:04 +02:00
ui_ - > sign_out - > hide ( ) ;
2011-02-17 14:47:54 +01:00
2011-05-09 21:54:04 +02:00
connect ( ui_ - > login , SIGNAL ( clicked ( ) ) , SLOT ( Validate ( ) ) ) ;
2011-02-17 14:47:54 +01:00
connect ( ui_ - > sign_out , SIGNAL ( clicked ( ) ) , SLOT ( SignOut ( ) ) ) ;
ui_ - > username - > setMinimumWidth ( QFontMetrics ( QFont ( ) ) . width ( " WWWWWWWWWWWW " ) ) ;
resize ( sizeHint ( ) ) ;
}
2011-02-19 19:24:11 +01:00
QString RemoteConfig : : DefaultAgentName ( ) {
return QString ( " %1 on %2 " ) . arg ( QCoreApplication : : applicationName ( ) ,
QHostInfo : : localHostName ( ) ) ;
}
2011-02-17 14:47:54 +01:00
RemoteConfig : : ~ RemoteConfig ( ) {
delete ui_ ;
}
bool RemoteConfig : : NeedsValidation ( ) const {
return ! ui_ - > username - > text ( ) . isEmpty ( ) & & ! ui_ - > password - > text ( ) . isEmpty ( ) ;
}
void RemoteConfig : : Validate ( ) {
ui_ - > busy - > show ( ) ;
waiting_for_auth_ = true ;
ValidateGoogleAccount ( ui_ - > username - > text ( ) , ui_ - > password - > text ( ) ) ;
}
2011-03-01 17:18:55 +01:00
// Validates a Google account against ClientLogin and fetches a token usable for
// X-GOOGLE-TOKEN SASL authentication for Google Talk:
2011-02-17 14:47:54 +01:00
// http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#ClientLogin
void RemoteConfig : : ValidateGoogleAccount ( const QString & username , const QString & password ) {
QNetworkRequest request = QNetworkRequest ( QUrl ( kClientLoginUrl ) ) ;
QString post_data =
" accountType=HOSTED_OR_GOOGLE& "
" service=mail& "
" source= " + QUrl : : toPercentEncoding ( QCoreApplication : : applicationName ( ) ) + " & "
" Email= " + QUrl : : toPercentEncoding ( username ) + " & "
" Passwd= " + QUrl : : toPercentEncoding ( password ) ;
QNetworkReply * reply = network_ - > post ( request , post_data . toUtf8 ( ) ) ;
connect ( reply , SIGNAL ( finished ( ) ) , SLOT ( ValidateFinished ( ) ) ) ;
}
void RemoteConfig : : ValidateFinished ( ) {
QNetworkReply * reply = qobject_cast < QNetworkReply * > ( sender ( ) ) ;
Q_ASSERT ( reply ) ;
reply - > deleteLater ( ) ;
2011-03-01 17:03:04 +01:00
QString data = QString : : fromUtf8 ( reply - > readAll ( ) ) ;
QVariant status_code = reply - > attribute ( QNetworkRequest : : HttpStatusCodeAttribute ) ;
if ( reply - > error ( ) = = QNetworkReply : : NoError & & status_code . isValid ( ) & & status_code . toInt ( ) = = 200 ) {
QStringList params = data . split ( ' \n ' ) ;
foreach ( const QString & param , params ) {
if ( param . startsWith ( " Auth= " ) ) {
AuthenticationComplete ( param . split ( ' = ' ) [ 1 ] ) ;
return ;
}
}
2011-02-17 14:47:54 +01:00
}
2011-03-01 17:03:04 +01:00
AuthenticationComplete ( QString : : null ) ;
2011-02-17 14:47:54 +01:00
}
2011-03-01 17:03:04 +01:00
void RemoteConfig : : AuthenticationComplete ( const QString & token ) {
2011-02-17 14:47:54 +01:00
if ( ! waiting_for_auth_ )
return ; // Wasn't us that was waiting for auth
2011-03-01 17:03:04 +01:00
const bool success = ! token . isNull ( ) ;
2011-02-17 14:47:54 +01:00
ui_ - > busy - > hide ( ) ;
waiting_for_auth_ = false ;
2011-02-19 19:24:11 +01:00
if ( ! success ) {
2011-02-17 14:47:54 +01:00
QMessageBox : : warning ( this , tr ( " Authentication failed " ) , tr ( " Your Google credentials were incorrect " ) ) ;
2011-02-19 19:24:11 +01:00
} else {
QSettings s ;
s . beginGroup ( kSettingsGroup ) ;
s . setValue ( " password " , ui_ - > password - > text ( ) ) ;
2011-03-01 17:03:04 +01:00
s . setValue ( " token " , token ) ;
2011-02-19 19:24:11 +01:00
ui_ - > password - > clear ( ) ;
2011-02-17 14:47:54 +01:00
2011-05-09 21:54:04 +02:00
//Save the other settings
Save ( ) ;
ui_ - > login_details - > hide ( ) ;
2011-05-09 22:37:14 +02:00
ui_ - > icon - > setPixmap ( IconLoader : : Load ( " task-complete " ) . pixmap ( 16 ) ) ;
2011-05-09 21:54:04 +02:00
ui_ - > status - > setText ( QString ( tr ( " You're logged in as <b>%1</b> " ) ) . arg ( ui_ - > username - > text ( ) ) ) ;
ui_ - > sign_out - > show ( ) ;
}
2011-02-17 14:47:54 +01:00
}
void RemoteConfig : : Load ( ) {
QSettings s ;
s . beginGroup ( kSettingsGroup ) ;
2011-02-19 19:24:11 +01:00
ui_ - > username - > setText ( s . value ( " username " ) . toString ( ) ) ;
ui_ - > agent_name - > setText ( s . value ( " agent_name " , DefaultAgentName ( ) ) . toString ( ) ) ;
2011-02-17 14:47:54 +01:00
}
void RemoteConfig : : Save ( ) {
QSettings s ;
s . beginGroup ( kSettingsGroup ) ;
2011-02-19 19:24:11 +01:00
s . setValue ( " username " , ui_ - > username - > text ( ) ) ;
s . setValue ( " agent_name " , ui_ - > agent_name - > text ( ) ) ;
2011-02-17 14:47:54 +01:00
}
void RemoteConfig : : SignOut ( ) {
ui_ - > username - > clear ( ) ;
ui_ - > password - > clear ( ) ;
2011-05-09 21:54:04 +02:00
ui_ - > sign_out - > hide ( ) ;
2011-05-09 22:37:14 +02:00
ui_ - > icon - > setPixmap ( IconLoader : : Load ( " task-reject " ) . pixmap ( 16 ) ) ;
2011-05-09 21:54:04 +02:00
ui_ - > status - > setText ( QString ( tr ( " Clementine can be controlled remotely by an Android phone. To enable this feature log in with the same Google account that is configured on your phone. " ) ) ) ;
ui_ - > login_details - > show ( ) ;
2011-02-19 19:24:11 +01:00
QSettings s ;
s . beginGroup ( kSettingsGroup ) ;
s . setValue ( " password " , QString ( ) ) ;
2011-02-17 14:47:54 +01:00
}