Skip to content
Merged
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
7 changes: 6 additions & 1 deletion domaintools/api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from datetime import datetime, timedelta, timezone
from hashlib import sha1, sha256, md5
from hmac import new as hmac
from typing import Union

import re
import ssl

from domaintools.constants import Endpoint, ENDPOINT_TO_SOURCE_MAP, FEEDS_PRODUCTS_LIST, OutputFormat
from domaintools._version import current as version
Expand Down Expand Up @@ -76,7 +78,7 @@ def __init__(
self.username = username
self.key = key
self.https = https
self.verify_ssl = verify_ssl
self.verify_ssl = self._get_ssl_default_context(verify_ssl)
self.rate_limit = rate_limit
self.proxy_url = proxy_url
self.extra_request_params = {}
Expand All @@ -92,6 +94,9 @@ def __init__(
if proxy_url and not isinstance(proxy_url, str):
raise Exception("Proxy URL must be a string. For example: '127.0.0.1:8888'")

def _get_ssl_default_context(self, verify_ssl: Union[str, bool]):
return ssl.create_default_context(cafile=verify_ssl) if isinstance(verify_ssl, str) else verify_ssl

def _build_api_url(self, api_url=None, api_port=None):
"""Build the API url based on the given url and port. Defaults to `https://api.domaintools.com`"""
rest_api_url = "https://api.domaintools.com"
Expand Down
52 changes: 52 additions & 0 deletions tests/e2e/scripts/test_e2e_runner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

# Script Requirements
# docker

MITM_BASIC_AUTH_CONTAINER_NAME="e2e_test_mitm_basic_auth"
MITM_CUSTOM_CERT_CONTAINER_NAME="e2e_test_mitm_custom_cert"
DOCKER_NETWORK_NAME="e2e_test_docker_network"

echo "Starting e2e tests..."

echo "Create a bridge network for the containers to communicate"
docker network create ${DOCKER_NETWORK_NAME}

echo "Spinning ${MITM_BASIC_AUTH_CONTAINER_NAME}"
docker run --rm -d \
--name ${MITM_BASIC_AUTH_CONTAINER_NAME} \
--network ${DOCKER_NETWORK_NAME} \
-p 8080:8080 mitmproxy/mitmproxy mitmdump \
--set proxyauth="username:pass"

echo "Spinning ${MITM_CUSTOM_CERT_CONTAINER_NAME}"
docker run --rm -d -v ~/.test_mitmproxy:/home/mitmproxy/.mitmproxy \
--name ${MITM_CUSTOM_CERT_CONTAINER_NAME} \
--network ${DOCKER_NETWORK_NAME} \
-p 8090:8090 mitmproxy/mitmproxy mitmdump \
--set listen_port=8090

# Check until custom cert from mitmproxy container is copied locally
echo "Checking for valid custom cert..."
while [ ! -f ~/.test_mitmproxy/mitmproxy-ca.pem ] ;
do
sleep 2
done
echo "Valid custom cert found!"

# Copy valid custom cert to target dir
cp ~/.test_mitmproxy/mitmproxy-ca.pem tests/e2e/mitmproxy-ca.pem

echo "E2E processing..."
python -m pytest -s --capture=sys -v --cov=domaintools tests/e2e

# Clean up containers
echo "Bringing down containers..."
docker stop ${MITM_BASIC_AUTH_CONTAINER_NAME} || true
docker stop ${MITM_CUSTOM_CERT_CONTAINER_NAME} || true
docker network rm ${DOCKER_NETWORK_NAME} || true

# Clean up custom certs
echo "Removing custom certs..."
rm -rf tests/e2e/mitmproxy-ca.pem
rm -rf ~/.test_mitmproxy
49 changes: 49 additions & 0 deletions tests/e2e/test_proxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""Tests proxy support for DomainTools APIs"""

import pytest

from httpx import ProxyError
from tests.settings import api


class TestProxy:

def test_account_information_using_proxy_with_basic_auth_should_succeed_if_correct_username_and_password_were_used(self):
api.verify_ssl = False
api.proxy_url = "http://username:pass@localhost:8080"
with api.account_information() as account_information:
assert "products" in account_information
for product in account_information:
assert "id" in product
assert "per_month_limit" in product
assert "absolute_limit" in product
assert "usage" in product
assert "expiration_date" in product

def test_account_information_using_proxy_with_basic_auth_should_fail_if_no_username_and_password_was_used(self):
api.verify_ssl = False
api.proxy_url = "http://localhost:8080"
with pytest.raises(ProxyError):
account_information = api.account_information()
account_information.response()

def test_account_information_using_proxy_with_basic_auth_should_fail_if_wrong_username_was_used(self):
api.verify_ssl = False
api.proxy_url = "http://wrongusername:pass@localhost:8080"
with pytest.raises(ProxyError):
account_information = api.account_information()
account_information.response()

def test_account_information_using_proxy_with_basic_auth_should_fail_if_wrong_password_was_used(self):
api.verify_ssl = False
api.proxy_url = "http://username:wrongpass@localhost:8080"
with pytest.raises(ProxyError):
account_information = api.account_information()
account_information.response()

def test_account_information_using_proxy_with_basic_auth_should_fail_if_wrong_username_and_password_were_used(self):
api.verify_ssl = False
api.proxy_url = "http://wrongusername:wrongpass@localhost:8080"
with pytest.raises(ProxyError):
account_information = api.account_information()
account_information.response()
42 changes: 42 additions & 0 deletions tests/e2e/test_ssl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Tests proxy support for DomainTools APIs"""

import pytest

from httpx import ConnectError
from tests.settings import api


class TestSsl:

def test_account_information_using_proxy_with_custom_cert_should_succeed_if_using_the_valid_custom_cert(self):
api.verify_ssl = "tests/e2e/mitmproxy-ca.pem"
api.proxy_url = "http://localhost:8090"
with api.account_information() as account_information:
assert "products" in account_information
for product in account_information:
assert "id" in product
assert "per_month_limit" in product
assert "absolute_limit" in product
assert "usage" in product
assert "expiration_date" in product

def test_account_information_using_proxy_with_custom_cert_should_be_successful_when_verify_ssl_is_disabled(self):
api.verify_ssl = False
api.proxy_url = "http://localhost:8090"
with api.account_information() as account_information:
assert "products" in account_information
for product in account_information:
assert "id" in product
assert "per_month_limit" in product
assert "absolute_limit" in product
assert "usage" in product
assert "expiration_date" in product

def test_account_information_using_proxy_with_custom_cert_should_fail_when_verify_ssl_is_enabled_but_not_using_the_installed_custom_cert(
self,
):
api.verify_ssl = True
api.proxy_url = "http://localhost:8090"
with pytest.raises(ConnectError):
account_information = api.account_information()
account_information.response()
4 changes: 3 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ deps=
rich
typer
.
commands=py.test -s --capture=sys --cov=domaintools --cov=domaintools_async tests
commands =
py.test -s --capture=sys --cov=domaintools --cov=domaintools_async tests \
--ignore=tests/e2e
coverage html
Loading