fix: bitwardne request data encode

pull/15625/head
ibuler 2025-06-23 13:40:35 +08:00 committed by 老广
parent 46ddad1d59
commit cb42df542d
4 changed files with 39 additions and 27 deletions

View File

@ -37,6 +37,7 @@ class UserConfirmationViewSet(JMSGenericViewSet):
backend_classes = ConfirmType.get_prop_backends(confirm_type) backend_classes = ConfirmType.get_prop_backends(confirm_type)
if not backend_classes: if not backend_classes:
return return
for backend_cls in backend_classes: for backend_cls in backend_classes:
backend = backend_cls(self.request.user, self.request) backend = backend_cls(self.request.user, self.request)
if not backend.check(): if not backend.check():
@ -69,6 +70,7 @@ class UserConfirmationViewSet(JMSGenericViewSet):
ok, msg = backend.authenticate(secret_key, mfa_type) ok, msg = backend.authenticate(secret_key, mfa_type)
if ok: if ok:
request.session['CONFIRM_LEVEL'] = ConfirmType.values.index(confirm_type) + 1 request.session['CONFIRM_LEVEL'] = ConfirmType.values.index(confirm_type) + 1
request.session['CONFIRM_TYPE'] = confirm_type
request.session['CONFIRM_TIME'] = int(time.time()) request.session['CONFIRM_TIME'] = int(time.time())
return Response('ok') return Response('ok')
return Response({'error': msg}, status=400) return Response({'error': msg}, status=400)

View File

@ -74,6 +74,7 @@ class PasskeyViewSet(AuthMixin, FlashMessageMixin, JMSModelViewSet):
if confirm_mfa: if confirm_mfa:
request.session['CONFIRM_LEVEL'] = ConfirmType.values.index('mfa') + 1 request.session['CONFIRM_LEVEL'] = ConfirmType.values.index('mfa') + 1
request.session['CONFIRM_TIME'] = int(time.time()) request.session['CONFIRM_TIME'] = int(time.time())
request.session['CONFIRM_TYPE'] = ConfirmType.MFA
request.session['passkey_confirm_mfa'] = '' request.session['passkey_confirm_mfa'] = ''
return Response('ok') return Response('ok')

View File

@ -14,23 +14,29 @@ from orgs.utils import tmp_to_root_org
class UserConfirmation(permissions.BasePermission): class UserConfirmation(permissions.BasePermission):
ttl = 60 * 5 ttl = 60 * 5
min_level = 1 min_level = 1
confirm_type = 'relogin' min_type = 'relogin'
def has_permission(self, request, view): def has_permission(self, request, view):
if not settings.SECURITY_VIEW_AUTH_NEED_MFA: if not settings.SECURITY_VIEW_AUTH_NEED_MFA:
return True return True
confirm_level = request.session.get('CONFIRM_LEVEL') confirm_level = request.session.get('CONFIRM_LEVEL')
confirm_type = request.session.get('CONFIRM_TYPE')
confirm_time = request.session.get('CONFIRM_TIME') confirm_time = request.session.get('CONFIRM_TIME')
ttl = self.get_ttl()
if not confirm_level or not confirm_time or \ ttl = self.get_ttl(confirm_type)
confirm_level < self.min_level or \ now = int(time.time())
confirm_time < time.time() - ttl:
raise UserConfirmRequired(code=self.confirm_type) 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 return True
def get_ttl(self): def get_ttl(self, confirm_type):
if self.confirm_type == ConfirmType.MFA: if confirm_type == ConfirmType.MFA:
ttl = settings.SECURITY_MFA_VERIFY_TTL ttl = settings.SECURITY_MFA_VERIFY_TTL
else: else:
ttl = self.ttl ttl = self.ttl
@ -40,7 +46,7 @@ class UserConfirmation(permissions.BasePermission):
def require(cls, confirm_type=ConfirmType.RELOGIN, ttl=60 * 5): def require(cls, confirm_type=ConfirmType.RELOGIN, ttl=60 * 5):
min_level = ConfirmType.values.index(confirm_type) + 1 min_level = ConfirmType.values.index(confirm_type) + 1
name = 'UserConfirmationLevel{}TTL{}'.format(min_level, ttl) 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): class IsValidUserOrConnectionToken(IsValidUser):

View File

@ -91,27 +91,30 @@
} }
} }
const publicKeyCredentialToJSON = (pubKeyCred) => { const publicKeyCredentialToJSON = pubKeyCred => {
if (pubKeyCred instanceof Array) { if (pubKeyCred instanceof Array) {
const arr = [] const arr = []
for (const i of pubKeyCred) { for (const i of pubKeyCred) {
arr.push(publicKeyCredentialToJSON(i)) arr.push(publicKeyCredentialToJSON(i))
} }
return arr 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 obj
return encode(pubKeyCred) }
}
if (pubKeyCred instanceof Object) { return pubKeyCred
const obj = {}
for (const key in pubKeyCred) {
obj[key] = publicKeyCredentialToJSON(pubKeyCred[key])
}
return obj
}
return pubKeyCred
} }
function GetAssertReq(getAssert) { function GetAssertReq(getAssert) {