mirror of https://github.com/eyhc1/rendercv.git
Disallow _ in domain names
This commit is contained in:
parent
bb65cade3a
commit
f0d3e705d8
|
@ -1057,8 +1057,24 @@ class Connection(BaseModel):
|
||||||
value: str
|
value: str
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def MastodonUname2Url(id: str) -> Optional[HttpUrl]:
|
def MastodonUname2Url(address: str) -> Optional[HttpUrl]:
|
||||||
"""From a Mastodon id "user@domain.example" returns profile url."""
|
"""returns profile url from a mastodon user address.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
address (str): A Mastodon user address. E.g., "user@social.example"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A pydantic HttpUrl object with the https URL for the user profile
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
url = MastodonUname2Url("user@social.example")
|
||||||
|
assert(url == HttpUrl(http://social.example/@user))
|
||||||
|
```
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
ValueError if the address is malformed.
|
||||||
|
"""
|
||||||
|
|
||||||
# The closest thing to a formal spec of Mastodon usernames
|
# The closest thing to a formal spec of Mastodon usernames
|
||||||
# where these regular expressions from a (reference?)
|
# where these regular expressions from a (reference?)
|
||||||
|
@ -1068,19 +1084,23 @@ class Connection(BaseModel):
|
||||||
#
|
#
|
||||||
# USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
|
# USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
|
||||||
# SERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
|
# SERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
|
||||||
# MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}i
|
#
|
||||||
# URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
|
# Note that the SERNAME expersion would allow underscores in DNS
|
||||||
|
# hostname labels. That would lead to invalid hostnames.
|
||||||
|
#
|
||||||
|
# I consider that a bug and will not be carrying that over here.
|
||||||
|
# (It is possible that pydantic would catch the error)
|
||||||
|
|
||||||
pattern = re.compile(r"""
|
pattern = re.compile(r"""
|
||||||
^\s* # ignore leading spaces
|
^\s* # ignore leading spaces
|
||||||
@? # Optional @ prefix
|
@? # Optional @ prefix
|
||||||
(?P<uname>[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?) # username part
|
(?P<uname>[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?) # username part
|
||||||
@ # separator
|
@ # separator
|
||||||
(?P<domain>[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?) # domain part
|
(?P<domain>[a-z0-9]+([a-z0-9.-]+[a-z0-9]+)?) # domain part
|
||||||
\s*$ # ignore trailing whitespace
|
\s*$ # ignore trailing whitespace
|
||||||
""", re.VERBOSE | re.IGNORECASE)
|
""", re.VERBOSE | re.IGNORECASE)
|
||||||
|
|
||||||
m = pattern.match(id)
|
m = pattern.match(address)
|
||||||
if m is None:
|
if m is None:
|
||||||
raise ValueError("Invalid mastodon address")
|
raise ValueError("Invalid mastodon address")
|
||||||
uname = m.group("uname")
|
uname = m.group("uname")
|
||||||
|
|
|
@ -862,14 +862,14 @@ class TestDataModel(unittest.TestCase):
|
||||||
data_model.read_input_file("nonexistent.json")
|
data_model.read_input_file("nonexistent.json")
|
||||||
|
|
||||||
def test_mastodon_parsing(self):
|
def test_mastodon_parsing(self):
|
||||||
mastodon_name = 'jpgoldberg@ioc.exchange'
|
mastodon_name = 'a_tooter@example.exchange'
|
||||||
expected = HttpUrl("https://ioc.exchange/@jpgoldberg")
|
expected = HttpUrl("https://example.exchange/@a_tooter")
|
||||||
result = data_model.Connection.MastodonUname2Url(mastodon_name)
|
result = data_model.Connection.MastodonUname2Url(mastodon_name)
|
||||||
with self.subTest("Without '@' prefix"):
|
with self.subTest("Without '@' prefix"):
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
mastodon_name = '@jpgoldberg@ioc.exchange'
|
mastodon_name = '@a_tooter@example.exchange'
|
||||||
expected = HttpUrl("https://ioc.exchange/@jpgoldberg")
|
expected = HttpUrl("https://example.exchange/@a_tooter")
|
||||||
result = data_model.Connection.MastodonUname2Url(mastodon_name)
|
result = data_model.Connection.MastodonUname2Url(mastodon_name)
|
||||||
with self.subTest("With '@' prefix"):
|
with self.subTest("With '@' prefix"):
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
@ -879,5 +879,17 @@ class TestDataModel(unittest.TestCase):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
data_model.Connection.MastodonUname2Url(mastodon_name)
|
data_model.Connection.MastodonUname2Url(mastodon_name)
|
||||||
|
|
||||||
|
mastodon_name = '@not_enough_at_symbols'
|
||||||
|
with self.subTest("Missing '@' separator"):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
data_model.Connection.MastodonUname2Url(mastodon_name)
|
||||||
|
|
||||||
|
mastodon_name = 'user@bad_domain.example'
|
||||||
|
with self.subTest("Underscore in domain portion"):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
data_model.Connection.MastodonUname2Url(mastodon_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue