Files
purple-electrumwallet/electrum/gui/qml/auth.py
T

72 lines
2.8 KiB
Python
Raw Normal View History

2022-06-15 22:41:33 +02:00
from functools import wraps, partial
2023-07-14 13:51:08 +02:00
from PyQt6.QtCore import pyqtSignal, pyqtSlot
2022-06-15 22:41:33 +02:00
from electrum.logging import get_logger
2023-09-22 16:34:28 +02:00
2026-01-15 11:30:09 +01:00
def auth_protect(func=None, reject=None, method='payment_auth', message=''):
"""
Supported methods:
* payment_auth: If the user has enabled the 'Payment authentication' config
they need to authenticate to continue. If biometrics are enabled they
can authenticate using the Android system dialog, else they will see the
wallet password dialog.
If the option is disabled they will have to confirm a dialog.
* wallet: Same as payment_auth, but not dependent on user configuration,
always requires authentication.
* wallet_password_only: No biometric/system authentication, user has to enter wallet password.
"""
2023-04-18 14:47:01 +02:00
if func is None:
return partial(auth_protect, reject=reject, method=method, message=message)
@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
2022-06-15 22:41:33 +02:00
2023-09-22 16:34:28 +02:00
2022-06-15 22:41:33 +02:00
class AuthMixin:
_auth_logger = get_logger(__name__)
authRequired = pyqtSignal([str, str], arguments=['method', 'authMessage'])
2022-06-15 22:41:33 +02:00
@pyqtSlot()
def authProceed(self):
self._auth_logger.debug('Proceeding with authed fn()')
try:
self._auth_logger.debug(str(getattr(self, '__auth_fcall')))
2023-09-22 16:34:28 +02:00
(func, args, kwargs, reject) = getattr(self, '__auth_fcall')
2022-06-15 22:41:33 +02:00
r = func(self, *args, **kwargs)
return r
except Exception as e:
2023-04-17 09:43:31 +02:00
self._auth_logger.error(f'Error executing wrapped fn(): {repr(e)}')
2022-06-15 22:41:33 +02:00
raise e
finally:
2023-09-22 16:34:28 +02:00
delattr(self, '__auth_fcall')
2022-06-15 22:41:33 +02:00
@pyqtSlot()
def authCancel(self):
self._auth_logger.debug('Cancelling authed fn()')
if not hasattr(self, '__auth_fcall'):
return
try:
2023-09-22 16:34:28 +02:00
(func, args, kwargs, reject) = getattr(self, '__auth_fcall')
2022-06-15 22:41:33 +02:00
if reject is not None:
if hasattr(self, reject):
getattr(self, reject)()
else:
2023-04-17 09:43:31 +02:00
self._auth_logger.error(f'Reject method "{reject}" not defined')
2022-06-15 22:41:33 +02:00
except Exception as e:
2023-04-17 09:43:31 +02:00
self._auth_logger.error(f'Error executing reject function "{reject}": {repr(e)}')
2022-06-15 22:41:33 +02:00
raise e
finally:
delattr(self, '__auth_fcall')