mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-19 10:08:44 -06:00
Add filtering of Script objects based on object permissions with custom constraints
This commit is contained in:
@@ -18,7 +18,17 @@ They can also be used as a mechanism for validating the integrity of data within
|
|||||||
Custom scripts are Python code which exists outside the NetBox code base, so they can be updated and changed without interfering with the core NetBox installation. And because they're completely custom, there is no inherent limitation on what a script can accomplish.
|
Custom scripts are Python code which exists outside the NetBox code base, so they can be updated and changed without interfering with the core NetBox installation. And because they're completely custom, there is no inherent limitation on what a script can accomplish.
|
||||||
|
|
||||||
!!! danger "Only install trusted scripts"
|
!!! danger "Only install trusted scripts"
|
||||||
Custom scripts have unrestricted access to change anything in the databse and are inherently unsafe and should only be installed and run from trusted sources. You should also review and set permissions for who can run scripts if the script can modify any data.
|
Custom scripts have unrestricted access to change anything in the database and are inherently unsafe and should only be installed and run from trusted sources. You should also review and set permissions for who can run scripts if the script can modify any data.
|
||||||
|
|
||||||
|
!!! tip "Permissions for Custom Scripts"
|
||||||
|
A user can be granted permissions on all Custom Scripts via the "Managed File" object-level permission. To further restrict a user to only be able to access certain scripts, create an additional permission on the "Script" object type, with appropriate queryset-style constraints matching fields available on Script. For example:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name__in": [
|
||||||
|
"MyScript"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Writing Custom Scripts
|
## Writing Custom Scripts
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ from extras.utils import SharedObjectViewMixin
|
|||||||
from netbox.object_actions import *
|
from netbox.object_actions import *
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from netbox.views.generic.mixins import TableMixin
|
from netbox.views.generic.mixins import TableMixin
|
||||||
|
from users.models import ObjectPermission
|
||||||
from utilities.forms import ConfirmationForm, get_field_value
|
from utilities.forms import ConfirmationForm, get_field_value
|
||||||
from utilities.htmx import htmx_partial, htmx_maybe_redirect_current_page
|
from utilities.htmx import htmx_partial, htmx_maybe_redirect_current_page
|
||||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||||
|
from utilities.permissions import qs_filter_from_constraints
|
||||||
from utilities.query import count_related
|
from utilities.query import count_related
|
||||||
from utilities.querydict import normalize_querydict
|
from utilities.querydict import normalize_querydict
|
||||||
from utilities.request import copy_safe_request
|
from utilities.request import copy_safe_request
|
||||||
@@ -1441,12 +1443,24 @@ class ScriptListView(ContentTypePermissionRequiredMixin, View):
|
|||||||
return 'extras.view_script'
|
return 'extras.view_script'
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
# Permissions for the Scripts page are given via the "Managed File" object permission. To further restrict
|
||||||
|
# users to access only specified scripts, create permissions on the "Script" object with appropriate
|
||||||
|
# queryset-style constraints matching fields available on Script.
|
||||||
script_modules = ScriptModule.objects.restrict(request.user).prefetch_related(
|
script_modules = ScriptModule.objects.restrict(request.user).prefetch_related(
|
||||||
'data_source', 'data_file', 'jobs'
|
'data_source', 'data_file', 'jobs'
|
||||||
)
|
)
|
||||||
|
script_ct = ContentType.objects.get_for_model(Script)
|
||||||
|
script_permissions = qs_filter_from_constraints(
|
||||||
|
ObjectPermission.objects.filter(
|
||||||
|
users=self.request.user, object_types=script_ct
|
||||||
|
).values_list("constraints", flat=True)
|
||||||
|
)
|
||||||
|
available_scripts = Script.objects.filter(script_permissions, module__in=script_modules)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'model': ScriptModule,
|
'model': ScriptModule,
|
||||||
'script_modules': script_modules,
|
'script_modules': script_modules,
|
||||||
|
'available_scripts': available_scripts,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use partial template for dashboard widgets
|
# Use partial template for dashboard widgets
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for script in scripts %}
|
{% for script in scripts %}
|
||||||
|
{% if script in available_scripts %}
|
||||||
{% with last_job=script.get_latest_jobs|first %}
|
{% with last_job=script.get_latest_jobs|first %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -113,6 +114,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Reference in New Issue
Block a user