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