Skip to content

Commit e876178

Browse files
committed
Fix bug with httpx usage - ensure that basic auth is set when provided
1 parent e02a95f commit e876178

File tree

10 files changed

+147
-1
lines changed

10 files changed

+147
-1
lines changed

ipfshttpclient/http_httpx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def _request(
179179
url=path,
180180
**map_args_to_httpx(
181181
params=params,
182-
auth=auth,
182+
auth=auth or session.auth, # type: ignore[arg-type]
183183
headers=headers,
184184
timeout=timeout,
185185
),

test/functional/conftest.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,87 @@
11
# Note that this file is special in that py.test will automatically import this file and gather
22
# its list of fixtures even if it is not directly imported into the corresponding test case.
33

4+
import os
45
import pathlib
56
import pytest
67
import sys
78
import typing as ty
9+
from multiaddr import Multiaddr
810

911
import ipfshttpclient
1012

1113

1214
TEST_DIR: pathlib.Path = pathlib.Path(__file__).parent
1315

1416

17+
def _running_in_linux() -> bool:
18+
return sys.platform == 'linux'
19+
20+
21+
def _running_in_travis_ci() -> bool:
22+
return '/home/travis/build' in os.getenv('PATH')
23+
24+
1525
@pytest.fixture(scope='session')
1626
def fake_dir() -> pathlib.Path:
1727
return TEST_DIR.joinpath('fake_dir')
1828

1929

30+
@pytest.fixture(scope='session')
31+
def docker_compose_file() -> str:
32+
"""
33+
Override the location of the file used by pytest-docker.
34+
35+
The fixture name must be docker_compose_file and return str.
36+
"""
37+
38+
if _running_in_travis_ci():
39+
pytest.skip('Docker hub reports rate limit errors on pulls from Travis CI servers')
40+
elif not _running_in_linux():
41+
pytest.skip("No IPFS server build for Windows; Travis doesn't support Docker on mac")
42+
43+
return str(TEST_DIR.joinpath('docker-compose.yml'))
44+
45+
46+
@pytest.fixture(scope='session')
47+
def ipfs_service_address(docker_ip, docker_services, ipfs_service_auth) -> Multiaddr:
48+
port = docker_services.port_for('proxy', 80)
49+
address = Multiaddr(f'/ip4/{docker_ip}/tcp/{port}')
50+
51+
print(f'Will connect to {address}')
52+
53+
def is_responsive() -> bool:
54+
try:
55+
with ipfshttpclient.connect(address, auth=ipfs_service_auth):
56+
pass
57+
except ipfshttpclient.exceptions.Error:
58+
return False
59+
else:
60+
return True
61+
62+
docker_services.wait_until_responsive(
63+
timeout=20, # Pulling the docker image is not included in this timeout
64+
pause=0.5,
65+
check=is_responsive
66+
)
67+
68+
return address
69+
70+
71+
@pytest.fixture(scope='session')
72+
def ipfs_service_auth() -> ty.Tuple[str, str]:
73+
return 'TheUser', 'ThePassword'
74+
75+
76+
@pytest.fixture(scope="function")
77+
def ipfs_service_client(ipfs_service_address, ipfs_service_auth):
78+
with ipfshttpclient.connect(
79+
addr=ipfs_service_address,
80+
auth=ipfs_service_auth
81+
) as client:
82+
yield client
83+
84+
2085
@pytest.fixture(scope='session')
2186
def ipfs_is_available() -> bool:
2287
"""

test/functional/docker-compose.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: '3.8'
2+
services:
3+
ipfs:
4+
build:
5+
dockerfile: ../../tools/ipfs/Dockerfile
6+
context: ../../tools/ipfs
7+
expose: [5001]
8+
9+
proxy:
10+
depends_on: [ipfs]
11+
build:
12+
dockerfile: ../../tools/nginx/Dockerfile
13+
context: ../../tools/nginx
14+
ports: [80:80]

test/functional/test_auth.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
3+
def test_basic_auth(ipfs_service_client):
4+
"""
5+
Validate that client can connect to an IPFS api that is secured
6+
behind an HTTP reverse proxy requiring basic authentication.
7+
"""
8+
9+
response = ipfs_service_client.version()
10+
11+
# Matches version in test/functional/docker-compose.yml
12+
assert response['Version'] == '0.8.0'

tools/ipfs/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM ipfs/go-ipfs:v0.8.0
2+
3+
RUN sed -i 's/exec ipfs "$@"//' /usr/local/bin/start_ipfs
4+
ADD entrypoint.sh /
5+
6+
ENTRYPOINT ["/entrypoint.sh"]
7+
CMD ["ipfs", "daemon", "--migrate=true", "--enable-namesys-pubsub"]

tools/ipfs/entrypoint.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
# Only does configuration; doesn't start the daemon
6+
/usr/local/bin/start_ipfs
7+
8+
echo "Enabling experimental features"
9+
10+
ipfs config --json Experimental.FilestoreEnabled true
11+
12+
echo "Enabled experimental features"
13+
14+
# Start the daemon (unless other args provided)
15+
exec "$@"

tools/nginx/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM nginx:1.19.10
2+
3+
RUN apt-get update -y && apt-get install -y apache2-utils
4+
RUN mkdir /secrets \
5+
&& cd /secrets \
6+
&& htpasswd -cb htpasswd TheUser ThePassword
7+
8+
ADD entrypoint.sh /usr/local/sbin/entrypoint
9+
ADD default.conf /etc/nginx/conf.d/default.conf
10+
11+
CMD ["nginx", "-g", "daemon off;"]
12+
ENTRYPOINT ["/usr/local/sbin/entrypoint"]

tools/nginx/default.conf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
server {
2+
listen 80;
3+
4+
location / {
5+
proxy_read_timeout 60;
6+
proxy_connect_timeout 60;
7+
client_max_body_size 104857600;
8+
9+
proxy_pass http://ipfs:5001;
10+
proxy_http_version 1.1;
11+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
12+
13+
auth_basic "Some Realm";
14+
auth_basic_user_file /secrets/htpasswd;
15+
}
16+
}

tools/nginx/entrypoint.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
exec "$@"

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ isolated_build = true
1313

1414
[testenv]
1515
deps =
16+
docker-compose ~= 1.29
1617
pytest ~= 6.2
1718
pytest-cov ~= 2.11
1819
pytest-dependency ~= 0.5
20+
pytest-docker ~= 0.10
1921
pytest-localserver ~= 0.5
2022
pytest-mock ~= 3.5
2123
pytest-ordering ~= 0.6

0 commit comments

Comments
 (0)