mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-21 11:37:21 -06:00
Clean up permissions utility functions
This commit is contained in:
parent
7b01ba9776
commit
85e932bfc1
@ -6,7 +6,7 @@ from django.contrib.auth.models import Group
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from users.models import ObjectPermission
|
from users.models import ObjectPermission
|
||||||
from utilities.permissions import permission_is_exempt, resolve_permission
|
from utilities.permissions import permission_is_exempt, resolve_permission, resolve_permission_ct
|
||||||
|
|
||||||
|
|
||||||
class ObjectPermissionBackend(ModelBackend):
|
class ObjectPermissionBackend(ModelBackend):
|
||||||
@ -42,8 +42,7 @@ class ObjectPermissionBackend(ModelBackend):
|
|||||||
return perms
|
return perms
|
||||||
|
|
||||||
def has_perm(self, user_obj, perm, obj=None):
|
def has_perm(self, user_obj, perm, obj=None):
|
||||||
app_label, codename = perm.split('.')
|
app_label, action, model_name = resolve_permission(perm)
|
||||||
action, model_name = codename.split('_')
|
|
||||||
|
|
||||||
# Superusers implicitly have all permissions
|
# Superusers implicitly have all permissions
|
||||||
if user_obj.is_active and user_obj.is_superuser:
|
if user_obj.is_active and user_obj.is_superuser:
|
||||||
@ -114,7 +113,7 @@ class RemoteUserBackend(_RemoteUserBackend):
|
|||||||
permissions_list = []
|
permissions_list = []
|
||||||
for permission_name, attrs in settings.REMOTE_AUTH_DEFAULT_PERMISSIONS.items():
|
for permission_name, attrs in settings.REMOTE_AUTH_DEFAULT_PERMISSIONS.items():
|
||||||
try:
|
try:
|
||||||
content_type, action = resolve_permission(permission_name)
|
content_type, action = resolve_permission_ct(permission_name)
|
||||||
# TODO: Merge multiple actions into a single ObjectPermission per content type
|
# TODO: Merge multiple actions into a single ObjectPermission per content type
|
||||||
obj_perm = ObjectPermission(actions=[action], attrs=attrs)
|
obj_perm = ObjectPermission(actions=[action], attrs=attrs)
|
||||||
obj_perm.save()
|
obj_perm.save()
|
||||||
|
@ -19,33 +19,36 @@ def get_permission_for_model(model, action):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_permission_action(name):
|
def resolve_permission(name):
|
||||||
"""
|
"""
|
||||||
Return the action component (e.g. view or add) from a permission name.
|
Given a permission name, return the app_label, action, and model_name components. For example, "dcim.view_site"
|
||||||
|
returns ("dcim", "view", "site").
|
||||||
|
|
||||||
:param name: Permission name in the format <app_label>.<action>_<model>
|
:param name: Permission name in the format <app_label>.<action>_<model>
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return name.split('.')[1].split('_')[0]
|
app_label, codename = name.split('.')
|
||||||
|
action, model_name = codename.rsplit('_', 1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Invalid permission name: {name}. Must be in the format <app_label>.<action>_<model>"
|
f"Invalid permission name: {name}. Must be in the format <app_label>.<action>_<model>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return app_label, action, model_name
|
||||||
|
|
||||||
def resolve_permission(name):
|
|
||||||
|
def resolve_permission_ct(name):
|
||||||
"""
|
"""
|
||||||
Given a permission name, return the relevant ContentType and action. For example, "dcim.view_site" returns
|
Given a permission name, return the relevant ContentType and action. For example, "dcim.view_site" returns
|
||||||
(Site, "view").
|
(Site, "view").
|
||||||
|
|
||||||
:param name: Permission name in the format <app_label>.<action>_<model>
|
:param name: Permission name in the format <app_label>.<action>_<model>
|
||||||
"""
|
"""
|
||||||
app_label, codename = name.split('.')
|
app_label, action, model_name = resolve_permission(name)
|
||||||
action, model_name = codename.split('_')
|
|
||||||
try:
|
try:
|
||||||
content_type = ContentType.objects.get(app_label=app_label, model=model_name)
|
content_type = ContentType.objects.get(app_label=app_label, model=model_name)
|
||||||
except ContentType.DoesNotExist:
|
except ContentType.DoesNotExist:
|
||||||
raise ValueError(f"Unknown app/model for {name}")
|
raise ValueError(f"Unknown app_label/model_name for {name}")
|
||||||
|
|
||||||
return content_type, action
|
return content_type, action
|
||||||
|
|
||||||
@ -56,8 +59,7 @@ def permission_is_exempt(name):
|
|||||||
|
|
||||||
:param name: Permission name in the format <app_label>.<action>_<model>
|
:param name: Permission name in the format <app_label>.<action>_<model>
|
||||||
"""
|
"""
|
||||||
app_label, codename = name.split('.')
|
app_label, action, model_name = resolve_permission(name)
|
||||||
action, model_name = codename.split('_')
|
|
||||||
|
|
||||||
if action == 'view':
|
if action == 'view':
|
||||||
if (
|
if (
|
||||||
|
@ -7,7 +7,7 @@ from django.urls import reverse, NoReverseMatch
|
|||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
from users.models import ObjectPermission, Token
|
from users.models import ObjectPermission, Token
|
||||||
from utilities.permissions import resolve_permission
|
from utilities.permissions import resolve_permission_ct
|
||||||
from .utils import disable_warnings, post_data
|
from .utils import disable_warnings, post_data
|
||||||
|
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ class TestCase(_TestCase):
|
|||||||
Assign a set of permissions to the test user. Accepts permission names in the form <app>.<action>_<model>.
|
Assign a set of permissions to the test user. Accepts permission names in the form <app>.<action>_<model>.
|
||||||
"""
|
"""
|
||||||
for name in names:
|
for name in names:
|
||||||
ct, action = resolve_permission(name)
|
ct, action = resolve_permission_ct(name)
|
||||||
obj_perm = ObjectPermission(actions=[action])
|
obj_perm = ObjectPermission(actions=[action])
|
||||||
obj_perm.save()
|
obj_perm.save()
|
||||||
obj_perm.users.add(self.user)
|
obj_perm.users.add(self.user)
|
||||||
|
@ -28,7 +28,7 @@ from extras.models import CustomField, CustomFieldValue, ExportTemplate
|
|||||||
from extras.querysets import CustomFieldQueryset
|
from extras.querysets import CustomFieldQueryset
|
||||||
from utilities.exceptions import AbortTransaction
|
from utilities.exceptions import AbortTransaction
|
||||||
from utilities.forms import BootstrapMixin, CSVDataField, TableConfigForm
|
from utilities.forms import BootstrapMixin, CSVDataField, TableConfigForm
|
||||||
from utilities.permissions import get_permission_action, get_permission_for_model
|
from utilities.permissions import get_permission_for_model, resolve_permission
|
||||||
from utilities.utils import csv_format, prepare_cloned_fields
|
from utilities.utils import csv_format, prepare_cloned_fields
|
||||||
from .error_handlers import handle_protectederror
|
from .error_handlers import handle_protectederror
|
||||||
from .forms import ConfirmationForm, ImportForm
|
from .forms import ConfirmationForm, ImportForm
|
||||||
@ -64,7 +64,7 @@ class ObjectPermissionRequiredMixin(AccessMixin):
|
|||||||
if user.has_perms((permission_required, *self.additional_permissions)):
|
if user.has_perms((permission_required, *self.additional_permissions)):
|
||||||
|
|
||||||
# Update the view's QuerySet to filter only the permitted objects
|
# Update the view's QuerySet to filter only the permitted objects
|
||||||
action = get_permission_action(permission_required)
|
action = resolve_permission(permission_required)[1]
|
||||||
self.queryset = self.queryset.restrict(user, action)
|
self.queryset = self.queryset.restrict(user, action)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -233,7 +233,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|||||||
# Compile a dictionary indicating which permissions are available to the current user for this model
|
# Compile a dictionary indicating which permissions are available to the current user for this model
|
||||||
permissions = {}
|
permissions = {}
|
||||||
for action in ('add', 'change', 'delete', 'view'):
|
for action in ('add', 'change', 'delete', 'view'):
|
||||||
perm_name = '{}.{}_{}'.format(model._meta.app_label, action, model._meta.model_name)
|
perm_name = get_permission_for_model(model, action)
|
||||||
permissions[action] = request.user.has_perm(perm_name)
|
permissions[action] = request.user.has_perm(perm_name)
|
||||||
|
|
||||||
# Construct the table based on the user's permissions
|
# Construct the table based on the user's permissions
|
||||||
|
Loading…
Reference in New Issue
Block a user