Skip to content

feat: add two-tier permission system with plugin and object-level access control#213

Merged
bonzo81 merged 7 commits intodevelopfrom
feature/permissions
Feb 16, 2026
Merged

feat: add two-tier permission system with plugin and object-level access control#213
bonzo81 merged 7 commits intodevelopfrom
feature/permissions

Conversation

@bonzo81
Copy link
Owner

@bonzo81 bonzo81 commented Feb 5, 2026

Summary

Adds a two-tier permission system to all plugin views:

  1. Plugin-level accessview_librenmssettings gates page access; change_librenmssettings gates write actions
  2. NetBox object permissions — Sync/import POST handlers check model-specific permissions (e.g., dcim.add_cable, dcim.change_device)

Changes

Core

  • New LibreNMSPermissionMixin and NetBoxObjectPermissionMixin in views/mixins.py
  • Permission constants in constants.py
  • LibreNMSPluginPermission class for API endpoints

Views

  • All views now inherit LibreNMSPermissionMixin
  • All sync POST handlers call require_write_permission() / require_all_permissions()
  • Import views check write permissions before confirm/import operations

Background Jobs

  • Non-superusers automatically fall back to synchronous mode (NetBox core restricts /api/core/background-tasks/ to superusers)
  • Import template conditionally shows background job UI

Navigation

  • All menu items require view_librenmssettings — unauthorized users don't see the menu

Documentation

  • User-facing permissions guide at docs/usage_tips/permissions.md
  • Added to mkdocs.yml nav

Tests

  • New test_permissions.py (780+ lines) covering mixins, API permissions, object permission helpers
  • Updated test_background_jobs.py for superuser fallback logic

…ess control

- Add LibreNMSPermissionMixin and NetBoxObjectPermissionMixin to all views
- Enforce view/change permissions on LibreNMSSettings model
- Add NetBox object permission checks on sync POST handlers
- Auto-fallback to synchronous mode for non-superuser background jobs
- Update navigation, API, templates, and import UI for permission gating
- Add user-facing permissions documentation and mkdocs nav entry
- Add test_permissions.py and update test_background_jobs.py
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a consistent two-tier authorization scheme across the NetBox LibreNMS plugin: a plugin-level permission gate for page access/write actions, plus NetBox model permission checks for object-mutating sync/import operations. It also adjusts background-job UX/behavior to fall back to synchronous execution for non-superusers (due to NetBox core background-task API restrictions).

Changes:

  • Introduces reusable permission mixins/constants and applies them across sync/import/status/settings views.
  • Adds model-level permission enforcement for sync/import POST handlers and passes user context into import utilities/jobs for permission checks.
  • Updates import UI/docs/tests to reflect background-job superuser-only polling and the new permission model.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
netbox_librenms_plugin/views/mixins.py Adds LibreNMSPermissionMixin + NetBoxObjectPermissionMixin helpers used across views.
netbox_librenms_plugin/constants.py Defines plugin permission constants (PERM_VIEW_PLUGIN, PERM_CHANGE_PLUGIN).
netbox_librenms_plugin/views/sync/locations.py Gates location create/update POSTs behind plugin write permission.
netbox_librenms_plugin/views/sync/ip_addresses.py Adds combined plugin + object permission enforcement for IP sync POSTs.
netbox_librenms_plugin/views/sync/interfaces.py Adds combined plugin + object permission enforcement for interface sync/delete POSTs.
netbox_librenms_plugin/views/sync/cables.py Adds combined plugin + object permission enforcement for cable sync POSTs.
netbox_librenms_plugin/views/sync/devices.py Gates device add/update actions behind plugin write permission.
netbox_librenms_plugin/views/sync/device_fields.py Adds combined plugin + object permission enforcement for device-field update actions.
netbox_librenms_plugin/views/base/librenms_sync_view.py Applies plugin view permission gate to base sync list view.
netbox_librenms_plugin/views/base/interfaces_view.py Applies plugin view permission gate to base interfaces view.
netbox_librenms_plugin/views/base/ip_addresses_view.py Applies plugin view permission gate to base IPs view and verify endpoint.
netbox_librenms_plugin/views/base/cables_view.py Applies plugin view permission gate to base cables view.
netbox_librenms_plugin/views/imports/list.py Applies plugin view permission gate + superuser-only background-job selection + context flag for template.
netbox_librenms_plugin/views/imports/actions.py Gates bulk import confirm/import actions behind plugin write permission; propagates user for permission checks; handles PermissionDenied.
netbox_librenms_plugin/import_utils.py Adds permission-check helpers and checks at start of bulk imports; plumbs user through.
netbox_librenms_plugin/jobs.py Passes user context into import utilities from background jobs.
netbox_librenms_plugin/api/views.py Adds DRF permission class for plugin API endpoints; converts sync_job_status to DRF decorators.
netbox_librenms_plugin/navigation.py Requires plugin view permission for menu visibility; renames menu label.
netbox_librenms_plugin/views/settings_views.py Replaces direct PermissionRequiredMixin with plugin permission mixin + explicit write check on POST.
netbox_librenms_plugin/views/status_check.py Applies plugin view permission gate to status list views.
netbox_librenms_plugin/views/mapping_views.py Applies plugin view permission gate to mapping CRUD/list views.
netbox_librenms_plugin/views/object_sync/devices.py Uses plugin view permission constant for tab visibility; adds plugin permission mixin to verify endpoint.
netbox_librenms_plugin/views/object_sync/vms.py Uses plugin view permission constant for tab visibility.
netbox_librenms_plugin/templates/netbox_librenms_plugin/librenms_import.html Disables background-job UI for non-superusers and hides cancel UI accordingly.
netbox_librenms_plugin/static/netbox_librenms_plugin/js/librenms_import.js Improves filter fetch error handling; uses modal manager hide helper consistently.
netbox_librenms_plugin/tests/test_permissions.py Adds comprehensive coverage for new mixins/helpers/API permission class and import permission enforcement.
netbox_librenms_plugin/tests/test_background_jobs.py Updates coverage for superuser-only background-job behavior.
netbox_librenms_plugin/tables/locations.py Adjusts accessors for site/location sync table data.
netbox_librenms_plugin/tables/interfaces.py Refactors row attr lambda for readability.
netbox_librenms_plugin/tables/device_status.py Minor comment/formatting updates related to backend permission handling.
docs/usage_tips/permissions.md Adds user-facing permissions guide for the new permission model.
mkdocs.yml Adds permissions guide to MkDocs nav.
docs/SUMMARY.md Adds permissions guide to docs summary.

Comment on lines 27 to 34
@@ -33,7 +34,7 @@ class InterfaceTypeMappingCreateView(generic.ObjectEditView):

Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These views perform write operations (create/edit/delete/bulk actions) but LibreNMSPermissionMixin only requires the plugin view permission. If write actions are intended to be gated by change_librenmssettings (as described elsewhere in this PR), these classes should require the change permission as well (e.g., override permission_required for write views or add a method-based permission check).

Copilot uses AI. Check for mistakes.
Validate Referer header with url_has_allowed_host_and_scheme before
using it for HX-Redirect or redirect targets. Falls back to
request.path when the referrer is external or missing.
Add dcim.add_virtualchassis to bulk import permission checks.
Explicitly validate object_type in sync views, raising Http404
for invalid values instead of silently defaulting to VM permissions.
Replace inline HTML alert response with messages.error and
HX-Redirect to match the permission denial pattern used elsewhere.
@bonzo81 bonzo81 merged commit d665ea1 into develop Feb 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant