Skip to content

Commit c92e58f

Browse files
author
DhanashreePetare
committed
Restrict Vault token exchange to specific hosts; improve auth errors; add tests and docs note (fixes #19)
1 parent 9448228 commit c92e58f

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ docker run --rm -v $(pwd):/data dbpedia/databus-python-client download $DOWNLOAD
164164
- If no `--localdir` is provided, the current working directory is used as base directory. The downloaded files will be stored in the working directory in a folder structure according to the Databus layout, i.e. `./$ACCOUNT/$GROUP/$ARTIFACT/$VERSION/`.
165165
- `--vault-token`
166166
- If the dataset/files to be downloaded require vault authentication, you need to provide a vault token with `--vault-token /path/to/vault-token.dat`. See [Registration (Access Token)](#registration-access-token) for details on how to get a vault token.
167+
168+
Note: Vault tokens are only required for certain protected Databus hosts (for example: `data.dbpedia.io`, `data.dev.dbpedia.link`). The client now detects those hosts and will fail early with a clear message if a token is required but not provided. Do not pass `--vault-token` for public downloads.
167169
- `--databus-key`
168170
- If the databus is protected and needs API key authentication, you can provide the API key with `--databus-key YOUR_API_KEY`.
169171

databusclient/api/download.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ def _download_file(
6666
# --- 1. Get redirect URL by requesting HEAD ---
6767
headers = {}
6868

69-
# Determine hostname early and fail fast if this host requires Vault token
69+
# Determine hostname early and fail fast if this host requires Vault token.
70+
# This prevents confusing 401/403 errors later and tells the user exactly
71+
# what to do (provide --vault-token).
7072
parsed = urlparse(url)
7173
host = parsed.hostname
7274
if host in VAULT_REQUIRED_HOSTS and not vault_token_file:
@@ -105,22 +107,28 @@ def _download_file(
105107
www = response.headers.get("WWW-Authenticate", "") # Check if authentication is required
106108

107109
# --- 3. Handle authentication responses ---
108-
# 3a. Server requests Bearer auth
110+
# 3a. Server requests Bearer auth. Only attempt token exchange for hosts
111+
# we explicitly consider Vault-protected (VAULT_REQUIRED_HOSTS). This avoids
112+
# sending tokens to unrelated hosts and makes auth behavior predictable.
109113
if response.status_code == 401 and "bearer" in www.lower():
110-
# If host is not configured for Vault, do not attempt token exchange
114+
# If host is not configured for Vault, do not attempt token exchange.
111115
if host not in VAULT_REQUIRED_HOSTS:
112116
raise DownloadAuthError(
113117
"Server requests Bearer authentication but this host is not configured for Vault token exchange."
114118
" Try providing a databus API key with --databus-key or contact your administrator."
115119
)
116120

117-
# Host requires Vault; ensure token file provided
121+
# Host requires Vault; ensure token file provided.
118122
if not vault_token_file:
119123
raise DownloadAuthError(
120124
f"Vault token required for host '{host}', but no token was provided. Please use --vault-token."
121125
)
122126

123127
# --- 3b. Fetch Vault token and retry ---
128+
# Token exchange is potentially sensitive and should only be performed
129+
# for known hosts. __get_vault_access__ handles reading the refresh
130+
# token and exchanging it; errors are translated to DownloadAuthError
131+
# for user-friendly CLI output.
124132
vault_token = __get_vault_access__(url, vault_token_file, auth_url, client_id)
125133
headers["Authorization"] = f"Bearer {vault_token}"
126134
headers.pop("Accept-Encoding", None)

tests/test_download_auth.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import os
21
from unittest.mock import Mock, patch
32

43
import pytest

0 commit comments

Comments
 (0)