Skip to content

Commit

Permalink
Validate redirect url enhancements (#1806)
Browse files Browse the repository at this point in the history
  • Loading branch information
ochiu authored Oct 31, 2024
1 parent ea0282b commit 2ae627c
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
16 changes: 14 additions & 2 deletions pay-api/src/pay_api/utils/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from datetime import datetime, timedelta, timezone
from decimal import Decimal
from typing import Dict
from urllib.parse import parse_qsl
from urllib.parse import parse_qsl, urlparse

import pytz
from dpath import get as dpath_get
Expand Down Expand Up @@ -55,15 +55,27 @@ def options(self, *args, **kwargs): # pylint: disable=unused-argument
return wrapper


def normalize_url(url: str) -> str:
"""Normalize the URL by removing 'www.' if present and strip trailing slash."""
parsed = urlparse(url)
netloc = parsed.netloc
if netloc.startswith("www."):
netloc = netloc[4:]
path = parsed.path.rstrip("/")
return f"{parsed.scheme}://{netloc}{path}"


def is_valid_redirect_url(url: str) -> bool:
"""Validate if the url is valid based on the VALID Redirect Url."""
disable_redirect_validation: bool = current_app.config.get("DISABLE_VALID_REDIRECT_URLS")
if disable_redirect_validation:
return True
valid_urls: list = current_app.config.get("VALID_REDIRECT_URLS")
is_valid = False
url = normalize_url(url)
for valid_url in valid_urls:
is_valid = url.startswith(valid_url[:-1]) if valid_url.endswith("*") else valid_url == url
valid_url = normalize_url(valid_url)
is_valid = url.startswith(normalize_url(valid_url[:-1])) if valid_url.endswith("*") else valid_url == url
if is_valid:
break
return is_valid
Expand Down
2 changes: 1 addition & 1 deletion pay-api/src/pay_api/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
Development release segment: .devN
"""

__version__ = "1.22.6" # pylint: disable=invalid-name
__version__ = "1.22.7" # pylint: disable=invalid-name
42 changes: 41 additions & 1 deletion pay-api/tests/unit/utils/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
"""
from datetime import datetime

import pytest
from flask import current_app
from holidays.constants import GOVERNMENT, OPTIONAL, PUBLIC
from holidays.countries import Canada

from pay_api.schemas import utils as schema_utils
from pay_api.utils.util import get_nearest_business_day
from pay_api.utils.util import get_nearest_business_day, is_valid_redirect_url


def test_next_business_day(session):
Expand Down Expand Up @@ -117,3 +119,41 @@ def test_validate_schema():
"""Assert get_schema works."""
schema_utils.get_schema("transaction_request.json")
assert True


@pytest.mark.parametrize(
"redirect_url, valid_urls, expected_result",
[
("https://bcregistry.ca", ["https://www.bcregistry.ca/*"], True),
("https://bcregistry.ca", ["https://www.bcregistry.ca/"], True),
("https://bcregistry.ca", ["https://www.bcregistry.ca"], True),
("https://bcregistry.ca/", ["https://www.bcregistry.ca/*"], True),
("https://bcregistry.ca/", ["https://www.bcregistry.ca/"], True),
("https://bcregistry.ca/", ["https://www.bcregistry.ca"], True),
("https://www.bcregistry.ca", ["https://www.bcregistry.ca/*"], True),
("https://www.bcregistry.ca", ["https://www.bcregistry.ca/"], True),
("https://www.bcregistry.ca", ["https://www.bcregistry.ca"], True),
("https://www.bcregistry.ca/", ["https://www.bcregistry.ca/*"], True),
("https://www.bcregistry.ca/", ["https://www.bcregistry.ca/"], True),
("https://www.bcregistry.ca/", ["https://www.bcregistry.ca"], True),
("https://www.bcregistry.ca", ["https://bcregistry.ca/*"], True),
("https://www.bcregistry.ca", ["https://bcregistry.ca/"], True),
("https://www.bcregistry.ca", ["https://bcregistry.ca"], True),
("https://www.bcregistry.ca/", ["https://bcregistry.ca/*"], True),
("https://www.bcregistry.ca/", ["https://bcregistry.ca/"], True),
("https://www.bcregistry.ca/", ["https://bcregistry.ca"], True),
("https://www.bcregistry.ca/abc", ["https://bcregistry.ca/*"], True),
("https://www.bcregistry.ca/abc/123", ["https://bcregistry.ca/*"], True),
("https://www.bcregistry.com/abc", ["https://bcregistry.ca"], False),
("https://www.bcregistry.com/abc/123", ["https://bcregistry.ca"], False),
("https://www.bcreg.ca/", ["https://bcregistry.ca"], False),
("https://bcreg.ca/", ["https://bcregistry.ca"], False),
("https://bcreg.ca/", ["https://bcregistry.ca", "https://www.bcreg.ca", "https://test.com"], True),
],
)
def test_validate_redirect_url(app, redirect_url, valid_urls, expected_result):
"""Test validate redirect url."""
app.config["DISABLE_VALID_REDIRECT_URLS"] = False
app.config["VALID_REDIRECT_URLS"] = valid_urls
with app.app_context():
assert is_valid_redirect_url(redirect_url) == expected_result

0 comments on commit 2ae627c

Please sign in to comment.