diff --git a/duniterpy/documents/constants.py b/duniterpy/documents/constants.py index 51d34b44ac74f44850f3839242f4993f5c386577..db303b27162e52200e28f87e21261a9bb8fa2980 100644 --- a/duniterpy/documents/constants.py +++ b/duniterpy/documents/constants.py @@ -10,3 +10,5 @@ block_uid_regex = "{block_id_regex}-{block_hash_regex}".format(block_id_regex=bl block_hash_regex=block_hash_regex) conditions_regex = "(&&|\|\|| |[()]|(SIG\({pubkey_regex}\)|(XHX\({hash_regex}\))))*"\ .format(pubkey_regex=pubkey_regex, hash_regex=hash_regex) +ipv4_regex = '(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' +ipv6_regex = '(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(?:(?:[0-9A-Fa-f]{1,4}:){,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){,6}[0-9A-Fa-f]{1,4})?::)' diff --git a/duniterpy/documents/peer.py b/duniterpy/documents/peer.py index 58264990c3dbcae18d2c17ee46516e84b8373567..da623ee3bb2d80f4e4f630b7010fe6cab056e0f5 100644 --- a/duniterpy/documents/peer.py +++ b/duniterpy/documents/peer.py @@ -4,7 +4,7 @@ from ..api.bma import ConnectionHandler from .document import Document, MalformedDocumentError from . import BlockUID from .. import MANAGED_API -from .constants import block_hash_regex, pubkey_regex +from .constants import block_hash_regex, pubkey_regex, ipv4_regex, ipv6_regex class Peer(Document): @@ -154,7 +154,8 @@ class UnknownEndpoint(Endpoint): class BMAEndpoint(Endpoint): - re_inline = re.compile('^BASIC_MERKLED_API(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ((?:[0-9.]{1,4}){4}))?(?: ((?:[0-9a-f:]{4,5}){4,8}))?(?: ([0-9]+))$') + re_inline = re.compile('^BASIC_MERKLED_API(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))?(?: ([0-9]+))$'.format(ipv4_regex=ipv4_regex, + ipv6_regex=ipv6_regex)) def __init__(self, server, ipv4, ipv6, port): self.server = server @@ -208,7 +209,8 @@ class BMAEndpoint(Endpoint): class SecuredBMAEndpoint(BMAEndpoint): - re_inline = re.compile('^BMAS(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ((?:[0-9.]{1,4}){4}))?(?: ((?:[0-9a-f:]{4,5}){4,8}))?(?: ([0-9]+))(?: ([/\w \.-]*)/?)?$') + re_inline = re.compile('^BMAS(?: ([a-z0-9-_.]*(?:.[a-zA-Z])))?(?: ({ipv4_regex}))?(?: ({ipv6_regex}))? ([0-9]+)(?: ([/\w \.-]*)/?)?$'.format(ipv4_regex=ipv4_regex, + ipv6_regex=ipv6_regex)) def __init__(self, server, ipv4, ipv6, port, path): super().__init__(server, ipv4, ipv6, port) @@ -218,7 +220,7 @@ class SecuredBMAEndpoint(BMAEndpoint): def from_inline(cls, inline): m = SecuredBMAEndpoint.re_inline.match(inline) if m is None: - raise MalformedDocumentError("BMAEndpoint") + raise MalformedDocumentError("BMAS") server = m.group(1) ipv4 = m.group(2) ipv6 = m.group(3) @@ -229,11 +231,8 @@ class SecuredBMAEndpoint(BMAEndpoint): return cls(server, ipv4, ipv6, port, path) def inline(self): - return "BMAS{DNS}{IPv4}{IPv6}{PORT}" \ - .format(DNS=(" {0}".format(self.server) if self.server else ""), - IPv4=(" {0}".format(self.ipv4) if self.ipv4 else ""), - IPv6=(" {0}".format(self.ipv6) if self.ipv6 else ""), - PORT=(" {0}".format(self.port) if self.port else "")) + inlined = [str(info) for info in (self.server, self.ipv4, self.ipv6, self.port, self.path) if info] + return "BMAS " + " ".join(inlined) def conn_handler(self, session=None, proxy=None): """ diff --git a/tests/documents/test_peer.py b/tests/documents/test_peer.py index f67f04b619028c44887c2de7335d13c6ae0c56df..94b914ff405284060bec2d1b9af814b5aed2097d 100644 --- a/tests/documents/test_peer.py +++ b/tests/documents/test_peer.py @@ -19,6 +19,16 @@ OTHER_PROTOCOL 88.77.66.55 9001 dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg== """ +test_weird_ipv6_peer = """Version: 10 +Type: Peer +Currency: g1 +PublicKey: 6fFt4zdvtNyVcfJn7Y41mKLmMDizyK3nVeNW3qdDXzpc +Block: 18198-000004AC710E04D8015ED6CA5D87D4B6620A7551233FFEE1B521FF756CE3B9CD +Endpoints: +BASIC_MERKLED_API duniter.aquilenet.fr 141.255.128.35 2a01:474::35 10901 +BMAS duniter.aquilenet.fr 443 +dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg== +""" class TestPeer(unittest.TestCase): def test_fromraw(self): @@ -68,3 +78,8 @@ class TestPeer(unittest.TestCase): self.assertEqual(from_rendered_peer.signatures[0], "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==") self.assertEqual(rawpeer, from_rendered_peer.signed_raw()) + + def test_incorrect(self): + peer = Peer.from_signed_raw(test_weird_ipv6_peer) + rendered_peer = peer.signed_raw() + from_rendered_peer = Peer.from_signed_raw(rendered_peer)