Prechádzať zdrojové kódy

Merge branch 'develop' into feature

jeremystretch 4 rokov pred
rodič
commit
803f9b6913

+ 8 - 5
CONTRIBUTING.md

@@ -160,17 +160,20 @@ accumulating a large backlog of work.
 The core maintainers group has chosen to make use of GitHub's [Stale bot](https://github.com/apps/stale)
 to aid in issue management.
 
-* Issues will be marked as stale after 45 days of no activity.
-* Then after 15 more days of inactivity, the issue will be closed.
+* Issues will be marked as stale after 60 days of no activity.
+* If the stable label is not removed in the following 30 days, the issue will
+  be closed automatically.
 * Any issue bearing one of the following labels will be exempt from all Stale
   bot actions:
   * `status: accepted`
   * `status: blocked`
   * `status: needs milestone`
 
-It is natural that some new issues get more attention than others. Stale bot
-helps bring renewed attention to potentially valuable issues that may have been
-overlooked.
+It is natural that some new issues get more attention than others. The stale
+bot helps bring renewed attention to potentially valuable issues that may have
+been overlooked. **Do not** comment on an issue that has been marked stale in
+an effort to circumvent the bot: Doing so will not remove the stale label.
+(Stale labels can be removed only by maintainers.)
 
 ## Maintainer Guidance
 

+ 5 - 0
docs/installation/3-netbox.md

@@ -73,6 +73,11 @@ Next, clone the **master** branch of the NetBox GitHub repository into the curre
 
 ```no-highlight
 $ sudo git clone -b master https://github.com/netbox-community/netbox.git .
+```
+
+The screen below should be the result:
+
+```
 Cloning into '.'...
 remote: Counting objects: 1994, done.
 remote: Compressing objects: 100% (150/150), done.

+ 55 - 0
docs/plugins/index.md

@@ -89,3 +89,58 @@ Restart the WSGI service to load the new plugin:
 ```no-highlight
 # sudo systemctl restart netbox
 ```
+
+## Removing Plugins
+
+Follow these steps to completely remove a plugin.
+
+### Update Configuration
+
+Remove the plugin from the `PLUGINS` list in `configuration.py`. Also remove any relevant configuration parameters from `PLUGINS_CONFIG`.
+
+### Remove the Python Package
+
+Use `pip` to remove the installed plugin:
+
+```no-highlight
+$ source /opt/netbox/venv/bin/activate
+(venv) $ pip uninstall <package>
+```
+
+### Restart WSGI Service
+
+Restart the WSGI service:
+
+```no-highlight
+# sudo systemctl restart netbox
+```
+
+### Drop Database Tables
+
+!!! note
+    This step is necessary only for plugin which have created one or more database tables (generally through the introduction of new models). Check your plugin's documentation if unsure.
+
+Enter the PostgreSQL database shell to determine if the plugin has created any SQL tables. Substitute `pluginname` in the example below for the name of the plugin being removed. (You can also run the `\dt` command without a pattern to list _all_ tables.)
+
+```no-highlight
+netbox=> \dt pluginname_*
+                   List of relations
+                   List of relations
+ Schema |       Name     | Type  | Owner
+--------+----------------+-------+--------
+ public | pluginname_foo | table | netbox
+ public | pluginname_bar | table | netbox
+(2 rows)
+```
+
+!!! warning
+    Exercise extreme caution when removing tables. Users are strongly encouraged to perform a backup of their database immediately before taking these actions.
+
+Drop each of the listed tables to remove it from the database:
+
+```no-highlight
+netbox=> DROP TABLE pluginname_foo;
+DROP TABLE
+netbox=> DROP TABLE pluginname_bar;
+DROP TABLE
+```

+ 9 - 0
docs/release-notes/version-2.11.md

@@ -1,5 +1,14 @@
 # NetBox v2.11
 
+## v2.11.10 (FUTURE)
+
+### Bug Fixes
+
+* [#5442](https://github.com/netbox-community/netbox/issues/5442) - Fix assignment of permissions based on LDAP groups
+* [#6773](https://github.com/netbox-community/netbox/issues/6773) - Add missing `display` field to rack unit serializer
+
+---
+
 ## v2.11.9 (2021-07-08)
 
 ### Bug Fixes

+ 4 - 0
netbox/dcim/api/serializers.py

@@ -209,6 +209,10 @@ class RackUnitSerializer(serializers.Serializer):
     face = ChoiceField(choices=DeviceFaceChoices, read_only=True)
     device = NestedDeviceSerializer(read_only=True)
     occupied = serializers.BooleanField(read_only=True)
+    display = serializers.SerializerMethodField(read_only=True)
+
+    def get_display(self, obj):
+        return obj['name']
 
 
 class RackReservationSerializer(PrimaryModelSerializer):

+ 9 - 0
netbox/netbox/api/authentication.py

@@ -25,6 +25,15 @@ class TokenAuthentication(authentication.TokenAuthentication):
         if not token.user.is_active:
             raise exceptions.AuthenticationFailed("User inactive")
 
+        # When LDAP authentication is active try to load user data from LDAP directory
+        if settings.REMOTE_AUTH_BACKEND == 'netbox.authentication.LDAPBackend':
+            from netbox.authentication import LDAPBackend
+            ldap_backend = LDAPBackend()
+            user = ldap_backend.populate_user(token.user.username)
+            # If the user is found in the LDAP directory use it, if not fallback to the local user
+            if user:
+                return user, token
+
         return token.user, token
 
 

+ 27 - 5
netbox/netbox/authentication.py

@@ -11,7 +11,7 @@ from users.models import ObjectPermission
 from utilities.permissions import permission_is_exempt, resolve_permission, resolve_permission_ct
 
 
-class ObjectPermissionBackend(ModelBackend):
+class ObjectPermissionMixin():
 
     def get_all_permissions(self, user_obj, obj=None):
         if not user_obj.is_active or user_obj.is_anonymous:
@@ -20,13 +20,16 @@ class ObjectPermissionBackend(ModelBackend):
             user_obj._object_perm_cache = self.get_object_permissions(user_obj)
         return user_obj._object_perm_cache
 
+    def get_permission_filter(self, user_obj):
+        return Q(users=user_obj) | Q(groups__user=user_obj)
+
     def get_object_permissions(self, user_obj):
         """
         Return all permissions granted to the user by an ObjectPermission.
         """
         # Retrieve all assigned and enabled ObjectPermissions
         object_permissions = ObjectPermission.objects.filter(
-            Q(users=user_obj) | Q(groups__user=user_obj),
+            self.get_permission_filter(user_obj),
             enabled=True
         ).prefetch_related('object_types')
 
@@ -86,6 +89,10 @@ class ObjectPermissionBackend(ModelBackend):
         return model.objects.filter(constraints, pk=obj.pk).exists()
 
 
+class ObjectPermissionBackend(ObjectPermissionMixin, ModelBackend):
+    pass
+
+
 class RemoteUserBackend(_RemoteUserBackend):
     """
     Custom implementation of Django's RemoteUserBackend which provides configuration hooks for basic customization.
@@ -133,11 +140,27 @@ class RemoteUserBackend(_RemoteUserBackend):
         return False
 
 
+# Create a new instance of django-auth-ldap's LDAPBackend with our own ObjectPermissions
+try:
+    from django_auth_ldap.backend import LDAPBackend as LDAPBackend_
+
+    class NBLDAPBackend(ObjectPermissionMixin, LDAPBackend_):
+        def get_permission_filter(self, user_obj):
+            permission_filter = super().get_permission_filter(user_obj)
+            if (self.settings.FIND_GROUP_PERMS and
+                    hasattr(user_obj, "ldap_user") and
+                    hasattr(user_obj.ldap_user, "group_names")):
+                permission_filter = permission_filter | Q(groups__name__in=user_obj.ldap_user.group_names)
+            return permission_filter
+except ModuleNotFoundError:
+    pass
+
+
 class LDAPBackend:
 
     def __new__(cls, *args, **kwargs):
         try:
-            from django_auth_ldap.backend import LDAPBackend as LDAPBackend_, LDAPSettings
+            from django_auth_ldap.backend import LDAPSettings
             import ldap
         except ModuleNotFoundError as e:
             if getattr(e, 'name') == 'django_auth_ldap':
@@ -163,8 +186,7 @@ class LDAPBackend:
                 "Required parameter AUTH_LDAP_SERVER_URI is missing from ldap_config.py."
             )
 
-        # Create a new instance of django-auth-ldap's LDAPBackend
-        obj = LDAPBackend_()
+        obj = NBLDAPBackend()
 
         # Read LDAP configuration parameters from ldap_config.py instead of settings.py
         settings = LDAPSettings()