Skip to content

Commit

Permalink
Add support for Heroku Review Apps
Browse files Browse the repository at this point in the history
Also fix failing tests.
  • Loading branch information
zupo authored and dz0ny committed Nov 7, 2024
1 parent 28f96ba commit 783e8e9
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 13 deletions.
5 changes: 0 additions & 5 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,3 @@ jobs:

- name: Test
run: poetry run make unit

- name: Upload to BlueRacer
run: bash <(curl -s https://app.blueracer.io/upload)
env:
BLUERACER_TOKEN: ${{ secrets.BLUERACER_TOKEN }}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ ifeq ($(full_suite),"false")
endif
full_suite_args = ""
ifeq ($(full_suite),"true")
full_suite_args = --junitxml junit.xml --durations 10 --cov=pyramid_cloudflare_access --cov-branch --cov-report html --cov-report xml:cov.xml --cov-report term-missing --cov-fail-under=100
full_suite_args = --cov=pyramid_cloudflare_access --cov-branch --cov-report html --cov-report xml:cov.xml --cov-report term-missing --cov-fail-under=100
endif

.PHONY: unit
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Compatibility
pyramid_cloudflare_access runs with pyramid>=1.7 and python>=3.6.
Other versions might also work.

Heroku Review Apps deployed on `*.herokuapp.com` subdomains automatically skip the cloudflare access check as their domains are dynamic and as such can't be configured in Cloudflare dashboard in advance.

Usage
-----
Expand Down
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,3 @@ black = "*"
autoflake = "*"
"zope.testing" = "*"
pytest-freezegun = "*"

[tool.pytest.ini_options]
junit_duration_report = "call"
4 changes: 4 additions & 0 deletions pyramid_cloudflare_access/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def authenticated_request(self, request: Request) -> bool:

def __call__(self, request: Request):

# Support for Heroku Review apps
if "herokuapp.com" in request.headers.get("Host", ""):
return self.handler(request)

if not self.authenticated_request(request):
raise exc.HTTPForbidden()

Expand Down
28 changes: 24 additions & 4 deletions pyramid_cloudflare_access/tests/test_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
sample_audience = "https://expenses-api"


@pytest.mark.freeze_time("2017-05-21")
@pytest.mark.freeze_time("2019-10-25 12:36:00")
def test_happy_path(mocker) -> None:
"""Test that JWT token is parsed and authorized."""

Expand All @@ -53,7 +53,7 @@ def test_happy_path(mocker) -> None:
request.cookies = {"CF_Authorization": sample_token}
request.registry.settings = {
"pyramid_cloudflare_access.policy_audience": sample_audience,
"pyramid_cloudflare_access.team": "auth0",
"pyramid_cloudflare_access.team": "https://foo.cloudflareaccess.com",
}

CloudflareAccess(tween_handler, request.registry)(request)
Expand All @@ -71,7 +71,7 @@ def test_missing_cookie(mocker) -> None:
request = testing.DummyRequest()
request.registry.settings = {
"pyramid_cloudflare_access.policy_audience": sample_audience,
"pyramid_cloudflare_access.team": "auth0",
"pyramid_cloudflare_access.team": "https://foo.cloudflareaccess.com",
}
with pytest.raises(HTTPBadRequest):
CloudflareAccess(tween_handler, request.registry)(request)
Expand All @@ -89,7 +89,27 @@ def test_auth_failed(mocker) -> None:
request.cookies = {"CF_Authorization": sample_token}
request.registry.settings = {
"pyramid_cloudflare_access.policy_audience": sample_audience,
"pyramid_cloudflare_access.team": "auth0",
"pyramid_cloudflare_access.team": "https://foo.cloudflareaccess.com",
}
with pytest.raises(HTTPForbidden):
CloudflareAccess(tween_handler, request.registry)(request)

def test_herokuapp(mocker) -> None:
"""Test that Cloudflare Access is skipped for Heroku-hosted apps.
This is to support Review Apps that have dynamic *.herokuapp.com hostname,
that cannot be configured as a domain for Cloudflare Access application
in Cloudflare dashboard.
"""
tween_handler = mocker.Mock()

request = testing.DummyRequest()
request.cookies = {}
request.registry.settings = {
"pyramid_cloudflare_access.policy_audience": sample_audience,
"pyramid_cloudflare_access.team": "https://foo.cloudflareaccess.com",
}
request.headers['Host'] = "foo.herokuapp.com"

CloudflareAccess(tween_handler, request.registry)(request)
tween_handler.assert_called_with(request)

0 comments on commit 783e8e9

Please sign in to comment.