From cf7d3423ccf02f1c703c11b6daf5bff5086e45ab Mon Sep 17 00:00:00 2001
From: Inso <insomniak.fr@gmail.com>
Date: Thu, 1 Jan 2015 20:50:56 +0100
Subject: [PATCH] Added password remembering mechanism

New dialog created : PasswordDialogAsker
Needs to be passed throught the Widgets managing the current account
---
 res/ui/mainwindow.ui               |  7 ---
 res/ui/password_asker.ui           | 85 ++++++++++++++++++++++++++++++
 src/cutecoin/gui/certification.py  | 20 ++-----
 src/cutecoin/gui/community_tab.py  | 10 ++--
 src/cutecoin/gui/currency_tab.py   | 39 ++++++++++++--
 src/cutecoin/gui/mainwindow.py     | 60 ++++++---------------
 src/cutecoin/gui/password_asker.py | 51 ++++++++++++++++++
 src/cutecoin/gui/transfer.py       | 16 ++----
 src/cutecoin/gui/wot_tab.py        |  7 +--
 9 files changed, 203 insertions(+), 92 deletions(-)
 create mode 100644 res/ui/password_asker.ui
 create mode 100644 src/cutecoin/gui/password_asker.py

diff --git a/res/ui/mainwindow.ui b/res/ui/mainwindow.ui
index 8c5588e0..81702a0e 100644
--- a/res/ui/mainwindow.ui
+++ b/res/ui/mainwindow.ui
@@ -15,13 +15,6 @@
   </property>
   <widget class="QWidget" name="centralwidget">
    <layout class="QVBoxLayout" name="verticalLayout_6">
-    <item>
-     <widget class="QLabel" name="label_account_name">
-      <property name="text">
-       <string>Please select an account</string>
-      </property>
-     </widget>
-    </item>
     <item>
      <widget class="QTabWidget" name="currencies_tabwidget">
       <property name="iconSize">
diff --git a/res/ui/password_asker.ui b/res/ui/password_asker.ui
new file mode 100644
index 00000000..867a88a5
--- /dev/null
+++ b/res/ui/password_asker.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasswordAskerDialog</class>
+ <widget class="QDialog" name="PasswordAskerDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>274</width>
+    <height>99</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Password</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLineEdit" name="edit_password">
+     <property name="echoMode">
+      <enum>QLineEdit::Password</enum>
+     </property>
+     <property name="placeholderText">
+      <string>Please enter your account password</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QCheckBox" name="check_remember">
+       <property name="text">
+        <string>Remember my password during this session</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </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>PasswordAskerDialog</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>PasswordAskerDialog</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>
diff --git a/src/cutecoin/gui/certification.py b/src/cutecoin/gui/certification.py
index d31c00ff..4a3f4c3c 100644
--- a/src/cutecoin/gui/certification.py
+++ b/src/cutecoin/gui/certification.py
@@ -16,13 +16,14 @@ class CertificationDialog(QDialog, Ui_CertificationDialog):
     classdocs
     '''
 
-    def __init__(self, certifier):
+    def __init__(self, certifier, password_asker):
         '''
         Constructor
         '''
         super().__init__()
         self.setupUi(self)
         self.certifier = certifier
+        self.password_asker = password_asker
         self.community = self.certifier.communities[0]
 
         for community in self.certifier.communities:
@@ -38,22 +39,7 @@ class CertificationDialog(QDialog, Ui_CertificationDialog):
         else:
             pubkey = self.edit_pubkey.text()
 
-        password = QInputDialog.getText(self, "Account password",
-                                        "Please enter your password",
-                                        QLineEdit.Password)
-        if password[1] is True:
-            password = password[0]
-        else:
-            return
-
-        while not self.certifier.check_password(password):
-            password = QInputDialog.getText(self, "Account password",
-                                            "Wrong password.\nPlease enter your password",
-                                            QLineEdit.Password)
-            if password[1] is True:
-                password = password[0]
-            else:
-                return
+        password = self.password_asker.ask()
 
         try:
             self.certifier.certify(password, self.community, pubkey)
diff --git a/src/cutecoin/gui/community_tab.py b/src/cutecoin/gui/community_tab.py
index 04538790..4165abd3 100644
--- a/src/cutecoin/gui/community_tab.py
+++ b/src/cutecoin/gui/community_tab.py
@@ -22,7 +22,7 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
     classdocs
     '''
 
-    def __init__(self, account, community):
+    def __init__(self, account, community, password_asker):
         '''
         Constructor
         '''
@@ -30,6 +30,7 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         self.setupUi(self)
         self.community = community
         self.account = account
+        self.password_asker = password_asker
         self.list_community_members.setModel(MembersListModel(community))
 
         if self.account.member_of(self.community):
@@ -39,7 +40,8 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
             self.button_membership.setText("Send membership demand")
             self.button_membership.clicked.connect(self.send_membership_demand)
 
-        self.tabs_information.addTab(WotTabWidget(account, community),
+        self.tabs_information.addTab(WotTabWidget(account, community,
+                                                  password_asker),
                                      QIcon(':/icons/wot_icon'),
                                      "Wot")
 
@@ -77,7 +79,7 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         dialog.exec_()
 
     def send_money_to_member(self):
-        dialog = TransferMoneyDialog(self.account)
+        dialog = TransferMoneyDialog(self.account, self.password_asker)
         person = self.sender().data()
         dialog.edit_pubkey.setText(person.pubkey)
         dialog.combo_community.setCurrentText(self.community.name())
@@ -85,7 +87,7 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         dialog.exec_()
 
     def certify_member(self):
-        dialog = CertificationDialog(self.account)
+        dialog = CertificationDialog(self.account, self.password_asker)
         person = self.sender().data()
         dialog.edit_pubkey.setText(person.pubkey)
         dialog.radio_pubkey.setChecked(True)
diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py
index df6adf0b..8223cc65 100644
--- a/src/cutecoin/gui/currency_tab.py
+++ b/src/cutecoin/gui/currency_tab.py
@@ -5,9 +5,11 @@ Created on 2 févr. 2014
 '''
 
 import logging
+import time
+
 from ucoinpy.api import bma
 from PyQt5.QtWidgets import QWidget, QMenu, QAction, QApplication
-from PyQt5.QtCore import QModelIndex, Qt, pyqtSlot
+from PyQt5.QtCore import QModelIndex, Qt, pyqtSlot, QThread, pyqtSignal
 from PyQt5.QtGui import QIcon
 from ..gen_resources.currency_tab_uic import Ui_CurrencyTabWidget
 from .community_tab import CommunityTabWidget
@@ -17,13 +19,37 @@ from ..models.wallets import WalletsListModel
 from ..models.wallet import WalletListModel
 
 
+class BlockchainInspector(QThread):
+    def __init__(self, community):
+        QThread.__init__(self)
+        self.community = community
+        self.exiting = False
+        self.last_block = self.community.request(bma.blockchain.Current)['number']
+
+    def __del__(self):
+        self.exiting = True
+        self.wait()
+
+    def run(self):
+        while not self.exiting:
+            time.sleep(10)
+            current_block = self.community.request(bma.blockchain.Current)
+            if self.last_block != current_block['number']:
+                logging.debug("New block, {0} mined in {1}".format(self.last_block,
+                                                                   self.community.currency))
+                self.new_block_mined.emit(current_block['number'])
+                self.last_block = current_block['number']
+
+    new_block_mined = pyqtSignal(int)
+
+
 class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
 
     '''
     classdocs
     '''
 
-    def __init__(self, app, community):
+    def __init__(self, app, community, password_asker):
         '''
         Constructor
         '''
@@ -31,8 +57,13 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
         self.setupUi(self)
         self.app = app
         self.community = community
+        self.password_asker = password_asker
         self.tab_community = CommunityTabWidget(self.app.current_account,
-                                                    self.community)
+                                                    self.community,
+                                                    self.password_asker)
+        bc_inspector = BlockchainInspector(community)
+        bc_inspector.new_block_mined.connect(self.refresh_block)
+        bc_inspector.start()
 
     def refresh(self):
         if self.app.current_account is None:
@@ -46,7 +77,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
             self.list_transactions_received.setModel(
                 ReceivedListModel(self.app.current_account, self.community))
             self.tab_community = CommunityTabWidget(self.app.current_account,
-                                                    self.community)
+                                                    self.community, self.password_asker)
             self.tabs_account.addTab(self.tab_community,
                                      QIcon(':/icons/community_icon'),
                                     "Community")
diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py
index 8add61f6..c529a3f8 100644
--- a/src/cutecoin/gui/mainwindow.py
+++ b/src/cutecoin/gui/mainwindow.py
@@ -7,41 +7,13 @@ from cutecoin.gen_resources.mainwindow_uic import Ui_MainWindow
 from PyQt5.QtWidgets import QMainWindow, QAction, QFileDialog
 from PyQt5.QtCore import QSignalMapper, QModelIndex, QThread, pyqtSignal
 from PyQt5.QtGui import QIcon
-from cutecoin.gui.process_cfg_account import ProcessConfigureAccount
-from cutecoin.gui.transfer import TransferMoneyDialog
-from cutecoin.gui.currency_tab import CurrencyTabWidget
-from cutecoin.gui.add_contact import AddContactDialog
-from cutecoin.gui.import_account import ImportAccountDialog
-from cutecoin.gui.certification import CertificationDialog
-
-from ucoinpy.api import bma
-
-import logging
-import time
-
-
-class BlockchainInspector(QThread):
-    def __init__(self, community):
-        QThread.__init__(self)
-        self.community = community
-        self.exiting = False
-        self.last_block = self.community.request(bma.blockchain.Current)['number']
-
-    def __del__(self):
-        self.exiting = True
-        self.wait()
-
-    def run(self):
-        while not self.exiting:
-            time.sleep(10)
-            current_block = self.community.request(bma.blockchain.Current)
-            if self.last_block != current_block['number']:
-                logging.debug("New block, {0} mined in {1}".format(self.last_block,
-                                                                   self.community.currency))
-                self.new_block_mined.emit(current_block)
-                self.last_block = current_block['number']
-
-    new_block_mined = pyqtSignal(int)
+from .process_cfg_account import ProcessConfigureAccount
+from .transfer import TransferMoneyDialog
+from .currency_tab import CurrencyTabWidget
+from .add_contact import AddContactDialog
+from .import_account import ImportAccountDialog
+from .certification import CertificationDialog
+from .password_asker import PasswordAskerDialog
 
 
 class MainWindow(QMainWindow, Ui_MainWindow):
@@ -58,6 +30,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         super().__init__()
         self.setupUi(self)
         self.app = app
+        self.password_asker = None
         self.refresh()
 
     def open_add_account_dialog(self):
@@ -70,7 +43,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.refresh()
 
     def open_transfer_money_dialog(self):
-        dialog = TransferMoneyDialog(self.app.current_account)
+        dialog = TransferMoneyDialog(self.app.current_account,
+                                     self.password_asker)
         dialog.accepted.connect(self.refresh_wallets)
         dialog.exec_()
         currency_tab = self.currencies_tabwidget.currentWidget()
@@ -79,7 +53,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
                                                              QModelIndex(), ())
 
     def open_certification_dialog(self):
-        dialog = CertificationDialog(self.app.current_account)
+        dialog = CertificationDialog(self.app.current_account,
+                                     self.password_asker)
         dialog.exec_()
 
     def open_add_contact_dialog(self):
@@ -115,18 +90,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self.menu_contacts.setEnabled(False)
             self.menu_actions.setEnabled(False)
         else:
+            self.password_asker = PasswordAskerDialog(self.app.current_account)
             self.menu_contacts.setEnabled(True)
             self.menu_actions.setEnabled(True)
-            self.label_account_name.setText(
-                "Current account : " +
-                self.app.current_account.name)
+            self.setWindowTitle("CuteCoin - Account : {0}".format(
+                self.app.current_account.name))
 
             self.currencies_tabwidget.clear()
             for community in self.app.current_account.communities:
-                tab_currency = CurrencyTabWidget(self.app, community)
-                bc_inspector = BlockchainInspector(community)
-                bc_inspector.new_block_mined.connect(tab_currency.refresh_block)
-                bc_inspector.start()
+                tab_currency = CurrencyTabWidget(self.app, community, self.password_asker)
                 tab_currency.refresh()
                 self.currencies_tabwidget.addTab(tab_currency,
                                                  QIcon(":/icons/currency_icon"),
diff --git a/src/cutecoin/gui/password_asker.py b/src/cutecoin/gui/password_asker.py
new file mode 100644
index 00000000..945e9567
--- /dev/null
+++ b/src/cutecoin/gui/password_asker.py
@@ -0,0 +1,51 @@
+'''
+Created on 24 dec. 2014
+
+@author: inso
+'''
+
+import logging
+
+from PyQt5.QtWidgets import QDialog, QMessageBox
+
+from ..gen_resources.password_asker_uic import Ui_PasswordAskerDialog
+
+
+class PasswordAskerDialog(QDialog, Ui_PasswordAskerDialog):
+
+    '''
+    A dialog to get password.
+    '''
+
+    def __init__(self, account):
+        '''
+        Constructor
+        '''
+        super().__init__()
+        self.setupUi(self)
+        self.account = account
+        self.password = ""
+        self.remember = False
+
+    def ask(self):
+        if not self.remember:
+            self.exec_()
+            pwd = self.password
+            if not self.remember:
+                self.password = ""
+            return pwd
+        else:
+            return self.password
+
+    def accept(self):
+        password = self.edit_password.text()
+        if self.account.check_password(password):
+            self.remember = self.check_remember.isChecked()
+            self.password = password
+
+            self.accepted.emit()
+            self.close()
+        else:
+            QMessageBox.warning(self, "Failed to get private key",
+                                "Wrong password typed. Cannot open the private key",
+                                QMessageBox.Ok)
diff --git a/src/cutecoin/gui/transfer.py b/src/cutecoin/gui/transfer.py
index cbdbafa6..1c952f94 100644
--- a/src/cutecoin/gui/transfer.py
+++ b/src/cutecoin/gui/transfer.py
@@ -17,13 +17,14 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
     classdocs
     '''
 
-    def __init__(self, sender):
+    def __init__(self, sender, password_asker):
         '''
         Constructor
         '''
         super().__init__()
         self.setupUi(self)
         self.sender = sender
+        self.password_asker = password_asker
         self.recipient_trusts = []
         self.wallet = None
         self.community = self.sender.communities[0]
@@ -49,18 +50,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog):
             recipient = self.edit_pubkey.text()
         amount = self.spinbox_amount.value()
 
-        password = ""
-        message = "Please enter your password"
-
-        while not self.sender.check_password(password):
-            password = QInputDialog.getText(self, "Account password",
-                        message,
-                        QLineEdit.Password)
-            message = "Error, wrong password. Please enter your password"
-            if password[1] is True:
-                password = password[0]
-            else:
-                return
+        password = self.password_asker.ask()
 
         try:
             self.wallet.send_money(self.sender.salt, password, self.community,
diff --git a/src/cutecoin/gui/wot_tab.py b/src/cutecoin/gui/wot_tab.py
index ceb93682..842226ef 100644
--- a/src/cutecoin/gui/wot_tab.py
+++ b/src/cutecoin/gui/wot_tab.py
@@ -14,7 +14,7 @@ from .transfer import TransferMoneyDialog
 
 
 class WotTabWidget(QWidget, Ui_WotTabWidget):
-    def __init__(self, account, community, parent=None):
+    def __init__(self, account, community, password_asker, parent=None):
         """
 
         :param cutecoin.core.account.Account account:
@@ -39,6 +39,7 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
 
         self.account = account
         self.community = community
+        self.password_asker = password_asker
 
         # nodes list for menu from search
         self.nodes = list()
@@ -169,13 +170,13 @@ class WotTabWidget(QWidget, Ui_WotTabWidget):
 
     def sign_node(self, metadata):
         # open certify dialog
-        dialog = CertificationDialog(self.account)
+        dialog = CertificationDialog(self.account, self.password_asker)
         dialog.edit_pubkey.setText(metadata['id'])
         dialog.radio_pubkey.setChecked(True)
         dialog.exec_()
 
     def send_money_to_node(self, metadata):
-        dialog = TransferMoneyDialog(self.account)
+        dialog = TransferMoneyDialog(self.account, self.password_asker)
         dialog.edit_pubkey.setText(metadata['id'])
         dialog.combo_community.setCurrentText(self.community.name())
         dialog.radio_pubkey.setChecked(True)
-- 
GitLab