From cb42df542d1e5c2d2917308faff7eb711b1fd7eb Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 23 Jun 2025 13:40:35 +0800 Subject: [PATCH] fix: bitwardne request data encode --- apps/authentication/api/confirm.py | 2 + apps/authentication/backends/passkey/api.py | 1 + apps/authentication/permissions.py | 24 +++++++----- .../templates/authentication/passkey.html | 39 ++++++++++--------- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/apps/authentication/api/confirm.py b/apps/authentication/api/confirm.py index 2bb371e48..95e6dfee0 100644 --- a/apps/authentication/api/confirm.py +++ b/apps/authentication/api/confirm.py @@ -37,6 +37,7 @@ class UserConfirmationViewSet(JMSGenericViewSet): backend_classes = ConfirmType.get_prop_backends(confirm_type) if not backend_classes: return + for backend_cls in backend_classes: backend = backend_cls(self.request.user, self.request) if not backend.check(): @@ -69,6 +70,7 @@ class UserConfirmationViewSet(JMSGenericViewSet): ok, msg = backend.authenticate(secret_key, mfa_type) if ok: request.session['CONFIRM_LEVEL'] = ConfirmType.values.index(confirm_type) + 1 + request.session['CONFIRM_TYPE'] = confirm_type request.session['CONFIRM_TIME'] = int(time.time()) return Response('ok') return Response({'error': msg}, status=400) diff --git a/apps/authentication/backends/passkey/api.py b/apps/authentication/backends/passkey/api.py index 86c4ebb3d..fd4c52a9a 100644 --- a/apps/authentication/backends/passkey/api.py +++ b/apps/authentication/backends/passkey/api.py @@ -74,6 +74,7 @@ class PasskeyViewSet(AuthMixin, FlashMessageMixin, JMSModelViewSet): if confirm_mfa: request.session['CONFIRM_LEVEL'] = ConfirmType.values.index('mfa') + 1 request.session['CONFIRM_TIME'] = int(time.time()) + request.session['CONFIRM_TYPE'] = ConfirmType.MFA request.session['passkey_confirm_mfa'] = '' return Response('ok') diff --git a/apps/authentication/permissions.py b/apps/authentication/permissions.py index 1bd87b4ea..13b15a17f 100644 --- a/apps/authentication/permissions.py +++ b/apps/authentication/permissions.py @@ -14,23 +14,29 @@ from orgs.utils import tmp_to_root_org class UserConfirmation(permissions.BasePermission): ttl = 60 * 5 min_level = 1 - confirm_type = 'relogin' + min_type = 'relogin' def has_permission(self, request, view): if not settings.SECURITY_VIEW_AUTH_NEED_MFA: return True confirm_level = request.session.get('CONFIRM_LEVEL') + confirm_type = request.session.get('CONFIRM_TYPE') confirm_time = request.session.get('CONFIRM_TIME') - ttl = self.get_ttl() - if not confirm_level or not confirm_time or \ - confirm_level < self.min_level or \ - confirm_time < time.time() - ttl: - raise UserConfirmRequired(code=self.confirm_type) + + ttl = self.get_ttl(confirm_type) + now = int(time.time()) + + if not confirm_level or not confirm_time: + raise UserConfirmRequired(code=self.min_type) + + if confirm_level < self.min_level or \ + confirm_time < now - ttl: + raise UserConfirmRequired(code=self.min_type) return True - def get_ttl(self): - if self.confirm_type == ConfirmType.MFA: + def get_ttl(self, confirm_type): + if confirm_type == ConfirmType.MFA: ttl = settings.SECURITY_MFA_VERIFY_TTL else: ttl = self.ttl @@ -40,7 +46,7 @@ class UserConfirmation(permissions.BasePermission): def require(cls, confirm_type=ConfirmType.RELOGIN, ttl=60 * 5): min_level = ConfirmType.values.index(confirm_type) + 1 name = 'UserConfirmationLevel{}TTL{}'.format(min_level, ttl) - return type(name, (cls,), {'min_level': min_level, 'ttl': ttl, 'confirm_type': confirm_type}) + return type(name, (cls,), {'min_level': min_level, 'ttl': ttl, 'min_type': confirm_type}) class IsValidUserOrConnectionToken(IsValidUser): diff --git a/apps/authentication/templates/authentication/passkey.html b/apps/authentication/templates/authentication/passkey.html index 9d87bff27..ccda9631d 100644 --- a/apps/authentication/templates/authentication/passkey.html +++ b/apps/authentication/templates/authentication/passkey.html @@ -91,27 +91,30 @@ } } - const publicKeyCredentialToJSON = (pubKeyCred) => { - if (pubKeyCred instanceof Array) { - const arr = [] - for (const i of pubKeyCred) { - arr.push(publicKeyCredentialToJSON(i)) - } - return arr + const publicKeyCredentialToJSON = pubKeyCred => { + if (pubKeyCred instanceof Array) { + const arr = [] + for (const i of pubKeyCred) { + arr.push(publicKeyCredentialToJSON(i)) + } + return arr + } + + if (pubKeyCred instanceof ArrayBuffer || pubKeyCred instanceof Uint8Array) { + return encode(pubKeyCred) + } + + if (pubKeyCred instanceof Object) { + const obj = {} + + for (const key in pubKeyCred) { + obj[key] = publicKeyCredentialToJSON(pubKeyCred[key]) } - if (pubKeyCred instanceof ArrayBuffer) { - return encode(pubKeyCred) - } + return obj + } - if (pubKeyCred instanceof Object) { - const obj = {} - for (const key in pubKeyCred) { - obj[key] = publicKeyCredentialToJSON(pubKeyCred[key]) - } - return obj - } - return pubKeyCred + return pubKeyCred } function GetAssertReq(getAssert) {