From d89df448d3e00915eee8c0fc7184b503e8cb7e5e Mon Sep 17 00:00:00 2001
From: autodeploy <benoit@startinblox.com>
Date: Tue, 2 Jul 2024 17:49:15 +0200
Subject: [PATCH] add: ipopenpermission to djangoldp

---
 djangoldp/filters.py     | 10 ++++++++++
 djangoldp/permissions.py | 18 ++++++++++++++++--
 djangoldp/utils.py       | 11 +++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/djangoldp/filters.py b/djangoldp/filters.py
index d568eb34..2c93699e 100644
--- a/djangoldp/filters.py
+++ b/djangoldp/filters.py
@@ -1,6 +1,9 @@
 from django.conf import settings
 from django.db.models import Q
 from rest_framework.filters import BaseFilterBackend
+from djangoldp.utils import check_client_ip
+
+PASSTHROUGH_IPS = getattr(settings, 'PASSTHROUGH_IPS', '')
 
 class OwnerFilterBackend(BaseFilterBackend):
     """Adds the objects owned by the user"""
@@ -133,3 +136,10 @@ class SearchByQueryParamFilterBackend(BaseFilterBackend):
             queryset = queryset.filter(_construct_search_query(search))
 
         return queryset
+
+class IPFilterBackend(BaseFilterBackend):
+    def filter_queryset(self, request, queryset, view):
+        if check_client_ip(request):
+            return queryset
+        else:
+            return queryset.none()
\ No newline at end of file
diff --git a/djangoldp/permissions.py b/djangoldp/permissions.py
index 78f65d19..f236db6c 100644
--- a/djangoldp/permissions.py
+++ b/djangoldp/permissions.py
@@ -4,8 +4,9 @@ from django.http import Http404
 from rest_framework.permissions import BasePermission, DjangoObjectPermissions, OR, AND
 from rest_framework.filters import BaseFilterBackend
 from rest_framework_guardian.filters import ObjectPermissionsFilter
-from djangoldp.filters import OwnerFilterBackend, NoFilterBackend, PublicFilterBackend
-from djangoldp.utils import is_anonymous_user, is_authenticated_user
+from djangoldp.filters import OwnerFilterBackend, NoFilterBackend, PublicFilterBackend, IPFilterBackend
+from djangoldp.utils import is_anonymous_user, is_authenticated_user, check_client_ip
+
 
 DEFAULT_DJANGOLDP_PERMISSIONS = {'view', 'add', 'change', 'delete', 'control'}
 DEFAULT_RESOURCE_PERMISSIONS = {'view', 'change', 'delete', 'control'}
@@ -229,8 +230,21 @@ class JoinMembersPermission(LDPBasePermission):
         new_ids = {user['@id'] for user in new_members}
         old_ids = {user.urlid for user in obj.members.user_set.all()}
         return self.check_patch(new_ids, old_ids, request.user) and self.check_patch(old_ids, new_ids, request.user)
+
+    def get_permissions(self, user, model, obj=None):
+        return set()
+
+
+class IPOpenPermissions(LDPBasePermission):
+    filter_backend = IPFilterBackend
+    def has_permission(self, request, view):
+        return check_client_ip(request)
+
+    def has_object_permission(self, request, view, obj):
+        return check_client_ip(request)
     
     def get_permissions(self, user, model, obj=None):
+        #Will always say there is no migrations, not taking the IP into accounts
         return set()
 
 
diff --git a/djangoldp/utils.py b/djangoldp/utils.py
index a32ac615..4413252b 100644
--- a/djangoldp/utils.py
+++ b/djangoldp/utils.py
@@ -12,3 +12,14 @@ def is_anonymous_user(user):
 def is_authenticated_user(user):
     anonymous_username = getattr(settings, 'ANONYMOUS_USER_NAME', None)
     return user.is_authenticated and user.username != anonymous_username
+
+
+# this method is used to check if a given IP is part of the PASSTHROUGH_IPS list
+def check_client_ip(request):
+    x_forwarded_for = request.headers.get('x-forwarded-for')
+    if x_forwarded_for:
+        if any(ip in x_forwarded_for.replace(' ', '').split(',') for ip in PASSTHROUGH_IPS):
+            return True
+    elif request.META.get('REMOTE_ADDR') in PASSTHROUGH_IPS:
+        return True
+    return False
-- 
GitLab