Skip to content

Commit

Permalink
enhance: 支持调整 auth timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
shabbywu committed Jan 26, 2024
1 parent 8c832f1 commit 1afef64
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 12 deletions.
2 changes: 1 addition & 1 deletion moby_distribution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from moby_distribution.spec.image_json import ImageJSON
from moby_distribution.spec.manifest import ManifestSchema1, ManifestSchema2, OCIManifestSchema1

__version__ = "0.5.9"
__version__ = "0.5.10"
__ALL__ = [
"DockerRegistryV2Client",
"Blob",
Expand Down
27 changes: 19 additions & 8 deletions moby_distribution/registry/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from www_authenticate import parse

from moby_distribution.registry.exceptions import AuthFailed
from moby_distribution.registry.utils import TypeTimeout
from moby_distribution.spec.auth import TokenResponse

AUTH_TIMEOUT = 60 * 3
AUTH_TIMEOUT = 30
logger = logging.getLogger(__name__)


Expand All @@ -35,7 +36,9 @@ def www_authenticate(self):
self._www_authenticate = parse(self._raw_www_authenticate)
return self._www_authenticate

def authenticate(self, username: Optional[str] = None, password: Optional[str] = None) -> AuthorizationProvider:
def authenticate(
self, username: Optional[str] = None, password: Optional[str] = None, *, timeout: TypeTimeout = AUTH_TIMEOUT
) -> AuthorizationProvider:
raise NotImplementedError

@property
Expand Down Expand Up @@ -73,7 +76,9 @@ def provide(self) -> str:
class HTTPBasicAuthentication(BaseAuthentication):
"""`HTTP Basic Authentication` Authenticator"""

def authenticate(self, username: Optional[str] = None, password: Optional[str] = None) -> AuthorizationProvider:
def authenticate(
self, username: Optional[str] = None, password: Optional[str] = None, *, timeout: TypeTimeout = AUTH_TIMEOUT
) -> AuthorizationProvider:
if username is None or password is None:
raise AuthFailed(
message="请提供用户名和密码",
Expand Down Expand Up @@ -108,7 +113,9 @@ def __init__(self, www_authenticate: str, offline_token: bool = True):
self.service = self.bearer["service"]
self.scope = self.bearer.get("scope", None)

def authenticate(self, username: Optional[str] = None, password: Optional[str] = None) -> AuthorizationProvider:
def authenticate(
self, username: Optional[str] = None, password: Optional[str] = None, *, timeout: TypeTimeout = AUTH_TIMEOUT
) -> AuthorizationProvider:
"""Authenticate to the registry.
If no username and password provided, will authenticate as the anonymous user.
Expand All @@ -130,7 +137,7 @@ def authenticate(self, username: Optional[str] = None, password: Optional[str] =
logger.warning("请同时提供 username 和 password!")

logger.info("sending authentication request to authorization service<%s>", self.backend)
resp = requests.get(self.backend, headers=headers, params=params, timeout=AUTH_TIMEOUT)
resp = requests.get(self.backend, headers=headers, params=params, timeout=timeout)
if resp.status_code != 200:
raise AuthFailed(
message="用户凭证校验失败, 请检查用户信息和操作权限",
Expand All @@ -143,9 +150,13 @@ def authenticate(self, username: Optional[str] = None, password: Optional[str] =
class UniversalAuthentication(BaseAuthentication):
"""An Auto auth backend, which will auto auth by `scheme` provided by www_authenticate"""

def authenticate(self, username: Optional[str] = None, password: Optional[str] = None) -> AuthorizationProvider:
def authenticate(
self, username: Optional[str] = None, password: Optional[str] = None, *, timeout: TypeTimeout = AUTH_TIMEOUT
) -> AuthorizationProvider:
if "basic" in self.www_authenticate:
return HTTPBasicAuthentication(self.raw_www_authenticate).authenticate(username, password)
return HTTPBasicAuthentication(self.raw_www_authenticate).authenticate(username, password, timeout=timeout)
elif "bearer" in self.www_authenticate:
return DockerRegistryTokenAuthentication(self.raw_www_authenticate).authenticate(username, password)
return DockerRegistryTokenAuthentication(self.raw_www_authenticate).authenticate(
username, password, timeout=timeout
)
raise NotImplementedError("未支持的认证方式")
10 changes: 8 additions & 2 deletions moby_distribution/registry/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def from_api_endpoint(
password: Optional[str] = None,
authenticator_class: Type[BaseAuthentication] = UniversalAuthentication,
default_timeout: TypeTimeout = 60 * 10,
https_detect_timeout: float = 10,
https_detect_timeout: float = 30,
):
https_scheme = "https://"
http_scheme = "http://"
Expand Down Expand Up @@ -62,15 +62,19 @@ def __init__(
verify_certificate: bool = True,
authenticator_class: Type[BaseAuthentication] = UniversalAuthentication,
default_timeout: TypeTimeout = 60 * 10,
auth_timeout: TypeTimeout = 30,
):
if default_timeout is not None and not isinstance(default_timeout, tuple) and isinf(default_timeout):
raise ValueError("default_timeout should not be infinity.")
if auth_timeout is not None and not isinstance(auth_timeout, tuple) and isinf(auth_timeout):
raise ValueError("auth_timeout should not be infinity.")
if api_base_url.endswith("/"):
api_base_url = api_base_url.rstrip("/")
self.api_base_url = api_base_url
self.session = requests.session()
self.session.verify = verify_certificate
self.default_timeout = default_timeout
self.auth_timeout = auth_timeout

self.username = username
self.password = password
Expand Down Expand Up @@ -141,7 +145,9 @@ def _validate_response(self, resp: requests.Response, auto_auth: bool = True) ->
if auto_auth:
www_authenticate = resp.headers["www-authenticate"]
auth = self.authenticator_class(www_authenticate)
self._authed = auth.authenticate(username=self.username, password=self.password)
self._authed = auth.authenticate(
username=self.username, password=self.password, timeout=self.auth_timeout
)
raise exceptions.RetryAgain

logger.debug("Requesting %s, but PermissionDeny, Equivalent curl command: %s", url, curl)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "moby-distribution"
version = "0.5.9"
version = "0.5.10"
description = "Yet another moby(docker) distribution implement by python."
authors = ["shabbywu <[email protected]>"]
license = "Apache-2.0"
Expand Down

0 comments on commit 1afef64

Please sign in to comment.