Bläddra i källkod

Extend menu items and buttons to accept a list of required permissions

Jeremy Stretch 5 år sedan
förälder
incheckning
e7f7b14214

+ 2 - 3
docs/plugins/development.md

@@ -305,17 +305,16 @@ A `PluginMenuItem` has the following attributes:
 
 * `link` - The name of the URL path to which this menu item links
 * `link_text` - The text presented to the user
-* `permission` - The name of the permission required to display this link (optional)
+* `permissions` - A list of permissions required to display this link (optional)
 * `buttons` - An iterable of PluginMenuButton instances to display (optional)
 
-
 A `PluginMenuButton` has the following attributes:
 
 * `link` - The name of the URL path to which this button links
 * `title` - The tooltip text (displayed when the mouse hovers over the button)
 * `icon_class` - Button icon CSS class
 * `color` - One of the choices provided by `ButtonColorChoices` (optional)
-* `permission` - The name of the permission required to display this button (optional)
+* `permissions` - A list of permissions required to display this button (optional)
 
 ## Extending Core Templates
 

+ 15 - 8
netbox/extras/plugins/__init__.py

@@ -160,13 +160,17 @@ class PluginMenuItem:
     Links are specified as Django reverse URL strings.
     Buttons are each specified as a list of PluginMenuButton instances.
     """
-    def __init__(self, link, link_text, permission=None, buttons=None):
+    permissions = []
+    buttons = []
+
+    def __init__(self, link, link_text, permissions=None, buttons=None):
         self.link = link
         self.link_text = link_text
-        self.permission = permission
-        if buttons is None:
-            self.buttons = []
-        else:
+        if permissions is not None:
+            if type(permissions) not in (list, tuple):
+                raise TypeError("Permissions must be passed as a tuple or list.")
+            self.permissions = permissions
+        if buttons is not None:
             self.buttons = buttons
 
 
@@ -176,13 +180,16 @@ class PluginMenuButton:
     ButtonColorChoices.
     """
     color = ButtonColorChoices.DEFAULT
+    permissions = []
 
-    def __init__(self, link, title, icon_class, color=None, permission=None):
+    def __init__(self, link, title, icon_class, color=None, permissions=None):
         self.link = link
         self.title = title
         self.icon_class = icon_class
-        self.permission = permission
-
+        if permissions is not None:
+            if type(permissions) not in (list, tuple):
+                raise TypeError("Permissions must be passed as a tuple or list.")
+            self.permissions = permissions
         if color is not None:
             self.color = color
 

+ 13 - 16
netbox/templates/inc/plugin_menu_items.html

@@ -1,25 +1,22 @@
+{% load helpers %}
 <li class="dropdown">
     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Plugins <span class="caret"></span></a>
     <ul class="dropdown-menu">
         {% for section_name, menu_items in plugin_menu_items.items %}
             <li class="dropdown-header">{{ section_name }}</li>
             {% for menu_item in menu_items %}
-                {% if menu_item.permission %}
-                    <li{% if not menu_item.permission in perms %} class="disabled"{% endif %}>
-                {% else %}
-                    <li>
-                {% endif %}
-                        {% if menu_item.buttons %}
-                            <div class="buttons pull-right">
-                                {% for button in menu_item.buttons %}
-                                    {% if not button.permission or button.permission in perms %}
-                                        <a href="{% url button.link %}" class="btn btn-xs btn-{{ button.color }}" title="{{ button.title }}"><i class="fa {{ button.icon_class }}"></i></a>
-                                    {% endif %}
-                                {% endfor %}
-                            </div>
-                        {% endif %}
-                        <a href="{% url menu_item.link %}">{{ menu_item.link_text }}</a>
-                    </li>
+                <li{% if menu_item.permissions and not request.user|has_perms:menu_item.permissions %} class="disabled"{% endif %}>
+                    {% if menu_item.buttons %}
+                        <div class="buttons pull-right">
+                            {% for button in menu_item.buttons %}
+                                {% if not button.permissions or request.user|has_perms:button.permissions %}
+                                    <a href="{% url button.link %}" class="btn btn-xs btn-{{ button.color }}" title="{{ button.title }}"><i class="fa {{ button.icon_class }}"></i></a>
+                                {% endif %}
+                            {% endfor %}
+                        </div>
+                    {% endif %}
+                    <a href="{% url menu_item.link %}">{{ menu_item.link_text }}</a>
+                </li>
             {% endfor %}
             {% if not forloop.last %}
                 <li class="divider"></li>

+ 8 - 0
netbox/utilities/templatetags/helpers.py

@@ -201,6 +201,14 @@ def get_docs(model):
     return mark_safe(content)
 
 
+@register.filter()
+def has_perms(user, permissions_list):
+    """
+    Return True if the user has *all* permissions in the list.
+    """
+    return user.has_perms(permissions_list)
+
+
 #
 # Tags
 #