1
/* This file is part of Clementine.
2
Copyright 2010, David Sansome <me@davidsansome.com>
4
Clementine is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
9
Clementine is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
18
#include "remotesettingspage.h"
19
#include "ui_remotesettingspage.h"
20
#include "ui/iconloader.h"
22
#include <QCoreApplication>
24
#include <QMessageBox>
25
#include <QNetworkReply>
28
const char* kClientLoginUrl = "https://www.google.com/accounts/ClientLogin";
29
const char* RemoteSettingsPage::kSettingsGroup = "Remote";
31
RemoteSettingsPage::RemoteSettingsPage(SettingsDialog* dialog)
32
: SettingsPage(dialog),
33
ui_(new Ui_RemoteSettingsPage),
34
waiting_for_auth_(false),
35
network_(new NetworkAccessManager(this))
39
ui_->icon->setPixmap(IconLoader::Load("task-reject").pixmap(16));
40
setWindowIcon(IconLoader::Load("network-server"));
43
ui_->sign_out->setIcon(IconLoader::Load("list-remove"));
44
ui_->sign_out->hide();
46
connect(ui_->login, SIGNAL(clicked()), SLOT(Login()));
47
connect(ui_->sign_out, SIGNAL(clicked()), SLOT(SignOut()));
49
ui_->username->setMinimumWidth(QFontMetrics(QFont()).width("WWWWWWWWWWWW"));
53
QString RemoteSettingsPage::DefaultAgentName() {
54
return QString("%1 on %2").arg(QCoreApplication::applicationName(),
55
QHostInfo::localHostName());
58
RemoteSettingsPage::~RemoteSettingsPage() {
62
void RemoteSettingsPage::Login() {
64
waiting_for_auth_ = true;
66
ValidateGoogleAccount(ui_->username->text(), ui_->password->text());
69
// Validates a Google account against ClientLogin and fetches a token usable for
70
// X-GOOGLE-TOKEN SASL authentication for Google Talk:
71
// http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#ClientLogin
72
void RemoteSettingsPage::ValidateGoogleAccount(const QString& username, const QString& password) {
73
QNetworkRequest request = QNetworkRequest(QUrl(kClientLoginUrl));
75
"accountType=HOSTED_OR_GOOGLE&"
77
"source=" + QUrl::toPercentEncoding(QCoreApplication::applicationName()) + "&"
78
"Email=" + QUrl::toPercentEncoding(username) + "&"
79
"Passwd=" + QUrl::toPercentEncoding(password);
80
QNetworkReply* reply = network_->post(request, post_data.toUtf8());
81
connect(reply, SIGNAL(finished()), SLOT(LoginFinished()));
84
void RemoteSettingsPage::LoginFinished() {
85
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
88
QString data = QString::fromUtf8(reply->readAll());
90
QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
91
if (reply->error() == QNetworkReply::NoError && status_code.isValid() && status_code.toInt() == 200) {
92
QStringList params = data.split('\n');
93
foreach (const QString& param, params) {
94
if (param.startsWith("Auth=")) {
95
LoginComplete(param.split('=')[1]);
100
LoginComplete(QString::null);
103
void RemoteSettingsPage::LoginComplete(const QString& token) {
104
if (!waiting_for_auth_)
105
return; // Wasn't us that was waiting for auth
107
const bool success = !token.isNull();
110
waiting_for_auth_ = false;
113
QMessageBox::warning(this, tr("Authentication failed"), tr("Your Google credentials were incorrect"));
116
s.beginGroup(kSettingsGroup);
117
s.setValue("password", ui_->password->text());
118
s.setValue("token", token);
119
ui_->password->clear();
121
//Save the other settings
124
ui_->login_details->hide();
125
ui_->icon->setPixmap(IconLoader::Load("task-complete").pixmap(16));
126
ui_->status->setText(QString(tr("You're logged in as <b>%1</b>")).arg(ui_->username->text()));
127
ui_->sign_out->show();
131
void RemoteSettingsPage::Load() {
133
s.beginGroup(kSettingsGroup);
135
ui_->username->setText(s.value("username").toString());
136
ui_->agent_name->setText(s.value("agent_name", DefaultAgentName()).toString());
139
void RemoteSettingsPage::Save() {
141
s.beginGroup(kSettingsGroup);
143
s.setValue("username", ui_->username->text());
144
s.setValue("agent_name", ui_->agent_name->text());
147
void RemoteSettingsPage::SignOut() {
148
ui_->username->clear();
149
ui_->password->clear();
150
ui_->sign_out->hide();
151
ui_->icon->setPixmap(IconLoader::Load("task-reject").pixmap(16));
152
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.")));
153
ui_->login_details->show();
156
s.beginGroup(kSettingsGroup);
157
s.setValue("password", QString());