-
-
Notifications
You must be signed in to change notification settings - Fork 227
Open
Labels
Description
Describe the bug
If an API access to
api/v1/controller/device/[device UUID]/location/
happens without superuser permissions it casuses a crash.
Steps To Reproduce
Create an user which has limited (location) permissions, but not the Superuser status
checked.
Login with that user and open the API access for the device location:
https://api.openwisp.example.com/api/v1/controller/device/83a77e46-9248-41fb-9a8f-0bf1751ef045/location/
It only reports then Server Error (500)
and ends up with the following crash in the log:
nginx-1 | [c2edc3204181] - - [11/Aug/2025:01:14:15 +0200] "GET /api/v1/controller/device/83a77e46-9248-41fb-9a8f-0bf1751ef045/location/ HTTP/1.1" status: 500 145 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0" http_x_forwarded_for: 41.66.90.31 - remote_addr: 192.168.72.5 - realip_remote_addr: 192.168.72.5 - real_ip: 41.66.90.31
nginx-1 | [c2edc3204181] - - [11/Aug/2025:01:14:15 +0200] "GET /favicon.ico HTTP/1.1" status: 404 179 "https://api.openwisp.example.com/api/v1/controller/device/83a77e46-9248-41fb-9a8f-0bf1751ef045/location/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0" http_x_forwarded_for: 41.66.90.31 - remote_addr: 192.168.72.5 - realip_remote_addr: 192.168.72.5 - real_ip: 41.66.90.31
api-1 |
api-1 | [092f75d2285f] - ERROR, time: [2025-08-11 01:14:15,549],process: 14, thread: 126987757770624
api-1 | Internal Server Error: /api/v1/controller/device/83a77e46-9248-41fb-9a8f-0bf1751ef045/location/
api-1 | Traceback (most recent call last):
api-1 | File "/usr/local/lib/python3.13/site-packages/django/core/handlers/exception.py", line 55, in inner
api-1 | response = get_response(request)
api-1 | File "/usr/local/lib/python3.13/site-packages/django/core/handlers/base.py", line 197, in _get_response
api-1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
api-1 | File "/usr/local/lib/python3.13/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
api-1 | return view_func(request, *args, **kwargs)
api-1 | File "/usr/local/lib/python3.13/site-packages/django/views/generic/base.py", line 105, in view
api-1 | return self.dispatch(request, *args, **kwargs)
api-1 | ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 509, in dispatch
api-1 | response = self.handle_exception(exc)
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 469, in handle_exception
api-1 | self.raise_uncaught_exception(exc)
api-1 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
api-1 | raise exc
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 497, in dispatch
api-1 | self.initial(request, *args, **kwargs)
api-1 | ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 415, in initial
api-1 | self.check_permissions(request)
api-1 | ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/views.py", line 332, in check_permissions
api-1 | if not permission.has_permission(request, self):
api-1 | ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_controller/mixins.py", line 19, in has_permission
api-1 | perm = super().has_permission(request, view)
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_users/api/permissions.py", line 120, in has_permission
api-1 | queryset = self._queryset(view)
api-1 | File "/usr/local/lib/python3.13/site-packages/rest_framework/permissions.py", line 223, in _queryset
api-1 | queryset = view.get_queryset()
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_controller/geo/api/views.py", line 121, in get_queryset
api-1 | qs = super().get_queryset()
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_users/api/mixins.py", line 57, in get_queryset
api-1 | qs = super().get_queryset()
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_users/api/mixins.py", line 105, in get_queryset
api-1 | self.assert_parent_exists()
api-1 | ~~~~~~~~~~~~~~~~~~~~~~~~~^^
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_users/api/mixins.py", line 111, in assert_parent_exists
api-1 | parent_queryset = self.get_organization_queryset(parent_queryset)
api-1 | File "/usr/local/lib/python3.13/site-packages/openwisp_users/api/mixins.py", line 65, in get_organization_queryset
api-1 | return qs.filter(self.queryset_organization_conditions)
api-1 | ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/query.py", line 1493, in filter
api-1 | return self._filter_or_exclude(False, args, kwargs)
api-1 | ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/query.py", line 1511, in _filter_or_exclude
api-1 | clone._filter_or_exclude_inplace(negate, args, kwargs)
api-1 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/query.py", line 1518, in _filter_or_exclude_inplace
api-1 | self._query.add_q(Q(*args, **kwargs))
api-1 | ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1646, in add_q
api-1 | clause, _ = self._add_q(q_object, can_reuse)
api-1 | ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1678, in _add_q
api-1 | child_clause, needed_inner = self.build_filter(
api-1 | ~~~~~~~~~~~~~~~~~^
api-1 | child,
api-1 | ^^^^^^
api-1 | ...<7 lines>...
api-1 | update_join_types=update_join_types,
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | )
api-1 | ^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1503, in build_filter
api-1 | return self._add_q(
api-1 | ~~~~~~~~~~~^
api-1 | filter_expr,
api-1 | ^^^^^^^^^^^^
api-1 | ...<7 lines>...
api-1 | update_join_types=update_join_types,
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | )
api-1 | ^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1678, in _add_q
api-1 | child_clause, needed_inner = self.build_filter(
api-1 | ~~~~~~~~~~~~~~~~~^
api-1 | child,
api-1 | ^^^^^^
api-1 | ...<7 lines>...
api-1 | update_join_types=update_join_types,
api-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | )
api-1 | ^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1526, in build_filter
api-1 | lookups, parts, reffed_expression = self.solve_lookup_type(arg, summarize)
api-1 | ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1333, in solve_lookup_type
api-1 | _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
api-1 | ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
api-1 | File "/usr/local/lib/python3.13/site-packages/django/db/models/sql/query.py", line 1805, in names_to_path
api-1 | raise FieldError(
api-1 | ...<2 lines>...
api-1 | )
api-1 | django.core.exceptions.FieldError: Cannot resolve keyword 'content_object' into field. Choices are: _is_deactivated, command, config, created, deviceconnection, devicefirmware, devicelocation, group, group_id, hardware_id, id, key, last_ip, mac_address, management_ip, model, modified, monitoring, name, notes, organization, organization_id, os, system, upgradeoperation, wifisession
api-1 | [092f75d2285f] - pid: 14 192.168.72.5 (-) {68 vars in 1288 bytes} [Mon Aug 11 01:14:15 2025] GET /api/v1/controller/device/83a77e46-9248-41fb-9a8f-0bf1751ef045/location/ => generated 145 bytes in 61 msecs (HTTP/1.1 500) 7 headers in 248 bytes (1 switches on core 0)
api-1 |
api-1 | [092f75d2285f] - WARNING, time: [2025-08-11 01:14:15,604],process: 14, thread: 126987530643200
api-1 | Not Found: /favicon.ico
api-1 | [092f75d2285f] - pid: 14 192.168.72.5 (-) {66 vars in 1235 bytes} [Mon Aug 11 01:14:15 2025] GET /favicon.ico => generated 179 bytes in 5 msecs (HTTP/1.1 404) 7 headers in 228 bytes (1 switches on core 1)
System Informatioon:
Docker Image: 24.11.2