Implement user authentication for core login
authorManuel Nickschas <sputnick@quassel-irc.org>
Tue, 24 Nov 2009 08:11:19 +0000 (09:11 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sat, 28 Nov 2009 23:39:41 +0000 (00:39 +0100)
We now popup a little dialog to allow the user entering user/password when
logging into a core with no or the wrong password.

src/client/coreconnection.cpp
src/client/coreconnection.h
src/qtui/CMakeLists.txt
src/qtui/coreconnectdlg.cpp
src/qtui/coreconnectdlg.h
src/qtui/mainwin.cpp
src/qtui/mainwin.h
src/qtui/ui/coreconnectauthdlg.ui [new file with mode: 0644]

index 863f1bd..f290756 100644 (file)
@@ -38,6 +38,7 @@ CoreConnection::CoreConnection(CoreAccountModel *model, QObject *parent)
   : QObject(parent),
   _model(model),
   _blockSize(0),
+  _state(Disconnected),
   _progressMinimum(0),
   _progressMaximum(-1),
   _progressValue(-1)
@@ -98,6 +99,7 @@ void CoreConnection::resetConnection() {
 
   _netsToSync.clear();
   _numNetsToSync = 0;
+  _state = Disconnected;
 
   setProgressMaximum(-1); // disable
   emit connectionMsg(tr("Disconnected from core."));
@@ -227,10 +229,8 @@ void CoreConnection::coreHasData() {
 }
 
 void CoreConnection::disconnectFromCore() {
-  if(isConnected()) {
-    Client::signalProxy()->removeAllPeers();
-    resetConnection();
-  }
+  Client::signalProxy()->removeAllPeers();
+  resetConnection();
 }
 
 void CoreConnection::reconnectToCore() {
@@ -366,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;
     }
   }
@@ -384,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()));
index 7a5d841..a74c12d 100644 (file)
@@ -85,7 +85,7 @@ signals:
   void startCoreSetup(const QVariantList &);
 
   // This signal MUST be handled synchronously!
-  void userAuthenticationRequired(CoreAccount *, const QString &errorMessage = QString());
+  void userAuthenticationRequired(CoreAccount *, bool *valid, const QString &errorMessage = QString());
 
   void handleIgnoreWarnings(bool permanently);
 
@@ -114,7 +114,7 @@ private slots:
   void connectionReady();
   //void doCoreSetup(const QVariant &setupData);
 
-  void loginToCore();
+  void loginToCore(const QString &previousError = QString());
   void loginSuccess();
   void loginFailed(const QString &errorMessage);
 
index 6e9626e..28e1b68 100644 (file)
@@ -119,6 +119,7 @@ set(FORMS
     coreconfigwizardadminuserpage.ui
     coreconfigwizardstorageselectionpage.ui
     coreconfigwizardsyncpage.ui
+    coreconnectauthdlg.ui
     coreinfodlg.ui
     debugbufferviewoverlay.ui
     debugconsole.ui
index 10ee20f..89f40a4 100644 (file)
@@ -60,3 +60,33 @@ void CoreConnectDlg::accept() {
   _settingsPage->save();
   QDialog::accept();
 }
+
+/******** CoreConnectAuthDlg ****************************************************************/
+
+CoreConnectAuthDlg::CoreConnectAuthDlg(CoreAccount *account, QWidget *parent)
+  : QDialog(parent),
+  _account(account)
+{
+  ui.setupUi(this);
+
+  connect(ui.user, SIGNAL(textChanged(QString)), SLOT(setButtonStates()));
+  connect(ui.password, SIGNAL(textChanged(QString)), SLOT(setButtonStates()));
+
+  ui.label->setText(tr("Please enter your credentials for %1:").arg(account->accountName()));
+  ui.user->setText(account->user());
+  ui.password->setText(account->password());
+  ui.rememberPasswd->setChecked(account->storePassword());
+}
+
+void CoreConnectAuthDlg::accept() {
+  _account->setUser(ui.user->text());
+  _account->setPassword(ui.password->text());
+  _account->setStorePassword(ui.rememberPasswd->isChecked());
+
+  QDialog::accept();
+}
+
+void CoreConnectAuthDlg::setButtonStates() {
+  bool valid = !(ui.user->text().isEmpty() || ui.password->text().isEmpty());
+  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
+}
index f7d29df..b892a20 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "coreaccount.h"
 
+#include "ui_coreconnectauthdlg.h"
+
 class CoreAccountSettingsPage;
 
 class CoreConnectDlg : public QDialog {
@@ -40,4 +42,20 @@ private:
   CoreAccountSettingsPage *_settingsPage;
 };
 
+class CoreConnectAuthDlg : public QDialog {
+  Q_OBJECT
+
+public:
+  CoreConnectAuthDlg(CoreAccount *account, QWidget *parent = 0);
+
+  void accept();
+
+private slots:
+  void setButtonStates();
+
+private:
+  Ui::CoreConnectAuthDlg ui;
+  CoreAccount *_account;
+};
+
 #endif
index 522766b..ed467cd 100644 (file)
@@ -158,6 +158,7 @@ void MainWin::init() {
            SLOT(messagesInserted(const QModelIndex &, int, int)));
   connect(GraphicalUi::contextMenuActionProvider(), SIGNAL(showChannelList(NetworkId)), SLOT(showChannelList(NetworkId)));
   connect(GraphicalUi::contextMenuActionProvider(), SIGNAL(showIgnoreList(QString)), SLOT(showIgnoreList(QString)));
+  connect(Client::coreConnection(), SIGNAL(userAuthenticationRequired(CoreAccount *, bool *, QString)), SLOT(userAuthenticationRequired(CoreAccount *, bool *, QString)));
 
   // Setup Dock Areas
   setDockNestingEnabled(true);
@@ -840,6 +841,12 @@ void MainWin::showCoreConnectionDlg() {
   }
 }
 
+void MainWin::userAuthenticationRequired(CoreAccount *account, bool *valid, const QString &errorMessage) {
+  Q_UNUSED(errorMessage)
+  CoreConnectAuthDlg dlg(account, this);
+  *valid = (dlg.exec() == QDialog::Accepted);
+}
+
 void MainWin::showChannelList(NetworkId netId) {
   ChannelListDlg *channelListDlg = new ChannelListDlg();
 
index a42c3f8..d14a7c6 100644 (file)
@@ -42,6 +42,7 @@ class BufferHotListFilter;
 class BufferView;
 class BufferViewConfig;
 class ClientBufferViewConfig;
+class CoreAccount;
 class CoreConnectionStatusWidget;
 class BufferViewDock;
 class BufferWidget;
@@ -119,6 +120,7 @@ class MainWin
     void showAboutDlg();
     void showChannelList(NetworkId netId = NetworkId());
     void startInternalCore();
+    void userAuthenticationRequired(CoreAccount *, bool *valid, const QString &errorMessage);
     void showCoreConnectionDlg();
     void showCoreInfoDlg();
     void showAwayLog();
diff --git a/src/qtui/ui/coreconnectauthdlg.ui b/src/qtui/ui/coreconnectauthdlg.ui
new file mode 100644 (file)
index 0000000..fb95687
--- /dev/null
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CoreConnectAuthDlg</class>
+ <widget class="QDialog" name="CoreConnectAuthDlg">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>395</width>
+    <height>183</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Authentication Required</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Please enter your account data:</string>
+     </property>
+     <property name="wordWrap">
+      <bool>false</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="user"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Password:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="password">
+       <property name="echoMode">
+        <enum>QLineEdit::Password</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Username:</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QCheckBox" name="rememberPasswd">
+     <property name="text">
+      <string>Remember password</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>CoreConnectAuthDlg</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>CoreConnectAuthDlg</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>