Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug with httpx usage - ensure basic auth is set when provided #285

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ipfshttpclient/http_httpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def _request(
url=path,
**map_args_to_httpx(
params=params,
auth=auth,
auth=auth or session.auth, # type: ignore[arg-type]
headers=headers,
timeout=timeout,
),
Expand Down
65 changes: 65 additions & 0 deletions test/functional/conftest.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,87 @@
# Note that this file is special in that py.test will automatically import this file and gather
# its list of fixtures even if it is not directly imported into the corresponding test case.

import os
import pathlib
import pytest
import sys
import typing as ty
from multiaddr import Multiaddr

import ipfshttpclient


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


def _running_in_linux() -> bool:
return sys.platform == 'linux'


def _running_in_travis_ci() -> bool:
return '/home/travis/build' in os.getenv('PATH')


@pytest.fixture(scope='session')
def fake_dir() -> pathlib.Path:
return TEST_DIR.joinpath('fake_dir')


@pytest.fixture(scope='session')
def docker_compose_file() -> str:
"""
Override the location of the file used by pytest-docker.

The fixture name must be docker_compose_file and return str.
"""

if _running_in_travis_ci():
pytest.skip('Docker hub reports rate limit errors on pulls from Travis CI servers')
elif not _running_in_linux():
pytest.skip("No IPFS server build for Windows; Travis doesn't support Docker on mac")

return str(TEST_DIR.joinpath('docker-compose.yml'))


@pytest.fixture(scope='session')
def ipfs_service_address(docker_ip, docker_services, ipfs_service_auth) -> Multiaddr:
port = docker_services.port_for('proxy', 80)
address = Multiaddr(f'/ip4/{docker_ip}/tcp/{port}')

print(f'Will connect to {address}')

def is_responsive() -> bool:
try:
with ipfshttpclient.connect(address, auth=ipfs_service_auth):
pass
except ipfshttpclient.exceptions.Error:
return False
else:
return True

docker_services.wait_until_responsive(
timeout=20, # Pulling the docker image is not included in this timeout
pause=0.5,
check=is_responsive
)

return address


@pytest.fixture(scope='session')
def ipfs_service_auth() -> ty.Tuple[str, str]:
return 'TheUser', 'ThePassword'


@pytest.fixture(scope="function")
def ipfs_service_client(ipfs_service_address, ipfs_service_auth):
with ipfshttpclient.connect(
addr=ipfs_service_address,
auth=ipfs_service_auth
) as client:
yield client


@pytest.fixture(scope='session')
def ipfs_is_available() -> bool:
"""
Expand Down
14 changes: 14 additions & 0 deletions test/functional/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3.8'
services:
ipfs:
build:
dockerfile: ../../tools/ipfs/Dockerfile
context: ../../tools/ipfs
expose: [5001]

proxy:
depends_on: [ipfs]
build:
dockerfile: ../../tools/nginx/Dockerfile
context: ../../tools/nginx
ports: [80:80]
12 changes: 12 additions & 0 deletions test/functional/test_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@


def test_basic_auth(ipfs_service_client):
"""
Validate that client can connect to an IPFS api that is secured
behind an HTTP reverse proxy requiring basic authentication.
"""

response = ipfs_service_client.version()

# Matches version in test/functional/docker-compose.yml
assert response['Version'] == '0.8.0'
7 changes: 5 additions & 2 deletions test/functional/test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@
FAKE_FILE1_PATH = conftest.TEST_DIR / "fake_dir" / "fsdfgh"
FAKE_FILE2_PATH = conftest.TEST_DIR / "fake_dir" / "popoiopiu"

FAKE_FILE1_HASH = {"Hash": "QmQcCtMgLVwvMQGu6mvsRYLjwqrZJcYtH4mboM9urWW9vX",
"Name": "fsdfgh", "Size": "16"}
FAKE_FILE1_HASH = {
"Hash": "QmQcCtMgLVwvMQGu6mvsRYLjwqrZJcYtH4mboM9urWW9vX",
"Name": "fsdfgh", "Size": "16"
}

FAKE_FILE1_RAW_LEAVES_HASH = {
"Hash": "zb2rhXxZH5PFgCwBAm7xQMoBa6QWqytN8NPvXK7Qc9McDz9zJ",
"Name": "fsdfgh", "Size": "8"
Expand Down
7 changes: 7 additions & 0 deletions tools/ipfs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM ipfs/go-ipfs:v0.8.0

RUN sed -i 's/exec ipfs "$@"//' /usr/local/bin/start_ipfs
ADD entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]
CMD ["ipfs", "daemon", "--migrate=true", "--enable-namesys-pubsub"]
15 changes: 15 additions & 0 deletions tools/ipfs/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

set -e

# Only does configuration; doesn't start the daemon
/usr/local/bin/start_ipfs

echo "Enabling experimental features"

ipfs config --json Experimental.FilestoreEnabled true

echo "Enabled experimental features"

# Start the daemon (unless other args provided)
exec "$@"
12 changes: 12 additions & 0 deletions tools/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM nginx:1.19.10

RUN apt-get update -y && apt-get install -y apache2-utils
RUN mkdir /secrets \
&& cd /secrets \
&& htpasswd -cb htpasswd TheUser ThePassword

ADD entrypoint.sh /usr/local/sbin/entrypoint
ADD default.conf /etc/nginx/conf.d/default.conf

CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["/usr/local/sbin/entrypoint"]
16 changes: 16 additions & 0 deletions tools/nginx/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
server {
listen 80;

location / {
proxy_read_timeout 60;
proxy_connect_timeout 60;
client_max_body_size 104857600;

proxy_pass http://ipfs:5001;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

auth_basic "Some Realm";
auth_basic_user_file /secrets/htpasswd;
}
}
3 changes: 3 additions & 0 deletions tools/nginx/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

exec "$@"
2 changes: 2 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ isolated_build = true

[testenv]
deps =
docker-compose ~= 1.29
pytest ~= 6.2
pytest-cov ~= 2.11
pytest-dependency ~= 0.5
pytest-docker ~= 0.10
pytest-localserver ~= 0.5
pytest-mock ~= 3.5
pytest-ordering ~= 0.6
Expand Down