123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- # Copyright 2021 Google LLC
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- """Tests for the reauth module."""
- import base64
- import sys
- import mock
- import pytest
- import pyu2f
- from google.auth import exceptions
- from google.oauth2 import challenges
- def test_get_user_password():
- with mock.patch("getpass.getpass", return_value="foo"):
- assert challenges.get_user_password("") == "foo"
- def test_security_key():
- metadata = {
- "status": "READY",
- "challengeId": 2,
- "challengeType": "SECURITY_KEY",
- "securityKey": {
- "applicationId": "security_key_application_id",
- "challenges": [
- {
- "keyHandle": "some_key",
- "challenge": base64.urlsafe_b64encode(
- "some_challenge".encode("ascii")
- ).decode("ascii"),
- }
- ],
- },
- }
- mock_key = mock.Mock()
- challenge = challenges.SecurityKeyChallenge()
- # Test the case that security key challenge is passed.
- with mock.patch("pyu2f.model.RegisteredKey", return_value=mock_key):
- with mock.patch(
- "pyu2f.convenience.authenticator.CompositeAuthenticator.Authenticate"
- ) as mock_authenticate:
- mock_authenticate.return_value = "security key response"
- assert challenge.name == "SECURITY_KEY"
- assert challenge.is_locally_eligible
- assert challenge.obtain_challenge_input(metadata) == {
- "securityKey": "security key response"
- }
- mock_authenticate.assert_called_with(
- "security_key_application_id",
- [{"key": mock_key, "challenge": b"some_challenge"}],
- print_callback=sys.stderr.write,
- )
- # Test various types of exceptions.
- with mock.patch("pyu2f.model.RegisteredKey", return_value=mock_key):
- with mock.patch(
- "pyu2f.convenience.authenticator.CompositeAuthenticator.Authenticate"
- ) as mock_authenticate:
- mock_authenticate.side_effect = pyu2f.errors.U2FError(
- pyu2f.errors.U2FError.DEVICE_INELIGIBLE
- )
- assert challenge.obtain_challenge_input(metadata) is None
- with mock.patch(
- "pyu2f.convenience.authenticator.CompositeAuthenticator.Authenticate"
- ) as mock_authenticate:
- mock_authenticate.side_effect = pyu2f.errors.U2FError(
- pyu2f.errors.U2FError.TIMEOUT
- )
- assert challenge.obtain_challenge_input(metadata) is None
- with mock.patch(
- "pyu2f.convenience.authenticator.CompositeAuthenticator.Authenticate"
- ) as mock_authenticate:
- mock_authenticate.side_effect = pyu2f.errors.U2FError(
- pyu2f.errors.U2FError.BAD_REQUEST
- )
- with pytest.raises(pyu2f.errors.U2FError):
- challenge.obtain_challenge_input(metadata)
- with mock.patch(
- "pyu2f.convenience.authenticator.CompositeAuthenticator.Authenticate"
- ) as mock_authenticate:
- mock_authenticate.side_effect = pyu2f.errors.NoDeviceFoundError()
- assert challenge.obtain_challenge_input(metadata) is None
- with mock.patch(
- "pyu2f.convenience.authenticator.CompositeAuthenticator.Authenticate"
- ) as mock_authenticate:
- mock_authenticate.side_effect = pyu2f.errors.UnsupportedVersionException()
- with pytest.raises(pyu2f.errors.UnsupportedVersionException):
- challenge.obtain_challenge_input(metadata)
- with mock.patch.dict("sys.modules"):
- sys.modules["pyu2f"] = None
- with pytest.raises(exceptions.ReauthFailError) as excinfo:
- challenge.obtain_challenge_input(metadata)
- assert excinfo.match(r"pyu2f dependency is required")
- @mock.patch("getpass.getpass", return_value="foo")
- def test_password_challenge(getpass_mock):
- challenge = challenges.PasswordChallenge()
- with mock.patch("getpass.getpass", return_value="foo"):
- assert challenge.is_locally_eligible
- assert challenge.name == "PASSWORD"
- assert challenges.PasswordChallenge().obtain_challenge_input({}) == {
- "credential": "foo"
- }
- with mock.patch("getpass.getpass", return_value=None):
- assert challenges.PasswordChallenge().obtain_challenge_input({}) == {
- "credential": " "
- }
|