2022-05-11 14:50:37 +02:00
|
|
|
from typing import List, Optional
|
2022-03-14 09:33:31 +01:00
|
|
|
from urllib.parse import parse_qs
|
2022-03-29 17:53:00 +02:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
2022-02-16 09:38:55 +01:00
|
|
|
from app.config import ALLOWED_REDIRECT_DOMAINS
|
2022-12-14 11:50:36 +01:00
|
|
|
from app.utils import random_string, random_words, sanitize_next_url, canonicalize_email
|
2019-07-03 22:13:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_random_words():
|
|
|
|
s = random_words()
|
2023-03-13 19:55:16 +01:00
|
|
|
assert s.find("_") > 0
|
|
|
|
assert s.count("_") == 1
|
|
|
|
assert len(s) > 3
|
|
|
|
s = random_words(2, 3)
|
2023-04-04 08:46:29 +02:00
|
|
|
assert s.count("_") == 1
|
2023-03-13 19:55:16 +01:00
|
|
|
assert s[-1] in (str(i) for i in range(10))
|
2019-07-03 22:13:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_random_string():
|
|
|
|
s = random_string()
|
|
|
|
assert len(s) > 0
|
2022-02-15 15:16:31 +01:00
|
|
|
|
|
|
|
|
2022-03-29 17:53:00 +02:00
|
|
|
def generate_sanitize_url_cases() -> List:
|
2022-02-15 15:16:31 +01:00
|
|
|
cases = [
|
2022-03-29 17:53:00 +02:00
|
|
|
[None, None],
|
|
|
|
["", None],
|
|
|
|
["http://badhttp.com", None],
|
|
|
|
["https://badhttps.com", None],
|
|
|
|
["/", "/"],
|
|
|
|
["/auth", "/auth"],
|
|
|
|
["/some/path", "/some/path"],
|
|
|
|
["//somewhere.net", None],
|
2022-06-16 09:55:08 +02:00
|
|
|
["//\\\\evil.com", None],
|
2022-02-15 15:16:31 +01:00
|
|
|
]
|
2022-02-16 09:38:55 +01:00
|
|
|
for domain in ALLOWED_REDIRECT_DOMAINS:
|
2022-03-29 17:53:00 +02:00
|
|
|
cases.append([f"http://{domain}", f"http://{domain}"])
|
|
|
|
cases.append([f"https://{domain}", f"https://{domain}"])
|
|
|
|
cases.append([f"https://{domain}/sub", f"https://{domain}/sub"])
|
|
|
|
cases.append([domain, None])
|
|
|
|
cases.append([f"//{domain}", f"//{domain}"])
|
2022-05-11 14:50:37 +02:00
|
|
|
cases.append([f"https://google.com\\@{domain}/haha", None])
|
2022-03-29 17:53:00 +02:00
|
|
|
return cases
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("url,expected", generate_sanitize_url_cases())
|
2022-05-11 14:50:37 +02:00
|
|
|
def test_sanitize_url(url: str, expected: Optional[str]):
|
2022-03-29 17:53:00 +02:00
|
|
|
sanitized = sanitize_next_url(url)
|
|
|
|
assert expected == sanitized
|
2022-03-14 09:33:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_parse_querystring():
|
|
|
|
cases = [
|
|
|
|
{"input": "", "expected": {}},
|
|
|
|
{"input": "a=b", "expected": {"a": ["b"]}},
|
|
|
|
{"input": "a=b&c=d", "expected": {"a": ["b"], "c": ["d"]}},
|
|
|
|
{"input": "a=b&a=c", "expected": {"a": ["b", "c"]}},
|
|
|
|
]
|
|
|
|
|
|
|
|
for case in cases:
|
|
|
|
expected = case["expected"]
|
|
|
|
res = parse_qs(case["input"])
|
|
|
|
assert len(res) == len(expected)
|
|
|
|
for k, v in expected.items():
|
|
|
|
assert res[k] == v
|
2022-12-14 11:50:36 +01:00
|
|
|
|
|
|
|
|
|
|
|
def canonicalize_email_cases():
|
|
|
|
for domain in ("gmail.com", "protonmail.com", "proton.me", "pm.me"):
|
|
|
|
yield (f"a@{domain}", f"a@{domain}")
|
|
|
|
yield (f"a.b@{domain}", f"ab@{domain}")
|
|
|
|
yield (f"a.b+c@{domain}", f"ab@{domain}")
|
2023-03-13 13:01:00 +01:00
|
|
|
yield ("a.b+c@other.com", "a.b+c@other.com")
|
2022-12-14 11:50:36 +01:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("dirty,clean", canonicalize_email_cases())
|
|
|
|
def test_canonicalize_email(dirty: str, clean: str):
|
|
|
|
assert canonicalize_email(dirty) == clean
|