Skip to content

Commit

Permalink
Merge 4678b58 into 8973219
Browse files Browse the repository at this point in the history
  • Loading branch information
dichn committed Mar 7, 2022
2 parents 8973219 + 4678b58 commit b04c80e
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 15 deletions.
12 changes: 12 additions & 0 deletions exodus_lambda/functions/origin_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,25 @@ def handle_cookie_request(self, event):
self.logger.info("Handling cookie request: %s", uri)

signer = Signer(self.cookie_key, self.conf.get("key_id"))
policy_content = signer.cf_signer.build_policy(
resource="https://%s/content/*" % domain,
date_less_than=now + ttl,
).encode("utf-8")

policy_origin = signer.cf_signer.build_policy(
resource="https://%s/origin/*" % domain,
date_less_than=now + ttl,
).encode("utf-8")

cookies_content = signer.cookies_for_policy(
policy=policy_content,
append="; Secure; Path=/content/; Max-Age=%s"
% int(ttl.total_seconds()),
resource="https://%s/content/*" % domain,
date_less_than=now + ttl,
)
cookies_origin = signer.cookies_for_policy(
policy=policy_origin,
append="; Secure; Path=/origin/; Max-Age=%s"
% int(ttl.total_seconds()),
resource="https://%s/origin/*" % domain,
Expand Down
7 changes: 5 additions & 2 deletions exodus_lambda/functions/signer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import json

from botocore.signers import CloudFrontSigner
from cryptography.hazmat.backends import default_backend
Expand Down Expand Up @@ -30,8 +31,10 @@ def rsa_sign(self, message):
message, padding.PKCS1v15(), hashes.SHA1()
)

def cookies_for_policy(self, append, **kwargs):
policy = self.cf_signer.build_policy(**kwargs).encode("utf-8")
def cookies_for_policy(self, policy, append, **kwargs):
# policy = self.cf_signer.build_policy(**kwargs).encode("utf-8")
# if "resource" in kwargs and not kwargs.get("resource"):
# policy = remove_policy_resource(policy)
signature = self.cf_signer.rsa_signer(policy)

policy_b64 = cf_b64(policy).decode("utf-8")
Expand Down
1 change: 1 addition & 0 deletions test-requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ more-itertools
wcwidth
black
coveralls
cryptography
pylint
pytest-cov
mypy
Expand Down
78 changes: 78 additions & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,58 @@ certifi==2021.5.30 \
--hash=sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee \
--hash=sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8
# via requests
cffi==1.15.0 \
--hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \
--hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \
--hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \
--hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \
--hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \
--hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \
--hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \
--hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \
--hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \
--hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \
--hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \
--hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \
--hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \
--hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \
--hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \
--hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \
--hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \
--hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \
--hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \
--hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \
--hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \
--hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \
--hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \
--hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \
--hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \
--hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \
--hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \
--hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \
--hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \
--hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \
--hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \
--hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \
--hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \
--hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \
--hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \
--hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \
--hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \
--hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \
--hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \
--hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \
--hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \
--hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \
--hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \
--hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \
--hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \
--hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \
--hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \
--hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \
--hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \
--hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796
# via cryptography
charset-normalizer==2.0.7 \
--hash=sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0 \
--hash=sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b
Expand Down Expand Up @@ -92,6 +144,28 @@ coveralls==3.1.0 \
--hash=sha256:172fb79c5f61c6ede60554f2cac46deff6d64ee735991fb2124fb414e188bdb4 \
--hash=sha256:9b3236e086627340bf2c95f89f757d093cbed43d17179d3f4fb568c347e7d29a
# via -r test-requirements.in
cryptography==36.0.1 \
--hash=sha256:0a817b961b46894c5ca8a66b599c745b9a3d9f822725221f0e0fe49dc043a3a3 \
--hash=sha256:2d87cdcb378d3cfed944dac30596da1968f88fb96d7fc34fdae30a99054b2e31 \
--hash=sha256:30ee1eb3ebe1644d1c3f183d115a8c04e4e603ed6ce8e394ed39eea4a98469ac \
--hash=sha256:391432971a66cfaf94b21c24ab465a4cc3e8bf4a939c1ca5c3e3a6e0abebdbcf \
--hash=sha256:39bdf8e70eee6b1c7b289ec6e5d84d49a6bfa11f8b8646b5b3dfe41219153316 \
--hash=sha256:4caa4b893d8fad33cf1964d3e51842cd78ba87401ab1d2e44556826df849a8ca \
--hash=sha256:53e5c1dc3d7a953de055d77bef2ff607ceef7a2aac0353b5d630ab67f7423638 \
--hash=sha256:596f3cd67e1b950bc372c33f1a28a0692080625592ea6392987dba7f09f17a94 \
--hash=sha256:5d59a9d55027a8b88fd9fd2826c4392bd487d74bf628bb9d39beecc62a644c12 \
--hash=sha256:6c0c021f35b421ebf5976abf2daacc47e235f8b6082d3396a2fe3ccd537ab173 \
--hash=sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b \
--hash=sha256:74d6c7e80609c0f4c2434b97b80c7f8fdfaa072ca4baab7e239a15d6d70ed73a \
--hash=sha256:7be0eec337359c155df191d6ae00a5e8bbb63933883f4f5dffc439dac5348c3f \
--hash=sha256:94ae132f0e40fe48f310bba63f477f14a43116f05ddb69d6fa31e93f05848ae2 \
--hash=sha256:bb5829d027ff82aa872d76158919045a7c1e91fbf241aec32cb07956e9ebd3c9 \
--hash=sha256:ca238ceb7ba0bdf6ce88c1b74a87bffcee5afbfa1e41e173b1ceb095b39add46 \
--hash=sha256:ca28641954f767f9822c24e927ad894d45d5a1e501767599647259cbf030b903 \
--hash=sha256:e0344c14c9cb89e76eb6a060e67980c9e35b3f36691e15e1b7a9e58a0a6c6dc3 \
--hash=sha256:ebc15b1c22e55c4d5566e3ca4db8689470a0ca2babef8e3a9ee057a8b82ce4b1 \
--hash=sha256:ec63da4e7e4a5f924b90af42eddf20b698a70e58d86a72d943857c4c6045b3ee
# via -r test-requirements.in
docopt==0.6.2 \
--hash=sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491
# via coveralls
Expand Down Expand Up @@ -194,6 +268,10 @@ py==1.10.0 \
--hash=sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3 \
--hash=sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a
# via pytest
pycparser==2.21 \
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
# via cffi
pylint==2.9.3 \
--hash=sha256:23a1dc8b30459d78e9ff25942c61bb936108ccbe29dd9e71c01dc8274961709a \
--hash=sha256:5d46330e6b8886c31b5e3aba5ff48c10f4aa5e76cbf9002c6544306221e63fbc
Expand Down
Empty file added tests/integration/__init__.py
Empty file.
30 changes: 17 additions & 13 deletions tests/integration/test_exodus.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
import pytest
import requests

from ..test_utils.utils import generate_test_cookies

TEST_COOKIES = generate_test_cookies()


def test_exodus_basic(cdn_test_url):
url = (
cdn_test_url
+ "/content/aus/rhel/server/6/6.5/x86_64/os/Packages/c/cpio-2.10-12.el6_5.x86_64.rpm"
)

r = requests.get(url)
r = requests.get(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert "cache-control" not in r.headers
Expand All @@ -22,7 +26,7 @@ def test_header_not_exist_file(cdn_test_url):
cdn_test_url
+ "/content/aus/rhel/server/6/6.5/x86_64/os/Packages/c/cpio-2.10-12.el6_5.x86_64.rpm_not_exist" # noqa: E501
)
r = requests.get(url)
r = requests.get(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 404
assert "cache-control" not in r.headers
Expand All @@ -40,7 +44,7 @@ def test_header_not_exist_file(cdn_test_url):
@pytest.mark.parametrize("testdata_path", testdata_cache_control_path)
def test_header_cache_control(cdn_test_url, testdata_path):
url = cdn_test_url + testdata_path
r = requests.get(url)
r = requests.get(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert re.match("^max-age=[0-9]+$", r.headers["cache-control"])
Expand All @@ -52,7 +56,7 @@ def test_header_want_digest_GET(cdn_test_url):
cdn_test_url
+ "/content/dist/rhel/server/7/7.2/x86_64/rhev-mgmt-agent/3/os/repodata/repomd.xml"
)
r = requests.get(url, headers=headers)
r = requests.get(url, headers=headers, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert (
Expand All @@ -67,7 +71,7 @@ def test_header_want_digest_HEAD(cdn_test_url):
cdn_test_url
+ "/content/dist/rhel/server/7/7.2/x86_64/rhev-mgmt-agent/3/os/repodata/repomd.xml"
)
r = requests.head(url, headers=headers)
r = requests.head(url, headers=headers, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert (
Expand Down Expand Up @@ -99,7 +103,7 @@ def assert_content_type(url, content_type):
@pytest.mark.parametrize("testdata_path", testdata_content_type_path)
def test_content_type_header_GET(cdn_test_url, testdata_path):
url = cdn_test_url + testdata_path
r = requests.get(url)
r = requests.get(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert_content_type(url, r.headers["Content-Type"])
Expand All @@ -108,7 +112,7 @@ def test_content_type_header_GET(cdn_test_url, testdata_path):
@pytest.mark.parametrize("testdata_path", testdata_content_type_path)
def test_content_type_header_HEAD(cdn_test_url, testdata_path):
url = cdn_test_url + testdata_path
r = requests.head(url)
r = requests.head(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert_content_type(url, r.headers["Content-Type"])
Expand All @@ -127,7 +131,7 @@ def test_content_type_header_HEAD(cdn_test_url, testdata_path):
def test_origin_path_alias(cdn_test_url, testdata_path):
headers = {"want-digest": "id-sha-256"}
url = cdn_test_url + testdata_path
r = requests.head(url, headers=headers)
r = requests.head(url, headers=headers, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert (
Expand All @@ -146,7 +150,7 @@ def test_origin_path_alias(cdn_test_url, testdata_path):
def test_rhui_path_alias_aus(cdn_test_url, testdata_path):
headers = {"want-digest": "id-sha-256"}
url = cdn_test_url + testdata_path
r = requests.head(url, headers=headers)
r = requests.head(url, headers=headers, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert (
Expand All @@ -165,7 +169,7 @@ def test_rhui_path_alias_aus(cdn_test_url, testdata_path):
def test_rhui_path_alias_rhel8(cdn_test_url, testdata_path):
headers = {"want-digest": "id-sha-256"}
url = cdn_test_url + testdata_path
r = requests.head(url, headers=headers)
r = requests.head(url, headers=headers, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert (
Expand All @@ -184,7 +188,7 @@ def test_rhui_path_alias_rhel8(cdn_test_url, testdata_path):
def test_releasever_alias_rhel6(cdn_test_url, testdata_path):
headers = {"want-digest": "id-sha-256"}
url = cdn_test_url + testdata_path
r = requests.head(url, headers=headers)
r = requests.head(url, headers=headers, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert (
Expand All @@ -201,7 +205,7 @@ def test_releasever_alias_rhel6(cdn_test_url, testdata_path):
@pytest.mark.parametrize("testdata_path", testdata_no_content_type)
def test_no_content_type(cdn_test_url, testdata_path):
url = cdn_test_url + testdata_path
r = requests.get(url)
r = requests.get(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 200
assert r.headers["Content-Type"] == "application/octet-stream"
Expand All @@ -215,6 +219,6 @@ def test_no_content_type(cdn_test_url, testdata_path):
@pytest.mark.parametrize("testdata_path", testdata_absent_item)
def test_absent_item(cdn_test_url, testdata_path):
url = cdn_test_url + testdata_path
r = requests.get(url)
r = requests.get(url, cookies=TEST_COOKIES)
print(json.dumps(dict(r.headers), indent=2))
assert r.status_code == 404
40 changes: 40 additions & 0 deletions tests/test_utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import base64
import json
import os
from collections import OrderedDict
from datetime import datetime, timedelta, timezone

from botocore.utils import datetime2timestamp
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

from exodus_lambda.functions.signer import Signer

CONF_FILE = os.environ.get("EXODUS_LAMBDA_CONF_FILE")

Expand Down Expand Up @@ -50,3 +60,33 @@ def mock_definitions():
exodus_config = json.load(f)

return exodus_config


def remove_policy_resource(policy):
policy_dict = json.loads(policy.decode("utf-8"))
policy_dict["Statement"][0].pop("Resource")
return json.dumps(policy_dict).encode("utf-8")


def generate_test_cookies():
# Env var for using signed cookies
key = os.environ.get("EXODUS_CDN_PRIVATE_KEY")
key_id = os.environ.get("EXODUS_CDN_KEY_ID")

if not key or not key_id:
# envvar absent, requests will not be signed
return {}

# The cookies expire in 1 hour
expiration = datetime.now(timezone.utc) + timedelta(seconds=3600)
signer = Signer(key, key_id)
policy = signer.cf_signer.build_policy(
resource="", date_less_than=expiration
).encode("utf-8")

# Omit the Resource parameter for accessing all test content
policy = remove_policy_resource(policy)
cookies = signer.cookies_for_policy(
policy=policy, append="", date_less_than=expiration
)
return {item.split("=")[0]: item.split("=")[1] for item in cookies}

0 comments on commit b04c80e

Please sign in to comment.