Skip to content

Commit 39f8915

Browse files
authored
Add WAF rate bypass header to GC Articles requests (#2690)
* feat: add WAF rate bypass header to GC Articles requests * add tests, use env module in config
1 parent b8a174e commit 39f8915

3 files changed

Lines changed: 42 additions & 3 deletions

File tree

app/articles/api.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,14 @@ def _get_headers(auth_required=False):
111111
base_endpoint = current_app.config["GC_ARTICLES_API"]
112112
username = current_app.config["GC_ARTICLES_API_AUTH_USERNAME"]
113113
password = current_app.config["GC_ARTICLES_API_AUTH_PASSWORD"]
114+
waf_rate_bypass_secret = current_app.config["GC_ARTICLES_WAF_RATE_BYPASS_SECRET"]
115+
116+
headers = {}
117+
if waf_rate_bypass_secret:
118+
headers["waf-rate-bypass"] = waf_rate_bypass_secret
114119

115120
if auth_required:
116121
token = authenticate(username, password, base_endpoint)
117-
return {"Authorization": "Bearer {}".format(token)}
118-
return {}
122+
headers["Authorization"] = "Bearer {}".format(token)
123+
124+
return headers

app/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class Config(object):
9999
GC_ARTICLES_API = os.environ.get("GC_ARTICLES_API", "articles.alpha.canada.ca/notification-gc-notify")
100100
GC_ARTICLES_API_AUTH_PASSWORD = os.environ.get("GC_ARTICLES_API_AUTH_PASSWORD")
101101
GC_ARTICLES_API_AUTH_USERNAME = os.environ.get("GC_ARTICLES_API_AUTH_USERNAME")
102+
GC_ARTICLES_WAF_RATE_BYPASS_SECRET = env.str("GC_ARTICLES_WAF_RATE_BYPASS_SECRET", "my-secret-key")
102103
GC_ORGANISATIONS_BUCKET_NAME = os.environ.get("GC_ORGANISATIONS_BUCKET_NAME")
103104
GC_ORGANISATIONS_FILENAME = os.getenv("GC_ORGANISATIONS_FILENAME", "all.json")
104105
GOOGLE_ANALYTICS_ID = os.getenv("GOOGLE_ANALYTICS_ID", "G-R04KFLQCVQ")
@@ -175,6 +176,7 @@ def get_sensitive_config(cls) -> list[str]:
175176
"DEBUG_KEY",
176177
"GC_ARTICLES_API_AUTH_PASSWORD",
177178
"GC_ARTICLES_API_AUTH_USERNAME",
179+
"GC_ARTICLES_WAF_RATE_BYPASS_SECRET",
178180
"ROUTE_SECRET_KEY_1",
179181
"ROUTE_SECRET_KEY_2",
180182
"SECRET_KEY",

tests/app/articles/test_request_content.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import requests_mock
33
from werkzeug.exceptions import Forbidden
44

5-
from app.articles.api import get_content
5+
from app.articles.api import _get_headers, get_content
66

77
gc_articles_api = "articles.alpha.canada.ca/notification-gc-notify"
88
notify_url = f"https://{gc_articles_api}/wp-json/pages"
@@ -54,3 +54,34 @@ def test_get_content_403(app_, mocker, capsys):
5454
get_content("pages", {"slug": "mypage", "lang": "en"})
5555

5656
assert "403 Forbidden" in str(exception.value)
57+
58+
59+
class TestGetHeaders:
60+
def test_waf_rate_bypass_header_included_when_secret_set(self, app_, mocker):
61+
with app_.test_request_context():
62+
mocker.patch.dict(
63+
"app.current_app.config",
64+
values={"GC_ARTICLES_WAF_RATE_BYPASS_SECRET": "some-secret"},
65+
)
66+
headers = _get_headers()
67+
assert headers["waf-rate-bypass"] == "some-secret"
68+
69+
def test_waf_rate_bypass_header_not_included_when_secret_not_set(self, app_, mocker):
70+
with app_.test_request_context():
71+
mocker.patch.dict(
72+
"app.current_app.config",
73+
values={"GC_ARTICLES_WAF_RATE_BYPASS_SECRET": None},
74+
)
75+
headers = _get_headers()
76+
assert "waf-rate-bypass" not in headers
77+
78+
def test_waf_rate_bypass_header_included_alongside_auth_header(self, app_, mocker):
79+
mocker.patch("app.articles.api.authenticate", return_value="some-token")
80+
with app_.test_request_context():
81+
mocker.patch.dict(
82+
"app.current_app.config",
83+
values={"GC_ARTICLES_WAF_RATE_BYPASS_SECRET": "some-secret"},
84+
)
85+
headers = _get_headers(auth_required=True)
86+
assert headers["waf-rate-bypass"] == "some-secret"
87+
assert headers["Authorization"] == "Bearer some-token"

0 commit comments

Comments
 (0)