Files
2024-02-15 17:01:50 +00:00

68 lines
3.4 KiB
Python

from fido2 import cbor
from fido2.ctap2 import AuthenticatorData
from fido2.server import Fido2Server
from fido2.webauthn import PublicKeyCredentialRpEntity
from sentry.auth.authenticators.base import ActivationChallengeResult
from sentry.auth.authenticators.u2f import U2fInterface
from sentry.testutils.cases import TestCase
from sentry.testutils.silo import control_silo_test
def verifiy_origin(origin):
return True
@control_silo_test
class U2FInterfaceTest(TestCase):
def setUp(self):
self.u2f = U2fInterface()
self.login_as(user=self.user)
rp = PublicKeyCredentialRpEntity("richardmasentry.ngrok.io", "Sentry")
self.test_registration_server = Fido2Server(rp, verify_origin=verifiy_origin)
def test_start_enrollment_webauthn(self):
self.u2f.webauthn_registration_server = self.test_registration_server
encoded_challenge, state = self.u2f.start_enrollment(self.user)
challenge = cbor.decode(encoded_challenge)
assert len(state) == 2
assert state["user_verification"] == "discouraged"
assert len(state["challenge"]) == 43
assert challenge["publicKey"]["rp"] == {"id": "richardmasentry.ngrok.io", "name": "Sentry"}
assert challenge["publicKey"]["user"] == {
"id": self.user.id.to_bytes(64, byteorder="big"),
"name": self.user.username,
"displayName": self.user.username,
}
assert int.from_bytes(challenge["publicKey"]["user"]["id"], byteorder="big") == self.user.id
assert len(challenge["publicKey"]["pubKeyCredParams"]) == 4
def test_try_enroll_webauthn(self):
self.u2f.webauthn_registration_server = self.test_registration_server
state = {
"challenge": "FmKqEKsXOinMhOdNhcZbMCbGleTlDeFr0S1gSYGzPY0",
"user_verification": "discouraged",
}
data = '{"id":"TYJVkw5RJGuwyY-veny4wBvPnhIc1-2vs7a17W6fRPMevfDlTR_YWTnLwgeLjKvNaZgMDd2T75CD9bEUX3FyxQ","rawId":"TYJVkw5RJGuwyY-veny4wBvPnhIc1-2vs7a17W6fRPMevfDlTR_YWTnLwgeLjKvNaZgMDd2T75CD9bEUX3FyxQ","response":{"attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEdMsc6ARz46ITf5wcoxCGiLKiJRlmv2GeNJ635pkBOmVBAAAA_wAAAAAAAAAAAAAAAAAAAAAAQE2CVZMOUSRrsMmPr3p8uMAbz54SHNftr7O2te1un0TzHr3w5U0f2Fk5y8IHi4yrzWmYDA3dk--Qg_WxFF9xcsWlAQIDJiABIVggo6MzqMkVN1UI6d4gf60CoBH4CnAKURH0Q8ENYnD2k6MiWCCvFWvPJs_p0zGVyBwoZDy7WyQZUAPVZhmCAzXUnapQ-A","clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiRm1LcUVLc1hPaW5NaE9kTmhjWmJNQ2JHbGVUbERlRnIwUzFnU1lHelBZMCIsIm9yaWdpbiI6Imh0dHBzOi8vcmljaGFyZG1hc2VudHJ5Lm5ncm9rLmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ"},"type":""}'
assert len(self.u2f.config.setdefault("devices", [])) == 0
self.u2f.try_enroll("enrollment_data", data, state=state)
assert len(self.u2f.config.setdefault("devices", [])) == 1
device = self.u2f.config.setdefault("devices", [])[0]
assert device["name"] is not None
assert device["ts"] is not None
assert type(device["binding"]) is AuthenticatorData
def test_activate_webauthn(self):
self.test_try_enroll_webauthn()
request = self.make_request(user=self.user)
result = self.u2f.activate(request)
assert isinstance(result, ActivationChallengeResult)
assert len(request.session["webauthn_authentication_state"]["challenge"]) == 43
assert request.session["webauthn_authentication_state"]["user_verification"] is None