defining SignonSessionCore as SignonDisposable and code optimization
[accounts-sso:vitalyrepins-signon.git] / src / signond / signonsessioncore.cpp
1 /*
2  * This file is part of signon
3  *
4  * Copyright (C) 2009-2010 Nokia Corporation.
5  *
6  * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * version 2.1 as published by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  */
22
23 #include "signond-common.h"
24 #include "signonauthsession.h"
25 #include "signonidentityinfo.h"
26 #include "signonidentity.h"
27 #include "signonauthsessionadaptor.h"
28 #include "signonui_interface.h"
29 #include "SignOn/uisessiondata_priv.h"
30
31 #include "SignOn/authpluginif.h"
32
33 #define MAX_IDLE_TIME SIGNOND_MAX_IDLE_TIME
34 /*
35  * the watchdog searches for idle sessions with period of half of idle timeout
36  * */
37 #define IDLE_WATCHDOG_TIMEOUT SIGNOND_MAX_IDLE_TIME * 500
38
39 using namespace SignonDaemonNS;
40
41 /*
42  * cache of session queues, as was mentined they cannot be static
43  * */
44 QMap<QString, SignonSessionCore *> sessionsOfStoredCredentials;
45 /*
46  * List of "zero" autsessions, needed for global signout
47  * */
48 QList<SignonSessionCore *> sessionsOfNonStoredCredentials;
49
50 static QVariantMap filterVariantMap(const QVariantMap &other)
51 {
52     QVariantMap result;
53
54     foreach(QString key, other.keys())
55     {
56         if (!other.value(key).isNull() && other.value(key).isValid())
57             result.insert(key, other.value(key));
58     }
59
60     return result;
61 }
62
63 static QString sessionName(const quint32 id, const QString &method)
64 {
65    return QString(id) + QLatin1String("+") + method;
66 }
67
68 SignonSessionCore::SignonSessionCore(quint32 id,
69                                      const QString &method,
70                                      int timeout,
71                                      SignonDaemon *parent) :
72                                      SignonDisposable(timeout, parent),
73                                      m_id(id),
74                                      m_method(method)
75 {
76     TRACE();
77     m_signonui = NULL;
78     m_watcher = NULL;
79
80     m_signonui = new SignonUiAdaptor(
81                                     SIGNON_UI_SERVICE,
82                                     SIGNON_UI_DAEMON_OBJECTPATH,
83                                     QDBusConnection::sessionBus());
84 }
85
86 SignonSessionCore::~SignonSessionCore()
87 {
88     TRACE();
89
90     delete m_plugin;
91     delete m_watcher;
92     delete m_signonui;
93
94     m_plugin = NULL;
95     m_signonui = NULL;
96     m_watcher = NULL;
97 }
98
99 SignonSessionCore *SignonSessionCore::sessionCore(const quint32 id, const QString &method, SignonDaemon *parent)
100 {
101     TRACE();
102     QString objectName;
103     QString key = sessionName(id, method);
104
105     if (id) {
106         if (sessionsOfStoredCredentials.contains(key)) {
107             return sessionsOfStoredCredentials.value(key);
108         }
109     }
110
111     SignonSessionCore *ssc = new SignonSessionCore(id, method, parent->authSessionTimeout(), parent);
112
113     if (ssc->setupPlugin() == false) {
114         TRACE() << "The resulted object is corrupted and has to be deleted";
115         delete ssc;
116         return NULL;
117     }
118
119     if (id)
120         sessionsOfStoredCredentials.insert(key, ssc);
121     else
122         sessionsOfNonStoredCredentials.append(ssc);
123
124     TRACE() << "The new session is created :" << key;
125     return ssc;
126 }
127
128 quint32 SignonSessionCore::id() const
129 {
130     TRACE();
131     keepInUse();
132     return m_id;
133 }
134
135 QString SignonSessionCore::method() const
136 {
137     TRACE();
138     keepInUse();
139     return m_method;
140 }
141
142 bool SignonSessionCore::setupPlugin()
143 {
144     m_plugin = PluginProxy::createNewPluginProxy(m_method);
145
146     if (!m_plugin) {
147         TRACE() << "Plugin of type " << m_method << " cannot be found";
148         return false;
149     }
150
151     connect(m_plugin,
152             SIGNAL(processResultReply(const QString&, const QVariantMap&)),
153             this,
154             SLOT(processResultReply(const QString&, const QVariantMap&)),
155             Qt::DirectConnection);
156
157     connect(m_plugin,
158             SIGNAL(processUiRequest(const QString&, const QVariantMap&)),
159             this,
160             SLOT(processUiRequest(const QString&, const QVariantMap&)),
161             Qt::DirectConnection);
162
163     connect(m_plugin,
164             SIGNAL(processRefreshRequest(const QString&, const QVariantMap&)),
165             this,
166             SLOT(processRefreshRequest(const QString&, const QVariantMap&)),
167             Qt::DirectConnection);
168
169     connect(m_plugin,
170             SIGNAL(processError(const QString&, int, const QString&)),
171             this,
172             SLOT(processError(const QString&, int, const QString&)),
173             Qt::DirectConnection);
174
175     connect(m_plugin,
176             SIGNAL(stateChanged(const QString&, int, const QString&)),
177             this,
178             SLOT(stateChangedSlot(const QString&, int, const QString&)),
179             Qt::DirectConnection);
180
181     return true;
182 }
183
184 void SignonSessionCore::stopAllAuthSessions()
185 {
186     qDeleteAll(sessionsOfStoredCredentials);
187     sessionsOfStoredCredentials.clear();
188
189     qDeleteAll(sessionsOfNonStoredCredentials);
190     sessionsOfNonStoredCredentials.clear();
191 }
192
193 QStringList SignonSessionCore::loadedPluginMethods(const QString &method)
194 {
195     foreach (SignonSessionCore *corePtr, sessionsOfStoredCredentials) {
196         if (corePtr->method() == method)
197             return corePtr->queryAvailableMechanisms(QStringList());
198     }
199
200     foreach (SignonSessionCore *corePtr, sessionsOfNonStoredCredentials) {
201         if (corePtr->method() == method)
202             return corePtr->queryAvailableMechanisms(QStringList());
203     }
204
205     return QStringList();
206 }
207
208 QStringList SignonSessionCore::queryAvailableMechanisms(const QStringList &wantedMechanisms)
209 {
210     keepInUse();
211
212     if (!wantedMechanisms.size())
213         return m_plugin->mechanisms();
214
215     return m_plugin->mechanisms().toSet().intersect(wantedMechanisms.toSet()).toList();
216 }
217
218 void SignonSessionCore::process(const QDBusConnection &connection,
219                                  const QDBusMessage &message,
220                                  const QVariantMap& sessionDataVa,
221                                  const QString& mechanism,
222                                  const QString& cancelKey)
223 {
224     TRACE();
225
226     keepInUse();
227
228     RequestData rd(connection, message, sessionDataVa, mechanism, cancelKey);
229     m_listOfRequests.enqueue(rd);
230
231     QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
232 }
233
234 void SignonSessionCore::cancel(const QString &cancelKey)
235 {
236     TRACE();
237
238     keepInUse();
239
240     int requestIndex;
241     for (requestIndex = 0; requestIndex < m_listOfRequests.size(); requestIndex++) {
242         if (m_listOfRequests.at(requestIndex).m_cancelKey == cancelKey)
243             break;
244     }
245
246     TRACE() << "The request is found with index " << requestIndex;
247
248     if (requestIndex < m_listOfRequests.size()) {
249         if (requestIndex == 0) {
250             m_canceled = cancelKey;
251             m_plugin->cancel();
252
253             if (m_watcher && !m_watcher->isFinished()) {
254                 m_signonui->cancelUiRequest(cancelKey);
255                 delete m_watcher;
256                 m_watcher = 0;
257             }
258         }
259
260         /*
261          * We must let to the m_listOfRequests to have the canceled request data
262          * in order to delay the next request execution until the actual cancelation
263          * will happen. We will know about that precisely: plugin must reply via
264          * resultSlot or via errorSlot.
265          * */
266         RequestData rd((requestIndex == 0 ?
267                         m_listOfRequests.head() :
268                         m_listOfRequests.takeAt(requestIndex)));
269
270         QDBusMessage errReply = rd.m_msg.createErrorReply(SIGNOND_SESSION_CANCELED_ERR_NAME,
271                                                           SIGNOND_SESSION_CANCELED_ERR_STR);
272         rd.m_conn.send(errReply);
273         TRACE() << "Size of the queue is " << m_listOfRequests.size();
274     }
275 }
276
277 void SignonSessionCore::setId(quint32 id)
278 {
279     keepInUse();
280
281     if (m_id == id)
282         return;
283
284     QString key;
285
286     if (id == 0)
287     {
288         key = sessionName(m_id, m_method);
289         sessionsOfNonStoredCredentials.append(sessionsOfStoredCredentials.take(key));
290     }
291     else
292     {
293         key = sessionName(id, m_method);
294         if (sessionsOfStoredCredentials.contains(key))
295         {
296             qCritical() << "attempt to assign existing id";
297             return;
298         }
299
300         sessionsOfNonStoredCredentials.removeOne(this);
301         sessionsOfStoredCredentials[key] = this;
302     }
303     m_id = id;
304 }
305
306 void SignonSessionCore::startProcess()
307 {
308     TRACE() << "the number of requests is : " << m_listOfRequests.length();
309
310     keepInUse();
311
312     RequestData data = m_listOfRequests.head();
313     QVariantMap parameters = data.m_params;
314
315     if (m_id) {
316         CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
317         if (db != NULL) {
318             SignonIdentityInfo info = db->credentials(m_id);
319             if (info.m_id != SIGNOND_NEW_IDENTITY) {
320                 /*
321                  * TODO: reconsider this code: maybe some more data is required
322                  * */
323                 parameters[QLatin1String("Secret")] = info.m_password;
324                 parameters[QLatin1String("UserName")] = info.m_userName;
325             } else {
326                 BLAME() << "Error occurred while getting data from credentials database.";
327                 /*
328                  * TODO: actual behavior should be clarified for this case
329                  * */
330             }
331         } else {
332             BLAME() << "Null database handler object.";
333         }
334     }
335
336     if (!m_plugin->process(data.m_cancelKey, parameters, data.m_mechanism)) {
337         QDBusMessage errReply = data.m_msg.createErrorReply(SIGNOND_RUNTIME_ERR_NAME,
338                                                             SIGNOND_RUNTIME_ERR_STR);
339         data.m_conn.send(errReply);
340         m_listOfRequests.removeFirst();
341         QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
342     } else
343         stateChangedSlot(data.m_cancelKey, SignOn::SessionStarted, QLatin1String("The request is started successfully"));
344 }
345
346 void SignonSessionCore::replyError(const QDBusConnection &conn, const QDBusMessage &msg, int err, const QString &message)
347 {
348     keepInUse();
349
350     QString errName;
351     QString errMessage;
352
353     //TODO - deprecated switch - remove if clause 1 moth after release of new error management
354     if(err < Error::AuthSessionErr) {
355         switch (err) {
356             case PLUGIN_ERROR_INVALID_STATE:
357                 errMessage = SIGNOND_WRONG_STATE_ERR_STR;
358                 errName = SIGNOND_WRONG_STATE_ERR_NAME;
359                 break;
360             case PLUGIN_ERROR_NOT_AUTHORIZED:
361                 errMessage = SIGNOND_INVALID_CREDENTIALS_ERR_STR;
362                 errName = SIGNOND_INVALID_CREDENTIALS_ERR_NAME;
363                 break;
364             case PLUGIN_ERROR_PERMISSION_DENIED:
365                 errMessage = SIGNOND_PERMISSION_DENIED_ERR_STR;
366                 errName = SIGNOND_PERMISSION_DENIED_ERR_NAME;
367                 break;
368             case PLUGIN_ERROR_NO_CONNECTION:
369                 errMessage = SIGNOND_NO_CONNECTION_ERR_STR;
370                 errName = SIGNOND_NO_CONNECTION_ERR_NAME;
371                 break;
372             case PLUGIN_ERROR_NETWORK_ERROR:
373                 errMessage = SIGNOND_NETWORK_ERR_STR;
374                 errName = SIGNOND_NETWORK_ERR_NAME;
375                 break;
376             case PLUGIN_ERROR_SSL_ERROR:
377                 errMessage = SIGNOND_SSL_ERR_STR;
378                 errName = SIGNOND_SSL_ERR_NAME;
379                 break;
380             case PLUGIN_ERROR_OPERATION_FAILED:
381                 errMessage = SIGNOND_OPERATION_FAILED_ERR_NAME;
382                 errName = SIGNOND_OPERATION_FAILED_ERR_NAME;
383                 break;
384              case PLUGIN_ERROR_MISSING_DATA:
385                 errMessage = SIGNOND_MISSING_DATA_ERR_STR;
386                 errName = SIGNOND_MISSING_DATA_ERR_NAME;
387                 break;
388             case PLUGIN_ERROR_MECHANISM_NOT_SUPPORTED:
389                 errMessage = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_STR;
390                 errName = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_NAME;
391                 break;
392             case PLUGIN_ERROR_RUNTIME:
393                 errMessage = SIGNOND_RUNTIME_ERR_STR;
394                 errName = SIGNOND_RUNTIME_ERR_NAME;
395                 break;
396             case PLUGIN_ERROR_USER_INTERACTION:
397                 errMessage = SIGNOND_USER_INTERACTION_ERR_STR;
398                 errName = SIGNOND_USER_INTERACTION_ERR_NAME;
399                 break;
400             case PLUGIN_ERROR_CANCELED:
401                 errMessage = SIGNOND_SESSION_CANCELED_ERR_STR;
402                 errName = SIGNOND_SESSION_CANCELED_ERR_NAME;
403                 break;
404             default:
405                 if (message.isEmpty())
406                     errMessage = SIGNOND_UNKNOWN_ERR_STR;
407                 else
408                     errMessage = message;
409                 errName = SIGNOND_UNKNOWN_ERR_NAME;
410                 break;
411         };
412     }
413
414     if (Error::AuthSessionErr < err && err < Error::UserErr) {
415         switch(err) {
416             case Error::MechanismNotAvailable:
417                 errName = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_NAME;
418                 errMessage = SIGNOND_MECHANISM_NOT_AVAILABLE_ERR_STR;
419                 break;
420             case Error::MissingData:
421                 errName = SIGNOND_MISSING_DATA_ERR_NAME;
422                 errMessage = SIGNOND_MISSING_DATA_ERR_STR;
423                 break;
424             case Error::InvalidCredentials:
425                 errName = SIGNOND_INVALID_CREDENTIALS_ERR_NAME;
426                 errMessage = SIGNOND_INVALID_CREDENTIALS_ERR_STR;
427                 break;
428             case Error::NotAuthorized:
429                 errName = SIGNOND_NOT_AUTHORIZED_ERR_NAME;
430                 errMessage = SIGNOND_NOT_AUTHORIZED_ERR_STR;
431                 break;
432             case Error::WrongState:
433                 errName = SIGNOND_WRONG_STATE_ERR_NAME;
434                 errMessage = SIGNOND_WRONG_STATE_ERR_STR;
435                 break;
436             case Error::OperationNotSupported:
437                 errName = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_NAME;
438                 errMessage = SIGNOND_OPERATION_NOT_SUPPORTED_ERR_STR;
439                 break;
440             case Error::NoConnection:
441                 errName = SIGNOND_NO_CONNECTION_ERR_NAME;
442                 errMessage = SIGNOND_NO_CONNECTION_ERR_STR;
443                 break;
444             case Error::Network:
445                 errName = SIGNOND_NETWORK_ERR_NAME;
446                 errMessage = SIGNOND_NETWORK_ERR_STR;
447                 break;
448             case Error::Ssl:
449                 errName = SIGNOND_SSL_ERR_NAME;
450                 errMessage = SIGNOND_SSL_ERR_STR;
451                 break;
452             case Error::Runtime:
453                 errName = SIGNOND_RUNTIME_ERR_NAME;
454                 errMessage = SIGNOND_RUNTIME_ERR_STR;
455                 break;
456             case Error::SessionCanceled:
457                 errName = SIGNOND_SESSION_CANCELED_ERR_NAME;
458                 errMessage = SIGNOND_SESSION_CANCELED_ERR_STR;
459                 break;
460             case Error::TimedOut:
461                 errName = SIGNOND_TIMED_OUT_ERR_NAME;
462                 errMessage = SIGNOND_TIMED_OUT_ERR_STR;
463                 break;
464             case Error::UserInteraction:
465                 errName = SIGNOND_USER_INTERACTION_ERR_NAME;
466                 errMessage = SIGNOND_USER_INTERACTION_ERR_STR;
467                 break;
468             case Error::OperationFailed:
469                 errName = SIGNOND_OPERATION_FAILED_ERR_NAME;
470                 errMessage = SIGNOND_OPERATION_FAILED_ERR_STR;
471                 break;
472             default:
473                 if (message.isEmpty())
474                     errMessage = SIGNOND_UNKNOWN_ERR_STR;
475                 else
476                     errMessage = message;
477                 errName = SIGNOND_UNKNOWN_ERR_NAME;
478                 break;
479         };
480     }
481
482     if(err > Error::UserErr) {
483         errName = SIGNOND_USER_ERROR_ERR_NAME;
484         errMessage = (QString::fromLatin1("%1:%2")).arg(err).arg(message);
485     }
486
487     QDBusMessage errReply;
488     errReply = msg.createErrorReply(errName, ( message.isEmpty() ? errMessage : message ));
489     conn.send(errReply);
490 }
491
492 void SignonSessionCore::processResultReply(const QString &cancelKey, const QVariantMap &data)
493 {
494     TRACE();
495
496     keepInUse();
497
498     if (!m_listOfRequests.size())
499         return;
500
501     RequestData rd = m_listOfRequests.dequeue();
502
503     if (cancelKey != m_canceled) {
504         QVariantList arguments;
505         QVariantMap data2 = filterVariantMap(data);
506
507         if (m_method != QLatin1String("password") && data2.contains(QLatin1String("Secret")))
508             data2.remove(QLatin1String("Secret"));
509
510         arguments << data2;
511
512         TRACE() << "sending reply: " << arguments;
513         rd.m_conn.send(rd.m_msg.createReply(arguments));
514         m_canceled = QString();
515
516         if (m_watcher && !m_watcher->isFinished()) {
517             m_signonui->cancelUiRequest(rd.m_cancelKey);
518             delete m_watcher;
519             m_watcher = 0;
520         }
521     }
522
523     m_canceled = QString();
524     QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
525 }
526
527 void SignonSessionCore::processUiRequest(const QString &cancelKey, const QVariantMap &data)
528 {
529     TRACE();
530
531     keepInUse();
532
533     if (cancelKey != m_canceled && m_listOfRequests.size()) {
534         QString uiRequestId = m_listOfRequests.head().m_cancelKey;
535
536         if (m_watcher) {
537             if (!m_watcher->isFinished())
538                 m_signonui->cancelUiRequest(uiRequestId);
539
540             delete m_watcher;
541             m_watcher = 0;
542         }
543
544         m_listOfRequests.head().m_params = filterVariantMap(data);
545         m_listOfRequests.head().m_params[SSOUI_KEY_REQUESTID] = uiRequestId;
546
547         if (m_id == SIGNOND_NEW_IDENTITY)
548             m_listOfRequests.head().m_params[SSOUI_KEY_STORED_IDENTITY] = false;
549         else
550             m_listOfRequests.head().m_params[SSOUI_KEY_STORED_IDENTITY] = true;
551
552         //TODO: figure out how we going to synchronize
553         //different login dialogs in order not to show
554         //multiple login dialogs for the same credentials
555         //data2["CredentialsId"] = m_id;
556         m_watcher = new QDBusPendingCallWatcher(m_signonui->queryDialog(m_listOfRequests.head().m_params),
557                                                 this);
558         connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
559     }
560 }
561
562 void SignonSessionCore::processRefreshRequest(const QString &cancelKey, const QVariantMap &data)
563 {
564     TRACE();
565
566     keepInUse();
567
568     if (cancelKey != m_canceled && m_listOfRequests.size()) {
569         QString uiRequestId = m_listOfRequests.head().m_cancelKey;
570
571         if (m_watcher) {
572             if (!m_watcher->isFinished())
573                 m_signonui->cancelUiRequest(uiRequestId);
574
575             delete m_watcher;
576             m_watcher = 0;
577         }
578
579         m_listOfRequests.head().m_params = filterVariantMap(data);
580         m_watcher = new QDBusPendingCallWatcher(m_signonui->refreshDialog(m_listOfRequests.head().m_params),
581                                                 this);
582         connect(m_watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(queryUiSlot(QDBusPendingCallWatcher*)));
583     }
584 }
585
586 void SignonSessionCore::processError(const QString &cancelKey, int err, const QString &message)
587 {
588     TRACE();
589     keepInUse();
590
591     if (!m_listOfRequests.size())
592         return;
593
594     RequestData rd = m_listOfRequests.dequeue();
595
596     if (cancelKey != m_canceled) {
597         replyError(rd.m_conn, rd.m_msg, err, message);
598
599         if (m_watcher && !m_watcher->isFinished()) {
600             m_signonui->cancelUiRequest(rd.m_cancelKey);
601             delete m_watcher;
602             m_watcher = 0;
603         }
604     }
605
606     m_canceled = QString();
607     QMetaObject::invokeMethod(this, "startNewRequest", Qt::QueuedConnection);
608 }
609
610 void SignonSessionCore::stateChangedSlot(const QString &cancelKey, int state, const QString &message)
611 {
612     if (cancelKey != m_canceled && m_listOfRequests.size()) {
613         RequestData rd = m_listOfRequests.head();
614         emit stateChanged(rd.m_cancelKey, (int)state, message);
615     }
616
617     keepInUse();
618 }
619
620 void SignonSessionCore::childEvent(QChildEvent *ce)
621 {
622     TRACE();
623     if (ce->added())
624         keepInUse();
625 }
626
627 void SignonSessionCore::queryUiSlot(QDBusPendingCallWatcher *call)
628 {
629     keepInUse();
630
631     QDBusPendingReply<QVariantMap> reply = *call;
632     bool isRequestToRefresh = false;
633     Q_ASSERT_X( m_listOfRequests.size() != 0, __func__, "queue of requests is empty");
634
635     if (!reply.isError() && reply.count()) {
636         QVariantMap resultParameters = reply.argumentAt<0>();
637         if (resultParameters.contains(SSOUI_KEY_REFRESH)) {
638             isRequestToRefresh = true;
639             resultParameters.remove(SSOUI_KEY_REFRESH);
640         }
641
642         if (m_id != SIGNOND_NEW_IDENTITY) {
643             CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
644             if (db != NULL) {
645                 SignonIdentityInfo info = db->credentials(m_id);
646
647                 info.m_userName = resultParameters[SSOUI_KEY_USERNAME].toString();
648                 info.m_password = resultParameters[SSOUI_KEY_PASSWORD].toString();
649
650                 if (!(db->updateCredentials(info)))
651                     TRACE() << "Error occured while updating credentials.";
652             }
653
654         } else {
655                 BLAME() << "Error occured while updating credentials. Null database handler object.";
656         }
657
658         m_listOfRequests.head().m_params = resultParameters;
659     } else {
660         m_listOfRequests.head().m_params.insert(SSOUI_KEY_ERROR, (int)SignOn::QUERY_ERROR_NO_SIGNONUI);
661     }
662
663     TRACE() << m_listOfRequests.head().m_params;
664
665     if (m_listOfRequests.head().m_cancelKey != m_canceled) {
666         if (isRequestToRefresh) {
667             TRACE() << "REFRESH IS REQUIRED";
668
669             m_listOfRequests.head().m_params.remove(SSOUI_KEY_REFRESH);
670             m_plugin->processRefresh(m_listOfRequests.head().m_cancelKey,
671                                      m_listOfRequests.head().m_params);
672         } else {
673             m_plugin->processUi(m_listOfRequests.head().m_cancelKey,
674                                 m_listOfRequests.head().m_params);
675         }
676     }
677
678     delete m_watcher;
679     m_watcher = NULL;
680 }
681
682 void SignonSessionCore::startNewRequest()
683 {
684     keepInUse();
685
686     // there is no request
687     if (!m_listOfRequests.length()) {
688         TRACE() << "the data queue is EMPTY!!!";
689         return;
690     }
691
692     //plugin is busy
693     if (m_plugin && m_plugin->isProcessing()) {
694         TRACE() << " the plugin is in challenge processing";
695         return;
696     }
697
698     //there is some UI operation with plugin
699     if (m_watcher && !m_watcher->isFinished()) {
700         TRACE() << "watcher is in running mode";
701         return;
702     }
703
704     TRACE() << "Start the authentication process";
705     startProcess();
706 }
707
708 void SignonSessionCore::destroy()
709 {
710     if (m_plugin->isProcessing() ||
711         m_watcher != NULL)
712     {
713         keepInUse();
714         return;
715     }
716
717     deleteLater();
718 }