Skip to content

Commit fde52b0

Browse files
committed
[docs] Added docs
Signed-off-by: DragnEmperor <[email protected]>
1 parent 5e46f06 commit fde52b0

File tree

7 files changed

+110
-10
lines changed

7 files changed

+110
-10
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ the OpenWISP architecture.
4949
user/openvpn.rst
5050
user/subnet-division-rules.rst
5151
user/whois.rst
52+
user/approximate-location.rst
5253
user/rest-api.rst
5354
user/settings.rst
5455

docs/user/approximate-location.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Approximate Location
2+
====================
3+
4+
.. important::
5+
6+
The **Approximate Location** feature is **disabled by default**.
7+
8+
Before enabling it, the :doc:`WHOIS Lookup feature <whois>` must be
9+
enabled and then set
10+
:ref:`OPENWISP_CONTROLLER_APPROXIMATE_LOCATION_ENABLED` to ``True``
11+
12+
.. contents:: **Table of contents**:
13+
:depth: 1
14+
:local:
15+
16+
Overview
17+
--------
18+
19+
The Approximate Location feature automatically creates or updates a
20+
device’s location based on latitude and longitude information retrieved
21+
from the WHOIS Lookup feature.
22+
23+
Trigger Conditions
24+
------------------
25+
26+
Approximate Location is triggered when:
27+
28+
- A **fresh WHOIS lookup** is performed for a device.
29+
- Or when a WHOIS record already exists for the device’s IP **and**:
30+
31+
- The device’s last IP address is **public**.
32+
- WHOIS lookup and Approximate Location is **enabled** for the device’s
33+
organization.
34+
35+
Behavior
36+
--------
37+
38+
If **a matching location already exists** for another device with the same
39+
IP, the system will **attach that location** to the current device if:
40+
41+
- Only one device is found with that IP and it has a location.
42+
- The current device **has no location** or if it does then the location
43+
is **approximate**.
44+
45+
If there is **no matching location**, a new approximate location is
46+
created or the existing one is updated using coordinates from the WHOIS
47+
record, but only if the existing location is approximate.

docs/user/settings.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,3 +793,20 @@ Maxmind Account ID required for the :doc:`WHOIS Lookup feature <whois>`.
793793
============ =======
794794

795795
Maxmind License Key required for the :doc:`WHOIS Lookup feature <whois>`.
796+
797+
.. _openwisp_controller_whois_approximate_location_enabled:
798+
799+
``OPENWISP_CONTROLLER_WHOIS_APPROXIMATE_LOCATION_ENABLED``
800+
----------------------------------------------------------
801+
802+
============ =========
803+
**type**: ``bool``
804+
**default**: ``False``
805+
============ =========
806+
807+
Allows enabling the optional :doc:`Approximate Location feature
808+
<approximate-location>`.
809+
810+
.. image:: https://raw.githubusercontent.com/openwisp/openwisp-controller/docs/docs/1.3/approximate-location-setting.png
811+
:target: https://raw.githubusercontent.com/openwisp/openwisp-controller/docs/docs/1.3/approximate-location-setting.png
812+
:alt: Approximate Location setting

openwisp_controller/config/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ def get_fields(self, request, obj=None):
13681368
if app_settings.REGISTRATION_ENABLED:
13691369
fields += ["registration_enabled", "shared_secret"]
13701370
if app_settings.WHOIS_CONFIGURED:
1371-
fields += ["whois_enabled"]
1371+
fields += ["whois_enabled", "approximate_location_enabled"]
13721372
fields += ["context"]
13731373
return fields
13741374

openwisp_controller/config/whois/test_whois.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from .utils import CreateWHOISMixin, WHOISTransactionMixin
1515

1616
Device = load_model("config", "Device")
17-
Location = load_model("geo", "Location")
1817
WHOISInfo = load_model("config", "WHOISInfo")
1918
Notification = load_model("openwisp_notifications", "Notification")
2019
OrganizationConfigSettings = load_model("config", "OrganizationConfigSettings")

openwisp_controller/geo/approximate_location/tasks.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
@shared_task
1111
def manage_approximate_locations(device_pk, ip_address, add_existing=False):
1212
"""
13-
Creates/updates fuzzy location for a device based on the latitude and longitude
14-
or attaches an existing location if `add_existing` is True.
13+
Creates/updates approximate location for a device based on the latitude and
14+
longitude or attaches an existing location if `add_existing` is True.
1515
Existing location here means a location of another device whose last_ip matches
1616
the given ip_address.
1717
@@ -21,7 +21,7 @@ def manage_approximate_locations(device_pk, ip_address, add_existing=False):
2121
2222
When `add_existing` is False:
2323
- A new location is created if no location exists for current device, or
24-
existing one is updated using coords from WHOIS record if it is approximate(fuzzy).
24+
existing one is updated using coords from WHOIS record if it is approximate (fuzzy).
2525
"""
2626
from openwisp_controller.config.whois.utils import send_whois_task_notification
2727

@@ -41,9 +41,9 @@ def _create_update_location():
4141
coords = Point(whois_obj.longitude, whois_obj.latitude, srid=4326)
4242
address = whois_obj.formatted_address
4343
location_name = (
44-
" ".join(address.split(",")[:2])
44+
",".join(address.split(",")[:2]) + f" (Estimated: {ip_address})"
4545
if address
46-
else f"Approximate Location {ip_address}"
46+
else f"Estimated Location: {ip_address}"
4747
)
4848
# Used to update an existing location if it is approximate
4949
# or create a new one if it doesn't exist
@@ -100,5 +100,5 @@ def _create_update_location():
100100
_create_update_location()
101101

102102
logger.info(
103-
f"Fuzzy location saved successfully for {device_pk} for IP: {ip_address}"
103+
f"Approximate location saved successfully for {device_pk} for IP: {ip_address}"
104104
)

openwisp_controller/geo/approximate_location/test_approximate_location.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django.contrib.gis.geos import GEOSGeometry
55
from django.core.exceptions import ImproperlyConfigured, ValidationError
66
from django.test import TestCase, TransactionTestCase, override_settings
7+
from django.urls import reverse
78
from swapper import load_model
89

910
from openwisp_controller.config import settings as config_app_settings
@@ -60,6 +61,41 @@ def test_approximate_location_configuration_setting(self):
6061
except AssertionError:
6162
self.fail("ValidationError message not equal to expected message.")
6263

64+
with self.subTest(
65+
"Test Approximate Location field visible on admin when "
66+
"WHOIS_CONFIGURED True"
67+
):
68+
self._login()
69+
org = self._get_org()
70+
url = reverse(
71+
"admin:openwisp_users_organization_change",
72+
args=[org.pk],
73+
)
74+
response = self.client.get(url)
75+
self.assertContains(
76+
response, 'name="config_settings-0-approximate_location_enabled"'
77+
)
78+
79+
with override_settings(
80+
OPENWISP_CONTROLLER_WHOIS_GEOIP_ACCOUNT=None,
81+
OPENWISP_CONTROLLER_WHOIS_GEOIP_KEY=None,
82+
):
83+
importlib.reload(config_app_settings)
84+
with self.subTest(
85+
"Test Approximate Location field hidden on admin when "
86+
"WHOIS_CONFIGURED False"
87+
):
88+
self._login()
89+
org = self._get_org()
90+
url = reverse(
91+
"admin:openwisp_users_organization_change",
92+
args=[org.pk],
93+
)
94+
response = self.client.get(url)
95+
self.assertNotContains(
96+
response, 'name="config_settings-0-approximate_location_enabled"'
97+
)
98+
6399

64100
class TestApproximateLocationTransaction(
65101
TestApproximateLocationMixin, WHOISTransactionMixin, TransactionTestCase
@@ -128,7 +164,7 @@ def _verify_location_details(device, mocked_response):
128164
mocked_response = self._mocked_client_response()
129165
mock_client.return_value.city.return_value = mocked_response
130166

131-
with self.subTest("Test Fuzzy location created when device is created"):
167+
with self.subTest("Test Approximate location created when device is created"):
132168
device = self._create_device(last_ip="172.217.22.14")
133169

134170
location = device.devicelocation.location
@@ -137,7 +173,7 @@ def _verify_location_details(device, mocked_response):
137173
self.assertEqual(location.type, "outdoor")
138174
_verify_location_details(device, mocked_response)
139175

140-
with self.subTest("Test Fuzzy location updated when last ip is updated"):
176+
with self.subTest("Test Approximate location updated when last ip is updated"):
141177
device.last_ip = "172.217.22.10"
142178
mocked_response.location.latitude = 50
143179
mocked_response.location.longitude = 150

0 commit comments

Comments
 (0)