Skip to content

Commit

Permalink
changes done to add new attribute allowed_ip_addresses to siteprofile…
Browse files Browse the repository at this point in the history
… and validating client ip against it
  • Loading branch information
pratibhavermasalesforce committed Nov 17, 2023
1 parent 20301bb commit d7c4b39
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def safe_key() -> str:
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"metadeploy.multitenancy.middleware.CurrentSiteMiddleware",
"metadeploy.multitenancy.iprestrict_middleware.IPRestrictMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
Expand Down
1 change: 1 addition & 0 deletions metadeploy/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,7 @@ class SiteProfile(TranslatableModel):
show_metadeploy_wordmark = models.BooleanField(default=True)
company_logo = models.ImageField(blank=True)
favicon = models.ImageField(blank=True)
allowed_ip_addresses = models.JSONField(default=list, blank=True, null=True)

@property
def welcome_text_markdown(self):
Expand Down
1 change: 1 addition & 0 deletions metadeploy/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@ class Meta:
"show_metadeploy_wordmark",
"company_logo",
"favicon",
"allowed_ip_addresses",
)


Expand Down
22 changes: 22 additions & 0 deletions metadeploy/multitenancy/iprestrict_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from metadeploy.api.models import SiteProfile
from . import current_site_id
from django.http import HttpResponseForbidden

class IPRestrictMiddleware:
def getSiteProfile(self):
profile = SiteProfile.objects.filter(site=current_site_id()).first()
return profile

def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
client_ip = request.META.get('REMOTE_ADDR', None)
profile = self.getSiteProfile()

if hasattr(profile, "allowed_ip_addresses") and profile.allowed_ip_addresses:
if client_ip not in profile.allowed_ip_addresses:
return HttpResponseForbidden("You don't have permission to access this resource.")

response = self.get_response(request)
return response
70 changes: 70 additions & 0 deletions metadeploy/multitenancy/tests/test_iprestrict_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from metadeploy.multitenancy.iprestrict_middleware import IPRestrictMiddleware
from django.contrib.sites.models import Site
from metadeploy.api.models import SiteProfile
from django.test import RequestFactory, TestCase
from unittest.mock import patch


class IPRestrictionMiddlewaretest(TestCase):
def setUp(self):
self.factory = RequestFactory()

@patch('metadeploy.multitenancy.iprestrict_middleware.IPRestrictMiddleware.getSiteProfile')
def test_ip_restrict_middleware_with_matching_allowed_client_ip(self, mock_site_profile_get):
request = self.factory.get('/test')
request.META["REMOTE_ADDR"] = "127.0.0.1"

site = Site.objects.create(name="Test")
mock_site_profile = SiteProfile()
mock_site_profile.site = site
mock_site_profile.name = site.name
mock_site_profile.allowed_ip_addresses = '["127.0.0.1"]'
mock_site_profile_get.return_value = mock_site_profile

response = IPRestrictMiddleware(lambda x: x)(request)
assert response == request


@patch('metadeploy.multitenancy.iprestrict_middleware.IPRestrictMiddleware.getSiteProfile')
def test_ip_restrict_middleware_without_matching_allowed_client_ip(self, mock_site_profile_get):
request = self.factory.get('/test')
request.META["REMOTE_ADDR"] = "127.0.0.2"

site = Site.objects.create(name="Test")
mock_site_profile = SiteProfile()
mock_site_profile.site = site
mock_site_profile.name = site.name
mock_site_profile.allowed_ip_addresses = '["127.0.0.1"]'
mock_site_profile_get.return_value = mock_site_profile

response = IPRestrictMiddleware(lambda x: x)(request)
assert response.status_code == 403

@patch('metadeploy.multitenancy.iprestrict_middleware.IPRestrictMiddleware.getSiteProfile')
def test_ip_restrict_middleware_without_allowed_list(self, mock_site_profile_get):
request = self.factory.get('/test')
request.META["REMOTE_ADDR"] = "127.0.0.1"

site = Site.objects.create(name="Test")
mock_site_profile = SiteProfile()
mock_site_profile.site = site
mock_site_profile.name = site.name
mock_site_profile_get.return_value = mock_site_profile

response = IPRestrictMiddleware(lambda x: x)(request)
assert response == request

@patch('metadeploy.multitenancy.iprestrict_middleware.IPRestrictMiddleware.getSiteProfile')
def test_ip_restrict_middleware_with_allowed_list_none(self, mock_site_profile_get):
request = self.factory.get('/test')
request.META["REMOTE_ADDR"] = "127.0.0.1"

site = Site.objects.create(name="Test")
mock_site_profile = SiteProfile()
mock_site_profile.site = site
mock_site_profile.name = site.name
mock_site_profile.allowed_ip_addresses = None
mock_site_profile_get.return_value = mock_site_profile

response = IPRestrictMiddleware(lambda x: x)(request)
assert response == request

0 comments on commit d7c4b39

Please sign in to comment.