72
75
void ClearErrorStatus();
73
76
void RemoveFailures(const QSet<uint> &accountIds);
74
77
void ReportFailure(uint accountId, const QVariantMap ¬ification);
78
bool ReauthenticateAccount(uint accountId,
79
const QVariantMap &extraParameters);
77
82
void setErrorStatus();
78
83
void notifyPropertyChanged(const char *propertyName);
86
void onReauthenticatorFinished(bool success);
81
89
mutable IndicatorService *q_ptr;
82
90
WebcredentialsAdaptor *m_adaptor;
83
91
QSet<uint> m_failures;
92
QMap<uint, QList<AuthData> > m_failureClientData;
93
QMap<uint, Reauthenticator*> m_reauthenticators;
94
QDBusMessage m_clientMessage;
84
95
bool m_errorStatus;
112
123
void IndicatorServicePrivate::ReportFailure(uint accountId,
113
124
const QVariantMap ¬ification)
115
Q_UNUSED(notification);
117
126
m_failures.insert(accountId);
128
/* If the original client data is provided, we remember it: it can
129
* be used to replay the authentication later.
131
if (notification.contains("ClientData")) {
132
/* If the key is not found, the QMap's [] operator inserts an empty
133
* element in the map and return a reference to it. So the following
134
* line of code returns a valid QList even if the account never failed
137
QList<AuthData> &failedAuthentications =
138
m_failureClientData[accountId];
141
authData.sessionData = notification["ClientData"].toMap();
142
authData.identity = quint32(notification["Identity"].toUInt());
143
authData.method = notification["Method"].toString();
144
authData.mechanism = notification["Mechanism"].toString();
145
failedAuthentications.append(authData);
118
148
notifyPropertyChanged("Failures");
120
150
setErrorStatus();
153
bool IndicatorServicePrivate::ReauthenticateAccount(uint accountId,
154
const QVariantMap &extraParameters)
156
if (!m_failureClientData.contains(accountId)) {
157
/* Nothing we can do about this account */
158
TRACE() << "No reauthentication data for account" << accountId;
162
if (m_reauthenticators.contains(accountId)) {
163
/* A reauthenticator for this account is already at work. This
164
* shouldn't happen in a real world scenario. */
165
qWarning() << "Reauthenticator already active on" << accountId;
169
TRACE() << "Reauthenticating account" << accountId;
171
/* If we need to reauthenticate, we are delivering the result
172
* after iterating the event loop, so we must inform QtDBus that
173
* it shouldn't use this method's return value as a result.
175
setDelayedReply(true);
176
m_clientMessage = message();
177
QList<AuthData> &failedAuthentications = m_failureClientData[accountId];
179
Reauthenticator *reauthenticator =
180
new Reauthenticator(failedAuthentications, extraParameters, this);
181
m_reauthenticators[accountId] = reauthenticator;
183
QObject::connect(reauthenticator, SIGNAL(finished(bool)),
184
this, SLOT(onReauthenticatorFinished(bool)),
185
Qt::QueuedConnection);
186
reauthenticator->start();
188
return true; // ignored, see setDelayedReply() above.
123
191
void IndicatorServicePrivate::setErrorStatus()
125
193
/* Don't show more than one notification, until the error status is
145
213
QDBusConnection::sessionBus().send(signal);
216
void IndicatorServicePrivate::onReauthenticatorFinished(bool success)
218
Reauthenticator *reauthenticator =
219
qobject_cast<Reauthenticator*>(sender());
221
/* Find the account; searching a map by value is inefficient, but
222
* in this case it's extremely likely that the map contains just
223
* one element. :-) */
225
QMap<uint,Reauthenticator*>::const_iterator i;
226
for (i = m_reauthenticators.constBegin();
227
i != m_reauthenticators.constEnd();
229
if (i.value() == reauthenticator) {
234
Q_ASSERT (accountId != 0);
236
QDBusMessage reply = m_clientMessage.createReply(success);
237
QDBusConnection::sessionBus().send(reply);
240
m_failureClientData.remove(accountId);
241
m_failures.remove(accountId);
242
notifyPropertyChanged("Failures");
244
if (m_failures.isEmpty()) {
249
m_reauthenticators.remove(accountId);
250
reauthenticator->deleteLater();
148
253
IndicatorService::IndicatorService(QObject *parent):
150
255
d_ptr(new IndicatorServicePrivate(this))