Trezor: add session timeout to preferences

Fixes #803
This commit is contained in:
Neil Booth 2016-01-03 17:25:47 +09:00
parent 87363c8301
commit 43fd684d97
2 changed files with 53 additions and 4 deletions

View File

@ -29,11 +29,18 @@ class TrezorCompatibleWallet(BIP44_Wallet):
# This is set when paired with a device, and used to re-pair
# a device that is disconnected and re-connected
self.device_id = None
# After timeout seconds we clear the device session
self.session_timeout = storage.get('session_timeout', 180)
# Errors and other user interaction is done through the wallet's
# handler. The handler is per-window and preserved across
# device reconnects
self.handler = None
def set_session_timeout(self, seconds):
self.print_error("setting session timeout to %d seconds" % seconds)
self.session_timeout = seconds
self.storage.put('session_timeout', seconds)
def disconnected(self):
self.print_error("disconnected")
self.handler.watching_only_changed()
@ -46,9 +53,8 @@ class TrezorCompatibleWallet(BIP44_Wallet):
self.print_error("wiped")
self.handler.watching_only_changed()
def initialized(self):
self.print_error("initialized")
self.handler.watching_only_changed()
def timeout(self):
self.print_error("timed out")
def get_action(self):
pass
@ -155,6 +161,7 @@ class TrezorCompatiblePlugin(BasePlugin):
BasePlugin.__init__(self, parent, config, name)
self.device = self.wallet_class.device
self.wallet_class.plugin = self
self.prevent_timeout = time.time() + 3600 * 24 * 365
# A set of client instances to USB paths
self.clients = set()
# The device wallets we have seen to inform on reconnection
@ -173,6 +180,13 @@ class TrezorCompatiblePlugin(BasePlugin):
if now > self.last_scan + 1:
self.last_scan = now
self.scan_devices()
for wallet in self.paired_wallets:
if now > wallet.last_operation + wallet.session_timeout:
client = self.lookup_client(wallet)
if client:
wallet.last_operation = self.prevent_timeout
self.clear_session(client)
wallet.timeout()
def scan_devices(self):
paths = self.HidTransport.enumerate()
@ -221,6 +235,9 @@ class TrezorCompatiblePlugin(BasePlugin):
client.clear_session()
def initialize_device(self, wallet, wizard):
# Prevent timeouts during initialization
wallet.last_operation = self.prevent_timeout
(strength, label, pin_protection, passphrase_protection) \
= wizard.request_trezor_reset_settings(self.device)
@ -247,10 +264,16 @@ class TrezorCompatiblePlugin(BasePlugin):
if not client.is_initialized():
self.initialize_device(wallet, wizard)
def operated_on(self, wallet):
self.print_error("set last_operation")
wallet.last_operation = time.time()
def pair_wallet(self, wallet, client):
self.print_error("pairing wallet %s to device %s" % (wallet, client))
self.operated_on(wallet)
self.paired_wallets.add(wallet)
wallet.device_id = client.features.device_id
wallet.last_operation = time.time()
client.wallet = wallet
wallet.connected()
@ -301,6 +324,7 @@ class TrezorCompatiblePlugin(BasePlugin):
assert isinstance(wallet, self.wallet_class)
assert wallet.handler != None
self.operated_on(wallet)
if wallet.device_id is None:
client = self.try_to_pair_wallet(wallet)
else:

View File

@ -1,6 +1,7 @@
from functools import partial
import threading
from PyQt4.Qt import Qt
from PyQt4.Qt import QGridLayout, QInputDialog, QPushButton
from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL
from electrum_gui.qt.main_window import StatusBarButton
@ -217,12 +218,17 @@ def qt_plugin_class(base_plugin_class):
client().wipe_device()
refresh()
def slider_moved():
mins = timeout_slider.sliderPosition()
timeout_label.setText(_("%2d minutes") % mins)
wallet = window.wallet
handler = wallet.handler
device = self.device
info_tab = QWidget()
info_layout = QGridLayout(info_tab)
tab_layout = QVBoxLayout(info_tab)
info_layout = QGridLayout()
noyes = [_("No"), _("Yes")]
bl_hash_label = QLabel()
device_label = QLabel()
@ -249,6 +255,22 @@ def qt_plugin_class(base_plugin_class):
(_("Firmware Version"), version_label),
(_("Language"), language_label),
])
tab_layout.addLayout(info_layout)
timeout_layout = QHBoxLayout()
timeout_label = QLabel()
timeout_slider = QSlider(Qt.Horizontal)
timeout_slider.setRange(1, 60)
timeout_slider.setSingleStep(1)
timeout_slider.setSliderPosition(wallet.session_timeout // 60)
timeout_slider.setTickInterval(5)
timeout_slider.setTickPosition(QSlider.TicksBelow)
timeout_slider.setTracking(True)
timeout_slider.valueChanged.connect(slider_moved)
timeout_layout.addWidget(QLabel(_("Session Timeout")))
timeout_layout.addWidget(timeout_slider)
timeout_layout.addWidget(timeout_label)
tab_layout.addLayout(timeout_layout)
advanced_tab = QWidget()
advanced_layout = QGridLayout(advanced_tab)
@ -267,8 +289,11 @@ def qt_plugin_class(base_plugin_class):
vbox.addStretch(1)
vbox.addLayout(Buttons(CloseButton(dialog)))
# Show values
slider_moved()
refresh()
dialog.setLayout(vbox)
handler.exec_dialog(dialog)
wallet.set_session_timeout(timeout_slider.sliderPosition() * 60)
return QtPlugin