mirror of
https://github.com/certbot/certbot.git
synced 2026-07-27 00:00:44 +02:00
Typed jose fields (#9073)
* Add generic methods to save some casts, and fix lint * Update current and oldest pinning * Fix classes * Remove some todos thanks to josepy 1.11.0 * Cleanup some useless pylint disable * Finish complete typing * Better TypeVar names * Upgrade pinning and fix some typing errors * Use protocol * Fix types in apache Co-authored-by: Brad Warren <bmw@users.noreply.github.com>
This commit is contained in:
co-authored by
Brad Warren
parent
7198f43008
commit
dac0b2c187
@@ -54,9 +54,9 @@ class Account:
|
||||
cross-machine migration scenarios.
|
||||
|
||||
"""
|
||||
creation_dt = acme_fields.RFC3339Field("creation_dt")
|
||||
creation_host = jose.Field("creation_host")
|
||||
register_to_eff = jose.Field("register_to_eff", omitempty=True)
|
||||
creation_dt: datetime.datetime = acme_fields.rfc3339("creation_dt")
|
||||
creation_host: str = jose.field("creation_host")
|
||||
register_to_eff: str = jose.field("register_to_eff", omitempty=True)
|
||||
|
||||
def __init__(self, regr: messages.RegistrationResource, key: jose.JWK,
|
||||
meta: Optional['Meta'] = None) -> None:
|
||||
@@ -135,7 +135,7 @@ class RegistrationResourceWithNewAuthzrURI(messages.RegistrationResource):
|
||||
continue to write out this field for some time so older
|
||||
clients don't crash in that scenario.
|
||||
"""
|
||||
new_authzr_uri = jose.Field('new_authzr_uri')
|
||||
new_authzr_uri: str = jose.field('new_authzr_uri')
|
||||
|
||||
|
||||
class AccountFileStorage(interfaces.AccountStorage):
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import Dict
|
||||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
|
||||
@@ -272,7 +273,7 @@ class AuthHandler:
|
||||
self.auth.cleanup(achalls)
|
||||
|
||||
def _challenge_factory(self, authzr: messages.AuthorizationResource,
|
||||
path: List[int]) -> List[achallenges.AnnotatedChallenge]:
|
||||
path: Sequence[int]) -> List[achallenges.AnnotatedChallenge]:
|
||||
"""Construct Namedtuple Challenges
|
||||
|
||||
:param messages.AuthorizationResource authzr: authorization
|
||||
@@ -350,7 +351,7 @@ def challb_to_achall(challb: messages.ChallengeBody, account_key: josepy.JWK,
|
||||
|
||||
def gen_challenge_path(challbs: List[messages.ChallengeBody],
|
||||
preferences: List[Type[challenges.Challenge]],
|
||||
combinations: Tuple[List[int], ...]) -> List[int]:
|
||||
combinations: Tuple[Tuple[int, ...], ...]) -> Tuple[int, ...]:
|
||||
"""Generate a plan to get authority over the identity.
|
||||
|
||||
.. todo:: This can be possibly be rewritten to use resolved_combinations.
|
||||
@@ -383,8 +384,8 @@ def gen_challenge_path(challbs: List[messages.ChallengeBody],
|
||||
|
||||
def _find_smart_path(challbs: List[messages.ChallengeBody],
|
||||
preferences: List[Type[challenges.Challenge]],
|
||||
combinations: Tuple[List[int], ...]
|
||||
) -> List[int]:
|
||||
combinations: Tuple[Tuple[int, ...], ...]
|
||||
) -> Tuple[int, ...]:
|
||||
"""Find challenge path with server hints.
|
||||
|
||||
Can be called if combinations is included. Function uses a simple
|
||||
@@ -399,7 +400,7 @@ def _find_smart_path(challbs: List[messages.ChallengeBody],
|
||||
|
||||
# max_cost is now equal to sum(indices) + 1
|
||||
|
||||
best_combo: Optional[List[int]] = None
|
||||
best_combo: Optional[Tuple[int, ...]] = None
|
||||
# Set above completing all of the available challenges
|
||||
best_combo_cost = max_cost
|
||||
|
||||
@@ -422,7 +423,7 @@ def _find_smart_path(challbs: List[messages.ChallengeBody],
|
||||
|
||||
|
||||
def _find_dumb_path(challbs: List[messages.ChallengeBody],
|
||||
preferences: List[Type[challenges.Challenge]]) -> List[int]:
|
||||
preferences: List[Type[challenges.Challenge]]) -> Tuple[int, ...]:
|
||||
"""Find challenge path without server hints.
|
||||
|
||||
Should be called if the combinations hint is not included by the
|
||||
@@ -440,7 +441,7 @@ def _find_dumb_path(challbs: List[messages.ChallengeBody],
|
||||
else:
|
||||
raise _report_no_chall_path(challbs)
|
||||
|
||||
return path
|
||||
return tuple(path)
|
||||
|
||||
|
||||
def _report_no_chall_path(challbs: List[messages.ChallengeBody]) -> errors.AuthorizationError:
|
||||
|
||||
@@ -251,7 +251,7 @@ def perform_registration(acme: acme_client.ClientV2, config: configuration.Names
|
||||
raise errors.Error("The ACME client must be an instance of "
|
||||
"acme.client.BackwardsCompatibleClientV2")
|
||||
except messages.Error as e:
|
||||
if e.code in ('invalidEmail', 'invalidContact'):
|
||||
if e.code in ("invalidEmail", "invalidContact"):
|
||||
if config.noninteractive_mode:
|
||||
msg = ("The ACME server believes %s is an invalid email address. "
|
||||
"Please ensure it is a valid email and attempt "
|
||||
|
||||
@@ -98,7 +98,7 @@ permitted by DNS standards.)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.reverter = reverter.Reverter(self.config)
|
||||
self.reverter.recovery_routine()
|
||||
self.env: Dict[achallenges.KeyAuthorizationAnnotatedChallenge, Dict[str, str]] = {}
|
||||
self.env: Dict[achallenges.AnnotatedChallenge, Dict[str, str]] = {}
|
||||
self.subsequent_dns_challenge = False
|
||||
self.subsequent_any_challenge = False
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ logger = logging.getLogger(__name__)
|
||||
if TYPE_CHECKING:
|
||||
ServedType = DefaultDict[
|
||||
acme_standalone.BaseDualNetworkedServers,
|
||||
Set[achallenges.KeyAuthorizationAnnotatedChallenge]
|
||||
Set[achallenges.AnnotatedChallenge]
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ from certbot import crypto_util
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot._internal import cli
|
||||
from certbot.achallenges import KeyAuthorizationAnnotatedChallenge as AnnotatedChallenge
|
||||
from certbot.achallenges import AnnotatedChallenge
|
||||
from certbot.compat import filesystem
|
||||
from certbot.compat import os
|
||||
from certbot.display import ops
|
||||
@@ -85,7 +85,7 @@ to serve all files under specified web root ({0})."""
|
||||
"file, it needs to be on a single line, like: webroot-map = "
|
||||
'{"example.com":"/var/www"}.')
|
||||
|
||||
def auth_hint(self, failed_achalls: Iterable[AnnotatedChallenge]) -> str: # pragma: no cover
|
||||
def auth_hint(self, failed_achalls: List[AnnotatedChallenge]) -> str: # pragma: no cover
|
||||
return ("The Certificate Authority failed to download the temporary challenge files "
|
||||
"created by Certbot. Ensure that the listed domains serve their content from "
|
||||
"the provided --webroot-path/-w and that files created there can be downloaded "
|
||||
@@ -105,7 +105,7 @@ to serve all files under specified web root ({0})."""
|
||||
def prepare(self) -> None: # pylint: disable=missing-function-docstring
|
||||
pass
|
||||
|
||||
def perform(self, achalls: Iterable[AnnotatedChallenge]) -> List[challenges.ChallengeResponse]: # pylint: disable=missing-function-docstring
|
||||
def perform(self, achalls: List[AnnotatedChallenge]) -> List[challenges.ChallengeResponse]: # pylint: disable=missing-function-docstring
|
||||
self._set_webroots(achalls)
|
||||
|
||||
self._create_challenge_dirs()
|
||||
@@ -257,7 +257,7 @@ to serve all files under specified web root ({0})."""
|
||||
self.performed[root_path].add(achall)
|
||||
return response
|
||||
|
||||
def cleanup(self, achalls: Iterable[AnnotatedChallenge]) -> None: # pylint: disable=missing-function-docstring
|
||||
def cleanup(self, achalls: List[AnnotatedChallenge]) -> None: # pylint: disable=missing-function-docstring
|
||||
for achall in achalls:
|
||||
root_path = self.full_roots.get(achall.domain, None)
|
||||
if root_path is not None:
|
||||
|
||||
@@ -29,7 +29,7 @@ class Reporter:
|
||||
_msg_type = collections.namedtuple('_msg_type', 'priority text on_crash')
|
||||
|
||||
def __init__(self, config: configuration.NamespaceConfig) -> None:
|
||||
self.messages: queue.PriorityQueue[Reporter._msg_type] = queue.PriorityQueue()
|
||||
self.messages: "queue.PriorityQueue[Reporter._msg_type]" = queue.PriorityQueue()
|
||||
self.config = config
|
||||
|
||||
def add_message(self, msg: str, priority: int, on_crash: bool = True) -> None:
|
||||
|
||||
@@ -18,8 +18,8 @@ try:
|
||||
from urllib3.connectionpool import HTTPConnectionPool
|
||||
except ImportError:
|
||||
# Stub imports for oldest requirements, that will never be used in snaps.
|
||||
HTTPConnection = object
|
||||
HTTPConnectionPool = object
|
||||
HTTPConnection = object # type: ignore[misc,assignment]
|
||||
HTTPConnectionPool = object # type: ignore[misc,assignment]
|
||||
|
||||
|
||||
_ARCH_TRIPLET_MAP = {
|
||||
|
||||
@@ -290,8 +290,11 @@ def make_key(bits: int = 1024, key_type: str = "rsa",
|
||||
try:
|
||||
name = elliptic_curve.upper()
|
||||
if name in ('SECP256R1', 'SECP384R1', 'SECP521R1'):
|
||||
curve = getattr(ec, elliptic_curve.upper())
|
||||
if not curve:
|
||||
raise errors.Error(f"Invalid curve type: {elliptic_curve}")
|
||||
_key = ec.generate_private_key(
|
||||
curve=getattr(ec, elliptic_curve.upper(), None)(),
|
||||
curve=curve(),
|
||||
backend=default_backend()
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -18,6 +18,8 @@ from typing import Tuple
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from acme import challenges
|
||||
|
||||
from certbot import achallenges
|
||||
from certbot import configuration
|
||||
from certbot import crypto_util
|
||||
@@ -377,7 +379,7 @@ class ChallengePerformer:
|
||||
if idx is not None:
|
||||
self.indices.append(idx)
|
||||
|
||||
def perform(self) -> List[achallenges.KeyAuthorizationAnnotatedChallenge]:
|
||||
def perform(self) -> List[challenges.KeyAuthorizationChallengeResponse]:
|
||||
"""Perform all added challenges.
|
||||
|
||||
:returns: challenge responses
|
||||
|
||||
@@ -7,8 +7,8 @@ import josepy as jose
|
||||
from requests.exceptions import HTTPError
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from acme.challenges import Challenge
|
||||
from certbot import errors
|
||||
from certbot.achallenges import AnnotatedChallenge
|
||||
from certbot.plugins import dns_test_common
|
||||
from certbot.plugins.dns_common_lexicon import LexiconClient
|
||||
from certbot.plugins.dns_test_common import _AuthenticatorCallableTestCase
|
||||
@@ -33,7 +33,7 @@ class _AuthenticatorCallableLexiconTestCase(_AuthenticatorCallableTestCase, Prot
|
||||
a mocked LexiconClient instance.
|
||||
"""
|
||||
mock_client: MagicMock
|
||||
achall: Challenge
|
||||
achall: AnnotatedChallenge
|
||||
|
||||
|
||||
class _LexiconAwareTestCase(Protocol):
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""ACME utilities for testing."""
|
||||
import datetime
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Iterable
|
||||
from typing import Tuple
|
||||
|
||||
@@ -74,7 +76,7 @@ def gen_authzr(authz_status: messages.Status, domain: str, challs: Iterable[chal
|
||||
chall_to_challb(chall, status)
|
||||
for chall, status in zip(challs, statuses)
|
||||
)
|
||||
authz_kwargs = {
|
||||
authz_kwargs: Dict[str, Any] = {
|
||||
"identifier": messages.Identifier(
|
||||
typ=messages.IDENTIFIER_FQDN, value=domain),
|
||||
"challenges": challbs,
|
||||
|
||||
Reference in New Issue
Block a user