Skip to content

Commit 421b074

Browse files
committed
feat: Authentication property for HTTP Basic auth in URL
1 parent 896f77f commit 421b074

File tree

1 file changed

+41
-2
lines changed
  • airflow_dbt_python/utils

1 file changed

+41
-2
lines changed

airflow_dbt_python/utils/url.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,27 @@
66
from enum import Enum
77
from pathlib import Path
88
from tarfile import TarFile
9-
from typing import Generator, Union
9+
from typing import Generator, NamedTuple, Optional, Union
1010
from urllib.parse import ParseResult, urljoin, urlparse, urlunparse
1111
from zipfile import ZipFile
1212

1313
URLLike = Union["URL", str, Path]
1414

1515

16+
class HTTPAuthentication(NamedTuple):
17+
"""HTTP Basic Authentication parameters."""
18+
19+
username: Optional[str]
20+
password: Optional[str]
21+
22+
def __repr__(self) -> str:
23+
"""Return a representation of this HTTPAuthentication.
24+
25+
We hide username and password since both may contain sensitive values.
26+
"""
27+
return "HTTPAuthentication(username='***', password='***')"
28+
29+
1630
class SupportedArchives(str, Enum):
1731
"""Enumeration of supported archive formats."""
1832

@@ -333,6 +347,21 @@ def parent(self) -> "URL":
333347
"""
334348
return URL(self.path.parent)
335349

350+
@property
351+
def authentication(self) -> HTTPAuthentication:
352+
"""Return this URL HTTP Authentication (if any).
353+
354+
>>> URL("/local/path/to/project.zip").authentication
355+
HTTPAuthentication(username='***', password='***')
356+
>>> URL("https://user:pw@gitlab.com").authentication # pragma: allowlist secret
357+
HTTPAuthentication(username='***', password='***')
358+
>>> URL("https://username@gitlab.com").authentication
359+
HTTPAuthentication(username='***', password='***')
360+
"""
361+
return HTTPAuthentication(
362+
username=self._parsed.username, password=self._parsed.password
363+
)
364+
336365
def __truediv__(self, other) -> "URL":
337366
"""Allows concatenating a path to this URL's path.
338367
@@ -354,8 +383,18 @@ def __str__(self) -> str:
354383
355384
>>> str(URL("s3://s3-bucket/path/to/my/profiles.yml"))
356385
's3://s3-bucket/path/to/my/profiles.yml'
386+
>>> str(URL("https://hey:secret@gh.com/hey/repo")) # pragma: allowlist secret
387+
'https://hey:***@github.com/hey/my-repo'
357388
"""
358-
return self._parsed.geturl()
389+
url_str = self._parsed.geturl()
390+
391+
if self._parsed.password:
392+
url_str = url_str.replace(self._parsed.password, "***")
393+
394+
if self._parsed.username:
395+
url_str = url_str.replace(self._parsed.username, "***")
396+
397+
return url_str
359398

360399
def __repr__(self) -> str:
361400
"""Return a representation of this URL."""

0 commit comments

Comments
 (0)