~ubuntu-branches/ubuntu/saucy/clementine/saucy

« back to all changes in this revision

Viewing changes to src/remote/remotesettingspage.cpp

  • Committer: Package Import Robot
  • Author(s): Thomas PIERSON
  • Date: 2012-01-01 20:43:39 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120101204339-lsb6nndwhfy05sde
Tags: 1.0.1+dfsg-1
New upstream release. (Closes: #653926, #651611, #657391)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of Clementine.
 
2
   Copyright 2010, David Sansome <me@davidsansome.com>
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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/>.
 
16
*/
 
17
 
 
18
#include "remotesettingspage.h"
 
19
#include "ui_remotesettingspage.h"
 
20
#include "ui/iconloader.h"
 
21
 
 
22
#include <QCoreApplication>
 
23
#include <QHostInfo>
 
24
#include <QMessageBox>
 
25
#include <QNetworkReply>
 
26
#include <QSettings>
 
27
 
 
28
const char* kClientLoginUrl = "https://www.google.com/accounts/ClientLogin";
 
29
const char* RemoteSettingsPage::kSettingsGroup = "Remote";
 
30
 
 
31
RemoteSettingsPage::RemoteSettingsPage(SettingsDialog* dialog)
 
32
  : SettingsPage(dialog),
 
33
    ui_(new Ui_RemoteSettingsPage),
 
34
    waiting_for_auth_(false),
 
35
    network_(new NetworkAccessManager(this))
 
36
{
 
37
  ui_->setupUi(this);
 
38
  ui_->busy->hide();
 
39
  ui_->icon->setPixmap(IconLoader::Load("task-reject").pixmap(16));
 
40
  setWindowIcon(IconLoader::Load("network-server"));
 
41
 
 
42
  // Icons
 
43
  ui_->sign_out->setIcon(IconLoader::Load("list-remove"));
 
44
  ui_->sign_out->hide();
 
45
 
 
46
  connect(ui_->login, SIGNAL(clicked()), SLOT(Login()));
 
47
  connect(ui_->sign_out, SIGNAL(clicked()), SLOT(SignOut()));
 
48
 
 
49
  ui_->username->setMinimumWidth(QFontMetrics(QFont()).width("WWWWWWWWWWWW"));
 
50
  resize(sizeHint());
 
51
}
 
52
 
 
53
QString RemoteSettingsPage::DefaultAgentName() {
 
54
  return QString("%1 on %2").arg(QCoreApplication::applicationName(),
 
55
                                 QHostInfo::localHostName());
 
56
}
 
57
 
 
58
RemoteSettingsPage::~RemoteSettingsPage() {
 
59
  delete ui_;
 
60
}
 
61
 
 
62
void RemoteSettingsPage::Login() {
 
63
  ui_->busy->show();
 
64
  waiting_for_auth_ = true;
 
65
 
 
66
  ValidateGoogleAccount(ui_->username->text(), ui_->password->text());
 
67
}
 
68
 
 
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));
 
74
  QString post_data =
 
75
      "accountType=HOSTED_OR_GOOGLE&"
 
76
      "service=mail&"
 
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()));
 
82
}
 
83
 
 
84
void RemoteSettingsPage::LoginFinished() {
 
85
  QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
 
86
  Q_ASSERT(reply);
 
87
  reply->deleteLater();
 
88
  QString data = QString::fromUtf8(reply->readAll());
 
89
 
 
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]);
 
96
        return;
 
97
      }
 
98
    }
 
99
  }
 
100
  LoginComplete(QString::null);
 
101
}
 
102
 
 
103
void RemoteSettingsPage::LoginComplete(const QString& token) {
 
104
  if (!waiting_for_auth_)
 
105
    return; // Wasn't us that was waiting for auth
 
106
 
 
107
  const bool success = !token.isNull();
 
108
 
 
109
  ui_->busy->hide();
 
110
  waiting_for_auth_ = false;
 
111
 
 
112
  if (!success) {
 
113
    QMessageBox::warning(this, tr("Authentication failed"), tr("Your Google credentials were incorrect"));
 
114
  } else {
 
115
    QSettings s;
 
116
    s.beginGroup(kSettingsGroup);
 
117
    s.setValue("password", ui_->password->text());
 
118
    s.setValue("token", token);
 
119
    ui_->password->clear();
 
120
 
 
121
    //Save the other settings
 
122
    Save();
 
123
 
 
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();
 
128
  }
 
129
}
 
130
 
 
131
void RemoteSettingsPage::Load() {
 
132
  QSettings s;
 
133
  s.beginGroup(kSettingsGroup);
 
134
 
 
135
  ui_->username->setText(s.value("username").toString());
 
136
  ui_->agent_name->setText(s.value("agent_name", DefaultAgentName()).toString());
 
137
}
 
138
 
 
139
void RemoteSettingsPage::Save() {
 
140
  QSettings s;
 
141
  s.beginGroup(kSettingsGroup);
 
142
 
 
143
  s.setValue("username", ui_->username->text());
 
144
  s.setValue("agent_name", ui_->agent_name->text());
 
145
}
 
146
 
 
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();
 
154
 
 
155
  QSettings s;
 
156
  s.beginGroup(kSettingsGroup);
 
157
  s.setValue("password", QString());
 
158
}