Sfoglia il codice sorgente

Closes #9070: Hide navigation menu items based on user permissions

jeremystretch 3 anni fa
parent
commit
779969f150

+ 1 - 0
docs/release-notes/version-3.3.md

@@ -27,6 +27,7 @@
 * [#8471](https://github.com/netbox-community/netbox/issues/8471) - Add `status` field to Cluster
 * [#8495](https://github.com/netbox-community/netbox/issues/8495) - Enable custom field grouping
 * [#8995](https://github.com/netbox-community/netbox/issues/8995) - Enable arbitrary ordering of REST API results
+* [#9070](https://github.com/netbox-community/netbox/issues/9070) - Hide navigation menu items based on user permissions
 * [#9166](https://github.com/netbox-community/netbox/issues/9166) - Add UI visibility toggle for custom fields
 * [#9177](https://github.com/netbox-community/netbox/issues/9177) - Add tenant assignment for wireless LANs & links
 * [#9536](https://github.com/netbox-community/netbox/issues/9536) - Track API token usage times

+ 38 - 53
netbox/utilities/templates/navigation/menu.html

@@ -1,58 +1,43 @@
 {% load helpers %}
 
 <ul class="navbar-nav">
-    {% for menu in nav_items %}
-        <li class="nav-item">
-            <a class="nav-link" href="#menu{{ menu.label }}" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="menu{{ menu.label }}">
-               <i class="{{ menu.icon_class }}"></i>
-               <span class="nav-link-text">{{ menu.label }}</span>
-             </a>
-            <div class="collapse" id="menu{{ menu.label }}">
-                <ul class="nav nav-sm flex-column">
-
-                    {% for group in menu.groups %}
-                        {# Within each main menu, there are groups of menu items #}
-                            <li class="nav-item">
-                                {# Group Label #}
-                                <div class="nav-group-header">
-                                    <span class="nav-group-label">{{ group.label }}</span>
-                                </div>
-                            </li>
-
-                        {% for item in group.items %}
-                            {# Each Item #}
-                            {% if request.user|has_perms:item.permissions %}
-                            <li class="nav-item{% if not item.buttons %} no-buttons{% endif %}">
-                                <a href="{% url item.link %}" class="nav-link">
-                                    {{ item.link_text }}
-                                </a>
-
-                                {# Menu item buttons (if any) #}
-                                {% if item.buttons %}
-                                    <div class="btn-group px-2">
-                                        {% for button in item.buttons %}
-                                            {% if request.user|has_perms:button.permissions %}
-                                                    <a class="btn btn-sm btn-{{ button.color }} lh-1" href="{% url button.link %}" title="{{ button.title }}">
-                                                        <i class="{{ button.icon_class }}"></i>
-                                                    </a>
-                                            {% endif %}
-                                        {% endfor %}
-                                    </div>
-                                {% endif %}
-                            </li>
-                            {% else %}
-                                {# Display a disabled link (no permission) #}
-                                <li class="nav-item disabled">
-                                    <a href="#" class="nav-link disabled" aria-disabled="true" disabled>
-                                        <i class='mdi mdi-lock small'></i>
-                                        {{ item.link_text }}
-                                    </a>
-                                </li>
-                            {% endif %}
-                        {% endfor %}
+  {% for menu, groups in nav_items %}
+    <li class="nav-item">
+      {# Menu heading #}
+      <a class="nav-link" href="#menu{{ menu.label }}" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="menu{{ menu.label }}">
+       <i class="{{ menu.icon_class }}"></i>
+       <span class="nav-link-text">{{ menu.label }}</span>
+      </a>
+      {# Menu groups #}
+      <div class="collapse" id="menu{{ menu.label }}">
+        <ul class="nav nav-sm flex-column">
+          {% for group, items in groups %}
+            {# Group heading #}
+            <li class="nav-item">
+              <div class="nav-group-header">
+                <span class="nav-group-label">{{ group.label }}</span>
+              </div>
+            </li>
+            {# Group items #}
+            {% for item, buttons in items %}
+              <li class="nav-item{% if not item.buttons %} no-buttons{% endif %}">
+                {# Item #}
+                <a href="{% url item.link %}" class="nav-link">{{ item.link_text }}</a>
+                {# Item buttons (if any) #}
+                {% if buttons %}
+                  <div class="btn-group px-2">
+                    {% for button in buttons %}
+                      <a class="btn btn-sm btn-{{ button.color }} lh-1" href="{% url button.link %}" title="{{ button.title }}">
+                        <i class="{{ button.icon_class }}"></i>
+                      </a>
                     {% endfor %}
-                </ul>
-            </div>
-        </li>
-    {% endfor %}
+                  </div>
+                {% endif %}
+              </li>
+            {% endfor %}
+          {% endfor %}
+        </ul>
+      </div>
+    </li>
+  {% endfor %}
 </ul>

+ 20 - 1
netbox/utilities/templatetags/navigation.py

@@ -13,7 +13,26 @@ def nav(context: Context) -> Dict:
     """
     Render the navigation menu.
     """
+    user = context['request'].user
+    nav_items = []
+
+    # Construct the navigation menu based upon the current user's permissions
+    for menu in MENUS:
+        groups = []
+        for group in menu.groups:
+            items = []
+            for item in group.items:
+                if user.has_perms(item.permissions):
+                    buttons = [
+                        button for button in item.buttons if user.has_perms(button.permissions)
+                    ]
+                    items.append((item, buttons))
+            if items:
+                groups.append((group, items))
+        if groups:
+            nav_items.append((menu, groups))
+
     return {
-        "nav_items": MENUS,
+        "nav_items": nav_items,
         "request": context["request"]
     }