diff --git a/dclient/cli.py b/dclient/cli.py index 26aeb0b..6ba3faa 100644 --- a/dclient/cli.py +++ b/dclient/cli.py @@ -2,6 +2,7 @@ import click import httpx import json import pathlib +from .utils import url_matches_prefix def get_config_dir(): @@ -79,7 +80,7 @@ def query(url, sql, token): def _token_for_url_from_auth(url, auth_file): auths = _load_auths(auth_file) for auth_url, token in auths.items(): - if url.startswith(auth_url): + if url_matches_prefix(url, auth_url): return token diff --git a/dclient/utils.py b/dclient/utils.py new file mode 100644 index 0000000..b03df35 --- /dev/null +++ b/dclient/utils.py @@ -0,0 +1,30 @@ +from urllib.parse import urlparse + + +def url_matches_prefix(url: str, prefix: str) -> bool: + url_parsed = urlparse(url) + prefix_parsed = urlparse(prefix) + + if ( + url_parsed.scheme != prefix_parsed.scheme + or url_parsed.netloc != prefix_parsed.netloc + ): + return False + + if url_parsed.path == prefix_parsed.path: + return True + + url_path = url_parsed.path + + # Add '/' to the end of the paths if they don't already end with '/' + prefix_path = prefix_parsed.path + + # Special treatment for /foo.json + if url_path.endswith(".json"): + if prefix_path + ".json" == url_path: + return True + + if not prefix_path.endswith("/"): + prefix_path += "/" + + return url_path.startswith(prefix_path) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..2219a0b --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,41 @@ +from dclient.utils import url_matches_prefix +import pytest + + +@pytest.mark.parametrize( + "url,prefix_url,expected", + ( + ("https://example.com/foo/bar", "https://example.com/foo", True), + ("https://example.com/foo/bar2", "https://example.com/foo/bar", False), + ("https://example.com/foo/bar/baz", "https://example.com/foo/bar", True), + ("https://example.com/foo/bar/baz", "https://example.com/foo", True), + ("https://example.com/foo.json", "https://example.com/foo", True), + # different scheme + ( + "http://example.com/foo/bar", + "https://example.com/foo", + False, + ), + # different netloc + ( + "https://example.org/foo/bar", + "https://example.com/foo", + False, + ), + # exactly the same + ("https://example.com/foo", "https://example.com/foo", True), + # trailing '/' + ( + "https://example.com/foo/bar", + "https://example.com/foo/bar/", + False, + ), + ( + "https://example.com/foo/bar/baz", + "https://example.com/foo/bar/", + True, + ), + ), +) +def test_url_matches_prefix(url, prefix_url, expected): + assert url_matches_prefix(url, prefix_url) == expected