diff --git a/tests/test_mfa.py b/tests/test_mfa.py index c1131eaffcc26793e990dfcb7b83611a25db41ae..05a61351bfeafd295282e034bcc73bdbd9406f0c 100644 --- a/tests/test_mfa.py +++ b/tests/test_mfa.py @@ -26,7 +26,7 @@ class TestMfaPrimitives(unittest.TestCase): def get_fido2_test_cred(self): try: - from fido2.ctap2 import AttestedCredentialData + from uffd.mfa.fido2_compat import AttestedCredentialData except ImportError: self.skipTest('fido2 could not be imported') # Example public key from webauthn spec 6.5.1.1 diff --git a/uffd/mfa/fido2_compat.py b/uffd/mfa/fido2_compat.py new file mode 100644 index 0000000000000000000000000000000000000000..dd8fd9ba0f88c5f1cafa175c6fea8715c740926a --- /dev/null +++ b/uffd/mfa/fido2_compat.py @@ -0,0 +1,26 @@ +# pylint: skip-file + +import fido2 as __fido2 + +if __fido2.__version__.startswith('0.5.'): + from fido2.client import ClientData + from fido2.server import Fido2Server, RelyingParty as __PublicKeyCredentialRpEntity + from fido2.ctap2 import AttestationObject, AuthenticatorData, AttestedCredentialData + from fido2 import cbor + cbor.encode = cbor.dumps + cbor.decode = lambda arg: cbor.loads(arg)[0] + class PublicKeyCredentialRpEntity(__PublicKeyCredentialRpEntity): + def __init__(self, name, id): + super().__init__(id, name) +elif __fido2.__version__.startswith('0.9.'): + from fido2.client import ClientData + from fido2.webauthn import PublicKeyCredentialRpEntity + from fido2.server import Fido2Server + from fido2.ctap2 import AttestationObject, AuthenticatorData, AttestedCredentialData + from fido2 import cbor +elif __fido2.__version__.startswith('1.'): + from fido2.webauthn import PublicKeyCredentialRpEntity, CollectedClientData as ClientData, AttestationObject, AuthenticatorData, AttestedCredentialData + from fido2.server import Fido2Server + from fido2 import cbor +else: + raise ImportError(f'Unsupported fido2 version: {__fido2.__version__}') diff --git a/uffd/mfa/models.py b/uffd/mfa/models.py index 81b6abd725ae677efbf87d7503e80a3129da7966..1e117ac64842ce5619d640a33f6ffdc8fbca079d 100644 --- a/uffd/mfa/models.py +++ b/uffd/mfa/models.py @@ -141,7 +141,7 @@ class WebauthnMethod(MFAMethod): @property def cred(self): - from fido2.ctap2 import AttestedCredentialData #pylint: disable=import-outside-toplevel + from .fido2_compat import AttestedCredentialData #pylint: disable=import-outside-toplevel return AttestedCredentialData(base64.b64decode(self._cred)) @cred.setter diff --git a/uffd/mfa/views.py b/uffd/mfa/views.py index 60f0b472d927c954f0a0141ca899d411da253ec1..bae2464942113ab7636d998e1d6f6d2e85a6dc5f 100644 --- a/uffd/mfa/views.py +++ b/uffd/mfa/views.py @@ -101,23 +101,7 @@ def delete_totp(id): #pylint: disable=redefined-builtin # WebAuthn support is optional because fido2 has a pretty unstable # interface and might be difficult to install with the correct version try: - import fido2 - if fido2.__version__.startswith('0.5.'): - from fido2.client import ClientData - from fido2.server import Fido2Server, RelyingParty as PublicKeyCredentialRpEntity - from fido2.ctap2 import AttestationObject, AuthenticatorData - from fido2 import cbor - # pylint: disable=no-member - cbor.encode = cbor.dumps - cbor.decode = lambda arg: cbor.loads(arg)[0] - elif fido2.__version__.startswith('0.9.'): - from fido2.client import ClientData - from fido2.webauthn import PublicKeyCredentialRpEntity - from fido2.server import Fido2Server - from fido2.ctap2 import AttestationObject, AuthenticatorData - from fido2 import cbor - else: - raise ImportError(f'Unsupported fido2 version: {fido2.__version__}') + from .fido2_compat import * # pylint: disable=wildcard-import,unused-wildcard-import WEBAUTHN_SUPPORTED = True except ImportError as err: warn(_('2FA WebAuthn support disabled because import of the fido2 module failed (%s)')%err) @@ -128,8 +112,8 @@ bp.add_app_template_global(WEBAUTHN_SUPPORTED, name='webauthn_supported') if WEBAUTHN_SUPPORTED: def get_webauthn_server(): hostname = urllib.parse.urlsplit(request.url).hostname - return Fido2Server(PublicKeyCredentialRpEntity(current_app.config.get('MFA_RP_ID', hostname), - current_app.config['MFA_RP_NAME'])) + return Fido2Server(PublicKeyCredentialRpEntity(id=current_app.config.get('MFA_RP_ID', hostname), + name=current_app.config['MFA_RP_NAME'])) @bp.route('/setup/webauthn/begin', methods=['POST']) @login_required()