Implement user authentication for core login
[quassel.git] / src / client / coreconnection.cpp
index b2c040e..f290756 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #include "client.h"
+#include "clientsettings.h"
 #include "coreaccountmodel.h"
 #include "identity.h"
 #include "network.h"
@@ -37,6 +38,7 @@ CoreConnection::CoreConnection(CoreAccountModel *model, QObject *parent)
   : QObject(parent),
   _model(model),
   _blockSize(0),
+  _state(Disconnected),
   _progressMinimum(0),
   _progressMaximum(-1),
   _progressValue(-1)
@@ -45,10 +47,6 @@ CoreConnection::CoreConnection(CoreAccountModel *model, QObject *parent)
 
 }
 
-void CoreConnection::start() {
-  connectToCore(1);
-}
-
 void CoreConnection::init() {
   connect(Client::signalProxy(), SIGNAL(disconnected()), SLOT(coreSocketDisconnected()));
 }
@@ -101,6 +99,7 @@ void CoreConnection::resetConnection() {
 
   _netsToSync.clear();
   _numNetsToSync = 0;
+  _state = Disconnected;
 
   setProgressMaximum(-1); // disable
   emit connectionMsg(tr("Disconnected from core."));
@@ -230,25 +229,45 @@ void CoreConnection::coreHasData() {
 }
 
 void CoreConnection::disconnectFromCore() {
-  if(isConnected()) {
-    Client::signalProxy()->removeAllPeers();
-    resetConnection();
-  }
+  Client::signalProxy()->removeAllPeers();
+  resetConnection();
 }
 
 void CoreConnection::reconnectToCore() {
-
+  if(currentAccount().isValid())
+    connectToCore(currentAccount().accountId());
 }
 
-void CoreConnection::connectToCore(AccountId accId) {
-  resetConnection();
+bool CoreConnection::connectToCore(AccountId accId) {
+  if(isConnected())
+    return false;
+
+  CoreAccountSettings s;
+
+  if(!accId.isValid()) {
+    // check our settings and figure out what to do
+    if(!s.autoConnectOnStartup())
+      return false;
+    if(s.autoConnectToFixedAccount())
+      accId = s.autoConnectAccount();
+    else
+      accId = s.lastAccount();
+    if(!accId.isValid())
+      return false;
+  }
   _account = accountModel()->account(accId);
-
   if(!_account.accountId().isValid()) {
-    emit connectionError(tr("Invalid core account, cannot connect!"));
-    return;
+    return false;
   }
 
+  s.setLastAccount(accId);
+  connectToCurrentAccount();
+  return true;
+}
+
+void CoreConnection::connectToCurrentAccount() {
+  resetConnection();
+
   Q_ASSERT(!_socket);
 #ifdef HAVE_SSL
   QSslSocket *sock = new QSslSocket(Client::instance());
@@ -347,12 +366,14 @@ void CoreConnection::connectionReady() {
   resetWarningsHandler();
 }
 
-void CoreConnection::loginToCore() {
+void CoreConnection::loginToCore(const QString &prevError) {
   emit connectionMsg(tr("Logging in..."));
-  if(currentAccount().user().isEmpty() || currentAccount().password().isEmpty()) {
-    emit userAuthenticationRequired(&_account);  // *must* be a synchronous call
-    if(currentAccount().user().isEmpty() || currentAccount().password().isEmpty()) {
+  if(currentAccount().user().isEmpty() || currentAccount().password().isEmpty() || !prevError.isEmpty()) {
+    bool valid = false;
+    emit userAuthenticationRequired(&_account, &valid, prevError);  // *must* be a synchronous call
+    if(!valid || currentAccount().user().isEmpty() || currentAccount().password().isEmpty()) {
       disconnectFromCore();
+      emit connectionError(tr("Login canceled"));
       return;
     }
   }
@@ -365,16 +386,16 @@ void CoreConnection::loginToCore() {
 }
 
 void CoreConnection::loginFailed(const QString &error) {
-  emit userAuthenticationRequired(&_account, error);  // *must* be a synchronous call
-  if(currentAccount().user().isEmpty() || currentAccount().password().isEmpty()) {
-    disconnectFromCore();
-    return;
-  }
-  loginToCore();
+  loginToCore(error);
 }
 
 void CoreConnection::loginSuccess() {
   updateProgress(0, 0);
+
+  // save current account data
+  _model->createOrUpdateAccount(currentAccount());
+  _model->save();
+
   setProgressText(tr("Receiving session state"));
   setState(Synchronizing);
   emit connectionMsg(tr("Synchronizing to %1...").arg(currentAccount().accountName()));