Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/google-auth/google/auth/crypt/rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

from google.auth import _helpers
from google.auth.crypt import _cryptography_rsa
from google.auth.crypt import _python_rsa
from google.auth.crypt import base

RSA_KEY_MODULE_PREFIX = "rsa.key"
Expand All @@ -37,6 +36,7 @@ class RSAVerifier(base.Verifier):
public_key (Union["rsa.key.PublicKey", cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey]):
The public key used to verify signatures.
Raises:
ImportError: if called with an rsa.key.PublicKey, when the rsa library is not installed
ValueError: if an unrecognized public key is provided
"""

Expand All @@ -45,6 +45,8 @@ def __init__(self, public_key):
if isinstance(public_key, RSAPublicKey):
impl_lib = _cryptography_rsa
elif module_str.startswith(RSA_KEY_MODULE_PREFIX):
from google.auth.crypt import _python_rsa

impl_lib = _python_rsa
else:
raise ValueError(f"unrecognized public key type: {type(public_key)}")
Expand Down Expand Up @@ -85,6 +87,7 @@ class RSASigner(base.Signer, base.FromServiceAccountMixin):
public key or certificate.

Raises:
ImportError: if called with an rsa.key.PrivateKey, when the rsa library is not installed
ValueError: if an unrecognized public key is provided
"""

Expand All @@ -93,6 +96,8 @@ def __init__(self, private_key, key_id=None):
if isinstance(private_key, RSAPrivateKey):
impl_lib = _cryptography_rsa
elif module_str.startswith(RSA_KEY_MODULE_PREFIX):
from google.auth.crypt import _python_rsa

impl_lib = _python_rsa
else:
raise ValueError(f"unrecognized private key type: {type(private_key)}")
Expand Down
19 changes: 16 additions & 3 deletions packages/google-auth/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"3.13",
"3.14",
]
ALL_PYTHON = UNIT_TEST_PYTHON_VERSIONS
ALL_PYTHON = UNIT_TEST_PYTHON_VERSIONS.copy()
ALL_PYTHON.extend(["3.7"])

# Error if a python version is missing
Expand Down Expand Up @@ -115,16 +115,29 @@ def mypy(session):


@nox.session(python=ALL_PYTHON)
def unit(session):
@nox.parametrize(["install_deprecated_extras"], (True, False))
def unit(session, install_deprecated_extras):
# Install all test dependencies, then install this package in-place.

if session.python in ("3.7",):
session.skip("Python 3.7 is no longer supported")
min_py, max_py = UNIT_TEST_PYTHON_VERSIONS[0], UNIT_TEST_PYTHON_VERSIONS[-1]
if not install_deprecated_extras and session.python not in (min_py, max_py):
# only run double tests on first and last supported versions
session.skip(
f"Extended tests only run on boundary Python versions ({min_py}, {max_py}) to reduce CI load."
)

constraints_path = str(
CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
)
session.install("-e", ".[testing]", "-c", constraints_path)
extras_str = "testing"
if install_deprecated_extras:
# rsa and oauth2client were both archived and support dropped,
# but we still test old code paths
session.install("oauth2client")
extras_str += ",rsa"
session.install("-e", f".[{extras_str}]", "-c", constraints_path)
session.run(
"pytest",
f"--junitxml=unit_{session.python}_sponge_log.xml",
Expand Down
8 changes: 3 additions & 5 deletions packages/google-auth/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
DEPENDENCIES = (
"pyasn1-modules>=0.2.1",
cryptography_base_require,
# TODO: remove rsa from dependencies in next release (replaced with cryptography)i
# https://github.com/googleapis/google-auth-library-python/issues/1810
"rsa>=3.1.4,<5",
)

requests_extra_require = ["requests >= 2.20.0, < 3.0.0"]
Expand All @@ -46,14 +43,14 @@
# TODO(https://github.com/googleapis/google-auth-library-python/issues/1739): Add bounds for urllib3 and packaging dependencies.
urllib3_extra_require = ["urllib3", "packaging"]

rsa_extra_require = ["rsa>=3.1.4,<5"]

# Unit test requirements.
testing_extra_require = [
# TODO(https://github.com/googleapis/google-auth-library-python/issues/1735): Remove `grpcio` from testing requirements once an extra is added for `grpcio` dependency.
"grpcio",
"flask",
"freezegun",
# TODO(https://github.com/googleapis/google-auth-library-python/issues/1736): Remove `oauth2client` from testing requirements once an extra is added for `oauth2client` dependency.
"oauth2client",
*pyjwt_extra_require,
"pytest",
"pytest-cov",
Expand Down Expand Up @@ -86,6 +83,7 @@
"requests": requests_extra_require,
"testing": testing_extra_require,
"urllib3": urllib3_extra_require,
"rsa": rsa_extra_require,
# TODO(https://github.com/googleapis/google-auth-library-python/issues/1735): Add an extra for `grpcio` dependency.
# TODO(https://github.com/googleapis/google-auth-library-python/issues/1736): Add an extra for `oauth2client` dependency.
}
Expand Down
1 change: 0 additions & 1 deletion packages/google-auth/testing/constraints-3.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# Then this file should have foo==1.14.0
pyasn1-modules==0.2.1
setuptools==40.3.0
rsa==3.1.4
cryptography==38.0.3
aiohttp==3.6.2
requests==2.20.0
Expand Down
3 changes: 2 additions & 1 deletion packages/google-auth/tests/crypt/test__python_rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@

from pyasn1_modules import pem # type: ignore
import pytest # type: ignore
import rsa # type: ignore

from google.auth import _helpers
from google.auth.crypt import _python_rsa
from google.auth.crypt import base

rsa = pytest.importorskip("rsa") # type: ignore


DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")

Expand Down
18 changes: 14 additions & 4 deletions packages/google-auth/tests/crypt/test_rsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import serialization
import pytest
import rsa as rsa_lib

try:
import rsa as rsa_lib
from google.auth.crypt import _python_rsa
except ImportError:
rsa_lib = None
_pyrhon_rsa = None

from google.auth.crypt import _cryptography_rsa
from google.auth.crypt import _python_rsa
from google.auth.crypt import rsa


Expand Down Expand Up @@ -70,11 +75,13 @@ def test_init_with_cryptography_key(self, cryptography_public_key):
assert isinstance(verifier._impl, _cryptography_rsa.RSAVerifier)
assert verifier._impl._pubkey == cryptography_public_key

@pytest.mark.skipif(not rsa_lib, reason="rsa library not installed")
def test_init_with_rsa_key(self, rsa_public_key):
verifier = rsa.RSAVerifier(rsa_public_key)
assert isinstance(verifier._impl, _python_rsa.RSAVerifier)
assert verifier._impl._pubkey == rsa_public_key

@pytest.mark.skipif(not rsa_lib, reason="rsa library not installed")
def test_warning_with_rsa(self, rsa_public_key):
with pytest.warns(DeprecationWarning, match="The 'rsa' library is deprecated"):
rsa.RSAVerifier(rsa_public_key)
Expand Down Expand Up @@ -114,12 +121,14 @@ def test_init_with_cryptography_key(self, cryptography_private_key):
assert signer._impl._key == cryptography_private_key
assert signer._impl.key_id == "123"

@pytest.mark.skipif(not rsa_lib, reason="rsa library not installed")
def test_init_with_rsa_key(self, rsa_private_key):
signer = rsa.RSASigner(rsa_private_key, key_id="123")
assert isinstance(signer._impl, _python_rsa.RSASigner)
assert signer._impl._key == rsa_private_key
assert signer._impl.key_id == "123"

@pytest.mark.skipif(not rsa_lib, reason="rsa library not installed")
def test_warning_with_rsa(self, rsa_private_key):
with pytest.warns(DeprecationWarning, match="The 'rsa' library is deprecated"):
rsa.RSASigner(rsa_private_key, key_id="123")
Expand All @@ -130,8 +139,8 @@ def test_init_with_unknown_key(self):
with pytest.raises(ValueError):
rsa.RSASigner(unknown_key)

def test_sign_delegates(self, rsa_private_key):
signer = rsa.RSASigner(rsa_private_key)
def test_sign_delegates(self, cryptography_private_key):
signer = rsa.RSASigner(cryptography_private_key)

with mock.patch.object(
signer._impl, "sign", return_value=b"signature"
Expand Down Expand Up @@ -164,6 +173,7 @@ def test_end_to_end_cryptography_lib(self, private_key_bytes, public_key_bytes):
assert isinstance(verifier._impl, _cryptography_rsa.RSAVerifier)
assert isinstance(signer._impl, _cryptography_rsa.RSASigner)

@pytest.mark.skipif(not rsa_lib, reason="rsa library not installed")
def test_end_to_end_rsa_lib(self, rsa_private_key, rsa_public_key):
signer = rsa.RSASigner(rsa_private_key)
message = b"Hello World"
Expand Down
Loading