1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/*
* Copyright (C) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
* @author Andre Moreira Magalhaes <andre.magalhaes@collabora.co.uk>
* Copyright (C) 2011 David Edmundson <kde@davidedmundson.co.uk>
* Copyright (C) 2011 Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "x-telepathy-password-auth-operation.h"
#include "x-telepathy-password-prompt.h"
#include <KDebug>
#include <KLocalizedString>
#include <KTp/wallet-interface.h>
XTelepathyPasswordAuthOperation::XTelepathyPasswordAuthOperation(
const Tp::AccountPtr &account,
Tp::Client::ChannelInterfaceSASLAuthenticationInterface *saslIface,
KTp::WalletInterface *walletInterface,
bool canTryAgain) :
Tp::PendingOperation(account),
m_account(account),
m_saslIface(saslIface),
m_walletInterface(walletInterface),
m_canTryAgain(canTryAgain)
{
connect(m_saslIface,
SIGNAL(SASLStatusChanged(uint,QString,QVariantMap)),
SLOT(onSASLStatusChanged(uint,QString,QVariantMap)));
}
XTelepathyPasswordAuthOperation::~XTelepathyPasswordAuthOperation()
{
}
void XTelepathyPasswordAuthOperation::onSASLStatusChanged(uint status, const QString &reason,
const QVariantMap &details)
{
if (status == Tp::SASLStatusNotStarted) {
kDebug() << "Requesting password";
promptUser(m_canTryAgain || !m_walletInterface->hasEntry(m_account, QLatin1String("lastLoginFailed")));
} else if (status == Tp::SASLStatusServerSucceeded) {
kDebug() << "Authentication handshake";
m_saslIface->AcceptSASL();
} else if (status == Tp::SASLStatusSucceeded) {
kDebug() << "Authentication succeeded";
if (m_walletInterface->hasEntry(m_account, QLatin1String("lastLoginFailed"))) {
m_walletInterface->removeEntry(m_account, QLatin1String("lastLoginFailed"));
}
setFinished();
} else if (status == Tp::SASLStatusInProgress) {
kDebug() << "Authenticating...";
} else if (status == Tp::SASLStatusServerFailed) {
kDebug() << "Error authenticating - reason:" << reason << "- details:" << details;
if (m_canTryAgain) {
kDebug() << "Retrying...";
promptUser(false);
} else {
kWarning() << "Authentication failed and cannot try again";
m_walletInterface->setEntry(m_account, QLatin1String("lastLoginFailed"), QLatin1String("true"));
// We cannot try again, but we can request again to set the account
// online. A new channel will be created, but since we set the
// lastLoginFailed entry, next time we will prompt for password
// and the user won't see any difference except for an
// authentication error notification
Tp::Presence requestedPresence = m_account->requestedPresence();
m_account->setRequestedPresence(requestedPresence);
QString errorMessage = details[QLatin1String("server-message")].toString();
setFinishedWithError(reason, errorMessage.isEmpty() ? i18n("Authentication error") : errorMessage);
}
}
}
void XTelepathyPasswordAuthOperation::promptUser(bool isFirstRun)
{
if (m_walletInterface->hasPassword(m_account) && isFirstRun) {
m_saslIface->StartMechanismWithData(QLatin1String("X-TELEPATHY-PASSWORD"),
m_walletInterface->password(m_account).toUtf8());
} else {
m_dialog = new XTelepathyPasswordPrompt(m_account, m_walletInterface);
connect(m_dialog.data(),
SIGNAL(finished(int)),
SLOT(onDialogFinished(int)));
m_dialog.data()->show();
}
}
void XTelepathyPasswordAuthOperation::onDialogFinished(int result)
{
switch (result) {
case QDialog::Rejected:
kDebug() << "Authentication cancelled";
m_saslIface->AbortSASL(Tp::SASLAbortReasonUserAbort, i18n("User cancelled auth"));
setFinished();
if (!m_dialog.isNull()) {
m_dialog.data()->deleteLater();
}
return;
case QDialog::Accepted:
// save password in kwallet if necessary...
if (!m_dialog.isNull()) {
if (m_dialog.data()->savePassword()) {
kDebug() << "Saving password in wallet";
m_walletInterface->setPassword(m_account, m_dialog.data()->password());
}
m_saslIface->StartMechanismWithData(QLatin1String("X-TELEPATHY-PASSWORD"), m_dialog.data()->password().toUtf8());
m_dialog.data()->deleteLater();
}
}
}
#include "x-telepathy-password-auth-operation.moc"
|