Skip to content

Commit

Permalink
port custom ca cert test to python
Browse files Browse the repository at this point in the history
  • Loading branch information
hubertdeng123 committed Apr 16, 2024
1 parent 3d63c9b commit f1f43eb
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 98 deletions.
28 changes: 16 additions & 12 deletions _integration-test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import subprocess
import os
import subprocess
import time

import httpx
import pytest

Expand All @@ -10,8 +11,10 @@
TEST_PASS = "test123TEST"
TIMEOUT_SECONDS = 60


def pytest_addoption(parser):
parser.addoption("--customizations", default="disabled")
parser.addoption("--customizations", default="disabled")


@pytest.fixture(scope="session", autouse=True)
def configure_self_hosted_environment(request):
Expand All @@ -28,23 +31,23 @@ def configure_self_hosted_environment(request):
raise AssertionError("timeout waiting for self-hosted to come up")

if request.config.getoption("--customizations") == "enabled":
os.environ['TEST_CUSTOMIZATIONS'] = "enabled"
script_content = '''\
os.environ["TEST_CUSTOMIZATIONS"] = "enabled"
script_content = """\
#!/bin/bash
touch /created-by-enhance-image
apt-get update
apt-get install -y gcc libsasl2-dev python-dev libldap2-dev libssl-dev
'''
"""

with open('sentry/enhance-image.sh', 'w') as script_file:
with open("sentry/enhance-image.sh", "w") as script_file:
script_file.write(script_content)
# Set executable permissions for the shell script
os.chmod('sentry/enhance-image.sh', 0o755)
os.chmod("sentry/enhance-image.sh", 0o755)

# Write content to the requirements.txt file
with open('sentry/requirements.txt', 'w') as req_file:
req_file.write('python-ldap\n')
os.environ['MINIMIZE_DOWNTIME'] = "1"
with open("sentry/requirements.txt", "w") as req_file:
req_file.write("python-ldap\n")
os.environ["MINIMIZE_DOWNTIME"] = "1"
subprocess.run(["./install.sh"], check=True)
# Create test user
subprocess.run(
Expand All @@ -68,7 +71,8 @@ def configure_self_hosted_environment(request):
text=True,
)


@pytest.fixture()
def setup_backup_restore_env_variables():
os.environ['SENTRY_DOCKER_IO_DIR'] = os.path.join(os.getcwd(), 'sentry')
os.environ['SKIP_USER_CREATION'] = "1"
os.environ["SENTRY_DOCKER_IO_DIR"] = os.path.join(os.getcwd(), "sentry")
os.environ["SKIP_USER_CREATION"] = "1"
46 changes: 0 additions & 46 deletions _integration-test/custom-ca-roots/setup.sh

This file was deleted.

4 changes: 0 additions & 4 deletions _integration-test/custom-ca-roots/teardown.sh

This file was deleted.

5 changes: 3 additions & 2 deletions _integration-test/custom-ca-roots/test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import unittest

import requests


class CustomCATests(unittest.TestCase):
def test_valid_self_signed(self):
self.assertEqual(requests.get("https://self.test").text, 'ok')
self.assertEqual(requests.get("https://self.test").text, "ok")

def test_invalid_self_signed(self):
with self.assertRaises(requests.exceptions.SSLError):
requests.get("https://fail.test")


if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()
47 changes: 37 additions & 10 deletions _integration-test/test_backup.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,52 @@
import subprocess
import os
import subprocess


def test_backup(setup_backup_restore_env_variables):
# Docker was giving me permissioning issues when trying to create this file and write to it even after giving read + write access
# to group and owner. Instead, try creating the empty file and then give everyone write access to the backup file
file_path = os.path.join(os.getcwd(), 'sentry', 'backup.json')
sentry_admin_sh = os.path.join(os.getcwd(), 'sentry-admin.sh')
open(file_path, 'a', encoding='utf8').close()
file_path = os.path.join(os.getcwd(), "sentry", "backup.json")
sentry_admin_sh = os.path.join(os.getcwd(), "sentry-admin.sh")
open(file_path, "a", encoding="utf8").close()
os.chmod(file_path, 0o666)
assert os.path.getsize(file_path) == 0
subprocess.run([sentry_admin_sh, "export", "global", "/sentry-admin/backup.json", "--no-prompt"], check=True)
subprocess.run(
[
sentry_admin_sh,
"export",
"global",
"/sentry-admin/backup.json",
"--no-prompt",
],
check=True,
)
assert os.path.getsize(file_path) > 0


def test_import(setup_backup_restore_env_variables):
# Bring postgres down and recreate the docker volume
subprocess.run(["docker", "compose", "--ansi", "never", "stop", "postgres"], check=True)
subprocess.run(["docker", "compose", "--ansi", "never", "rm", "-f", "-v", "postgres"], check=True)
subprocess.run(
["docker", "compose", "--ansi", "never", "stop", "postgres"], check=True
)
subprocess.run(
["docker", "compose", "--ansi", "never", "rm", "-f", "-v", "postgres"],
check=True,
)
subprocess.run(["docker", "volume", "rm", "sentry-postgres"], check=True)
subprocess.run(["docker", "volume", "create", "--name=sentry-postgres"], check=True)
subprocess.run(["docker", "compose", "--ansi", "never", "run", "web", "upgrade", "--noinput"], check=True)
subprocess.run(
["docker", "compose", "--ansi", "never", "run", "web", "upgrade", "--noinput"],
check=True,
)
subprocess.run(["docker", "compose", "--ansi", "never", "up", "-d"], check=True)
sentry_admin_sh = os.path.join(os.getcwd(), 'sentry-admin.sh')
subprocess.run([sentry_admin_sh, "import", "global", "/sentry-admin/backup.json", "--no-prompt"], check=True)
sentry_admin_sh = os.path.join(os.getcwd(), "sentry-admin.sh")
subprocess.run(
[
sentry_admin_sh,
"import",
"global",
"/sentry-admin/backup.json",
"--no-prompt",
],
check=True,
)
146 changes: 122 additions & 24 deletions _integration-test/test_run.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import subprocess
import datetime
import json
import os
import re
import shutil
import subprocess
import time
from functools import lru_cache
from bs4 import BeautifulSoup
from typing import Callable

import httpx
import pytest
import sentry_sdk
import time
import json
import re
from typing import Callable
from bs4 import BeautifulSoup
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID

SENTRY_CONFIG_PY = "sentry/sentry.conf.py"
SENTRY_TEST_HOST = os.getenv("SENTRY_TEST_HOST", "http:https://localhost:9000")
Expand Down Expand Up @@ -138,24 +146,114 @@ def test_cleanup_crons_running():


def test_custom_cas():
try:
subprocess.run(["./_integration-test/custom-ca-roots/setup.sh"], check=True)
subprocess.run(
[
"docker",
"compose",
"--ansi",
"never",
"run",
"--no-deps",
"web",
"python3",
"/etc/sentry/test-custom-ca-roots.py",
],
check=True,
# Set environment variable
os.environ["COMPOSE_FILE"] = (
"docker-compose.yml:_integration-test/custom-ca-roots/docker-compose.test.yml"
)

test_nginx_conf_path = "_integration-test/custom-ca-roots/nginx"
custom_certs_path = "certificates"

# Generate tightly constrained CA
ca_key = rsa.generate_private_key(
public_exponent=65537, key_size=2048, backend=default_backend()
)

ca_name = x509.Name(
[x509.NameAttribute(NameOID.COMMON_NAME, "TEST CA *DO NOT TRUST*")]
)

ca_cert = (
x509.CertificateBuilder()
.subject_name(ca_name)
.issuer_name(ca_name)
.public_key(ca_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.datetime.utcnow())
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
.add_extension(
x509.KeyUsage(
digital_signature=False,
key_encipherment=False,
content_commitment=False,
data_encipherment=False,
key_agreement=False,
key_cert_sign=True,
crl_sign=True,
encipher_only=False,
decipher_only=False,
),
critical=True,
)
.add_extension(
x509.NameConstraints([x509.DNSName("self.test")], None), critical=True
)
.sign(private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend())
)

ca_key_path = f"{test_nginx_conf_path}/ca.key"
ca_crt_path = f"{test_nginx_conf_path}/ca.crt"

with open(ca_key_path, "wb") as key_file:
key_file.write(
ca_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
)
finally:
subprocess.run(["./_integration-test/custom-ca-roots/teardown.sh"], check=True)

with open(ca_crt_path, "wb") as cert_file:
cert_file.write(ca_cert.public_bytes(serialization.Encoding.PEM))

# Create custom certs path and copy ca.crt
os.makedirs(custom_certs_path, exist_ok=True)
shutil.copyfile(ca_crt_path, f"{custom_certs_path}/test-custom-ca-roots.crt")
shutil.copyfile(
"_integration-test/custom-ca-roots/test.py", "sentry/test-custom-ca-roots.py"
)

subprocess.run(
["docker", "compose", "--ansi", "never", "up", "-d", "fixture-custom-ca-roots"],
check=True,
)
subprocess.run(
[
"docker",
"compose",
"--ansi",
"never",
"run",
"--no-deps",
"web",
"python3",
"/etc/sentry/test-custom-ca-roots.py",
],
check=True,
)
subprocess.run(
[
"docker",
"compose",
"--ansi",
"never",
"rm",
"-s",
"-f",
"-v",
"fixture-custom-ca-roots",
],
check=True,
)

# Remove files
os.remove(f"{custom_certs_path}/test-custom-ca-roots.crt")
os.remove("sentry/test-custom-ca-roots.py")

# Unset environment variable
if "COMPOSE_FILE" in os.environ:
del os.environ["COMPOSE_FILE"]


def test_receive_transaction_events(client_login):
Expand Down Expand Up @@ -235,7 +333,7 @@ def test_customizations():
"python",
"-c",
"import ldap",
]
],
]
for command in commands:
result = subprocess.run(command, check=False)
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
cryptography>=42.0.4
sentry-sdk>=1.39.2
pytest>=8.0.0
pytest-cov>=4.1.0
Expand Down

0 comments on commit f1f43eb

Please sign in to comment.