auth_protect: pass authMessage in the auth_protect decorator,
instead of relying on side-effects This is probably safer, and also more self-contained.
This commit is contained in:
@@ -4,32 +4,28 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty
|
||||
|
||||
from electrum.logging import get_logger
|
||||
|
||||
def auth_protect(func=None, reject=None, method='pin'):
|
||||
if func is None:
|
||||
return partial(auth_protect, reject=reject, method=method)
|
||||
def auth_protect(message='', method='pin', reject=None):
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
_logger = get_logger(__name__)
|
||||
_logger.debug(f'{str(self)}.{func.__name__}')
|
||||
if hasattr(self, '__auth_fcall'):
|
||||
_logger.debug('object already has a pending authed function call')
|
||||
raise Exception('object already has a pending authed function call')
|
||||
setattr(self, '__auth_fcall', (func,args,kwargs,reject))
|
||||
getattr(self, 'authRequired').emit(method)
|
||||
def decorator(func=None):
|
||||
if func is None:
|
||||
return partial(auth_protect, reject=reject, method=method)
|
||||
|
||||
return wrapper
|
||||
@wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
_logger = get_logger(__name__)
|
||||
_logger.debug(f'{str(self)}.{func.__name__}')
|
||||
if hasattr(self, '__auth_fcall'):
|
||||
_logger.debug('object already has a pending authed function call')
|
||||
raise Exception('object already has a pending authed function call')
|
||||
setattr(self, '__auth_fcall', (func,args,kwargs,reject))
|
||||
getattr(self, 'authRequired').emit(method, message)
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
class AuthMixin:
|
||||
_auth_logger = get_logger(__name__)
|
||||
|
||||
authRequired = pyqtSignal([str],arguments=['method'])
|
||||
|
||||
auth_message = ''
|
||||
_authMixinMessageChanged = pyqtSignal()
|
||||
@pyqtProperty(str, notify=_authMixinMessageChanged)
|
||||
def authMessage(self):
|
||||
return self.auth_message
|
||||
authRequired = pyqtSignal([str, str], arguments=['method', 'authMessage'])
|
||||
|
||||
@pyqtSlot()
|
||||
def authProceed(self):
|
||||
@@ -44,7 +40,6 @@ class AuthMixin:
|
||||
raise e
|
||||
finally:
|
||||
delattr(self,'__auth_fcall')
|
||||
self.auth_message = ''
|
||||
|
||||
@pyqtSlot()
|
||||
def authCancel(self):
|
||||
@@ -64,4 +59,3 @@ class AuthMixin:
|
||||
raise e
|
||||
finally:
|
||||
delattr(self, '__auth_fcall')
|
||||
self.auth_message = ''
|
||||
|
||||
@@ -372,7 +372,7 @@ ApplicationWindow
|
||||
id: _swaphelper
|
||||
wallet: Daemon.currentWallet
|
||||
onAuthRequired: {
|
||||
app.handleAuthRequired(_swaphelper, method)
|
||||
app.handleAuthRequired(_swaphelper, method, authMessage)
|
||||
}
|
||||
onError: {
|
||||
var dialog = app.messageDialog.createObject(app, { text: message })
|
||||
@@ -477,8 +477,8 @@ ApplicationWindow
|
||||
var dialog = app.messageDialog.createObject(app, {'text': error})
|
||||
dialog.open()
|
||||
}
|
||||
function onAuthRequired(method) {
|
||||
handleAuthRequired(Daemon, method)
|
||||
function onAuthRequired(method, authMessage) {
|
||||
handleAuthRequired(Daemon, method, authMessage)
|
||||
}
|
||||
function onLoadingChanged() {
|
||||
if (!Daemon.loading)
|
||||
@@ -509,8 +509,8 @@ ApplicationWindow
|
||||
|
||||
Connections {
|
||||
target: Daemon.currentWallet
|
||||
function onAuthRequired(method) {
|
||||
handleAuthRequired(Daemon.currentWallet, method)
|
||||
function onAuthRequired(method, authMessage) {
|
||||
handleAuthRequired(Daemon.currentWallet, method, authMessage)
|
||||
}
|
||||
// TODO: add to notification queue instead of barging through
|
||||
function onPaymentSucceeded(key) {
|
||||
@@ -523,12 +523,12 @@ ApplicationWindow
|
||||
|
||||
Connections {
|
||||
target: Config
|
||||
function onAuthRequired(method) {
|
||||
handleAuthRequired(Config, method)
|
||||
function onAuthRequired(method, authMessage) {
|
||||
handleAuthRequired(Config, method, authMessage)
|
||||
}
|
||||
}
|
||||
|
||||
function handleAuthRequired(qtobject, method) {
|
||||
function handleAuthRequired(qtobject, method, authMessage) {
|
||||
console.log('auth using method ' + method)
|
||||
if (method == 'wallet') {
|
||||
if (Daemon.currentWallet.verify_password('')) {
|
||||
@@ -551,12 +551,12 @@ ApplicationWindow
|
||||
} else if (method == 'pin') {
|
||||
if (Config.pinCode == '') {
|
||||
// no PIN configured
|
||||
handleAuthConfirmationOnly(qtobject)
|
||||
handleAuthConfirmationOnly(qtobject, authMessage)
|
||||
} else {
|
||||
var dialog = app.pinDialog.createObject(app, {
|
||||
mode: 'check',
|
||||
pincode: Config.pinCode,
|
||||
authMessage: qtobject.authMessage
|
||||
authMessage: authMessage
|
||||
})
|
||||
dialog.accepted.connect(function() {
|
||||
qtobject.authProceed()
|
||||
@@ -573,12 +573,12 @@ ApplicationWindow
|
||||
}
|
||||
}
|
||||
|
||||
function handleAuthConfirmationOnly(qtobject) {
|
||||
if (!qtobject.authMessage) {
|
||||
function handleAuthConfirmationOnly(qtobject, authMessage) {
|
||||
if (!authMessage) {
|
||||
qtobject.authProceed()
|
||||
return
|
||||
}
|
||||
var dialog = app.messageDialog.createObject(app, {text: qtobject.authMessage, yesno: true})
|
||||
var dialog = app.messageDialog.createObject(app, {text: authMessage, yesno: true})
|
||||
dialog.accepted.connect(function() {
|
||||
qtobject.authProceed()
|
||||
})
|
||||
|
||||
@@ -165,7 +165,6 @@ class QEChannelOpener(QObject, AuthMixin):
|
||||
node_id=self._node_pubkey,
|
||||
fee_est=None)
|
||||
|
||||
self.auth_message = _('Open Lightning channel?')
|
||||
acpt = lambda tx: self.do_open_channel(tx, self._connect_str_resolved, self._wallet.password)
|
||||
|
||||
self._finalizer = QETxFinalizer(self, make_tx=mktx, accept=acpt)
|
||||
@@ -174,7 +173,7 @@ class QEChannelOpener(QObject, AuthMixin):
|
||||
self._finalizer.wallet = self._wallet
|
||||
self.finalizerChanged.emit()
|
||||
|
||||
@auth_protect
|
||||
@auth_protect(message=_('Open Lichtning channel?'))
|
||||
def do_open_channel(self, funding_tx, conn_str, password):
|
||||
"""
|
||||
conn_str: a connection string that extract_nodeid can parse, i.e. cannot be a trampoline name
|
||||
|
||||
@@ -261,10 +261,9 @@ class QEDaemon(AuthMixin, QObject):
|
||||
self.walletDeleteError.emit('balance', _('There are still coins present in this wallet. Really delete?'))
|
||||
return
|
||||
|
||||
self.auth_message = _('Really delete this wallet?')
|
||||
self.delete_wallet(wallet)
|
||||
|
||||
@auth_protect
|
||||
@auth_protect(message=_('Really delete this wallet?'))
|
||||
def delete_wallet(self, wallet):
|
||||
path = standardize_path(wallet.wallet.storage.path)
|
||||
self._logger.debug('deleting wallet with path %s' % path)
|
||||
|
||||
@@ -383,7 +383,6 @@ class QEInvoice(QObject, QtEventListener):
|
||||
# TODO: is update amount_msat for overrideAmount sufficient?
|
||||
self._effectiveInvoice.amount_msat = self.amountOverride.satsInt * 1000
|
||||
|
||||
self._wallet.auth_message = _('Pay Lightning Invoice?')
|
||||
self._wallet.pay_lightning_invoice(self._effectiveInvoice)
|
||||
|
||||
def get_max_spendable_onchain(self):
|
||||
|
||||
@@ -423,17 +423,9 @@ class QESwapHelper(AuthMixin, QObject, QtEventListener):
|
||||
if not self._wallet.wallet.network:
|
||||
self.error.emit(_("You are offline."))
|
||||
return
|
||||
|
||||
if self.isReverse:
|
||||
self.auth_message = _('Do you want to do a reverse submarine swap?')
|
||||
else:
|
||||
self.auth_message = _('Do you want to do a submarine swap? '
|
||||
'You will need to wait for the swap transaction to confirm.'
|
||||
)
|
||||
|
||||
self._do_execute_swap()
|
||||
|
||||
@auth_protect
|
||||
@auth_protect(message=_('Confirm Lightning swap?'))
|
||||
def _do_execute_swap(self):
|
||||
if self.isReverse:
|
||||
lightning_amount = self._send_amount
|
||||
|
||||
@@ -584,7 +584,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
||||
def ln_auth_rejected(self):
|
||||
self.paymentAuthRejected.emit()
|
||||
|
||||
@auth_protect(reject='ln_auth_rejected')
|
||||
@auth_protect(message=_('Pay lightning invoice?'), reject='ln_auth_rejected')
|
||||
def pay_lightning_invoice(self, invoice: 'QEInvoice'):
|
||||
amount_msat = invoice.get_amount_msat()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user