Skip to content

Commit

Permalink
Merge "Detect range blocks with Page.is_blocked()"
Browse files Browse the repository at this point in the history
  • Loading branch information
jenkins-bot authored and Gerrit Code Review committed Jan 21, 2024
2 parents dd453a2 + 387edfc commit 58c89ba
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 2 deletions.
8 changes: 6 additions & 2 deletions pywikibot/page/_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from pywikibot.page._links import Link
from pywikibot.page._page import Page
from pywikibot.page._revision import Revision
from pywikibot.tools import deprecated, is_ip_address
from pywikibot.tools import deprecated, is_ip_address, is_ip_network


__all__ = ('User', )
Expand Down Expand Up @@ -85,6 +85,10 @@ def isAnonymous(self) -> bool: # noqa: N802
"""Determine if the user is editing as an IP address."""
return is_ip_address(self.username)

def is_CIDR(self) -> bool: # noqa: N802
"""Determine if the input refers to a range of IP addresses."""
return is_ip_network(self.username)

def getprops(self, force: bool = False) -> dict:
"""
Return a properties about the user.
Expand All @@ -95,7 +99,7 @@ def getprops(self, force: bool = False) -> dict:
del self._userprops
if not hasattr(self, '_userprops'):
self._userprops = list(self.site.users([self.username, ]))[0]
if self.isAnonymous():
if self.isAnonymous() or self.is_CIDR():
r = list(self.site.blocks(iprange=self.username, total=1))
if r:
self._userprops['blockedby'] = r[0]['by']
Expand Down
15 changes: 15 additions & 0 deletions pywikibot/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
'PYTHON_VERSION',
'as_filename',
'is_ip_address',
'is_ip_network',
'has_module',
'classproperty',
'suppress_warnings',
Expand Down Expand Up @@ -112,6 +113,20 @@ def is_ip_address(value: str) -> bool:
return False


def is_ip_network(value: str) -> bool:
"""Check if a value is a valid range of IPv4 or IPv6 addresses.
.. versionadded:: 9.0
:param value: value to check
"""
with suppress(ValueError):
ipaddress.ip_network(value)
return True

return False


def has_module(module: str, version: str | None = None) -> bool:
"""Check if a module can be imported.
Expand Down
76 changes: 76 additions & 0 deletions tests/tools_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
classproperty,
has_module,
is_ip_address,
is_ip_network,
suppress_warnings,
)
from pywikibot.tools.itertools import (
Expand Down Expand Up @@ -839,6 +840,81 @@ def test_invalid_ipv6_addresses(self):
self.assertFalse(is_ip_address(address))


class TestIsIpNetwork(TestCase):

"""Unit test class for is_ip_network."""

net = False

def test_valid_ipv4_ranges(self):
"""Check with valid IPv4 address ranges."""
valid_ranges = (
'0.0.0.0/32',
'1.2.3.4/32',
'1.2.3.0/24',
'192.168.0.0/16',
'192.168.0.0/15',
'255.0.0.0/8',
'0.0.0.0/1'
)

for ip_range in valid_ranges:
with self.subTest(ip_network=ip_range):
self.assertTrue(is_ip_network(ip_range))

def test_invalid_ipv4_ranges(self):
"""Check with invalid IPv4 address ranges."""
invalid_ranges = (
None,
'',
'0.0.0',
'1.2.3.256',
'1.2.3.-1',
'0.0.0.a',
'a.b.c.d',
'1.2.3.4/24',
'192.168.0.0/8',
'192.168.1.0/15'
)

for ip_range in invalid_ranges:
with self.subTest(ip_network=ip_range):
self.assertFalse(is_ip_network(ip_range))

def test_valid_ipv6_ranges(self):
"""Check with valid IPv6 address ranges."""
valid_ranges = (
'fe80:0000:0000:0000:0202:b3ff:fe1e:8329/128',
'fe80:0:0:0:202:b3ff:fe1e:8329/128',
'::ffff:5.9.158.75/128',
'2001:0db8:0000:0000:0000:0000:0000:0000/32',
'2001:0db8::/32',
'::/64',
'::/1',
)

for ip_range in valid_ranges:
with self.subTest(ip_network=ip_range):
self.assertTrue(is_ip_network(ip_range))

def test_invalid_ipv6_addresses(self):
"""Check with invalid IPv6 addresses."""
invalid_ranges = (
None,
'/32',
':/32',
':::/32',
'2001:db8::aaaa::1/128',
'fe80:0000:0000:0000:0202:b3ff:fe1e: 8329/128',
'fe80:0000:0000:0000:0202:b3ff:fe1e:829g/128',
'2001:0db8::/16'
)

for ip_range in invalid_ranges:
with self.subTest(ip_network=ip_range):
self.assertFalse(is_ip_network(ip_range))


class TestHasModule(TestCase):

"""Unit test class for has_module."""
Expand Down

0 comments on commit 58c89ba

Please sign in to comment.