From b63ba4b6360b75ab9e6790094cb2b3ef9038269c Mon Sep 17 00:00:00 2001
From: Matthias Mair <code@mjmair.com>
Date: Tue, 28 Jun 2022 03:26:05 +0200
Subject: [PATCH] [BUG] Duplication of "base URL" setting (#3263)

* [BUG] Duplication of "base URL" setting
Fixes #3196

Adds after_safe key to settings: this action is executed after the setting is saved. The current setting object is supplied to the function as the first argument.

* Add unittests

* fix style

* ammned allowed keys
---
 InvenTree/InvenTree/tests.py | 14 ++++++++++++++
 InvenTree/common/models.py   | 25 +++++++++++++++++++++++++
 InvenTree/common/tests.py    |  1 +
 3 files changed, 40 insertions(+)

diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py
index 07422b98f3..6f9db50ee5 100644
--- a/InvenTree/InvenTree/tests.py
+++ b/InvenTree/InvenTree/tests.py
@@ -9,6 +9,7 @@ from unittest import mock
 import django.core.exceptions as django_exceptions
 from django.conf import settings
 from django.contrib.auth import get_user_model
+from django.contrib.sites.models import Site
 from django.core.exceptions import ValidationError
 from django.test import TestCase, override_settings
 
@@ -604,3 +605,16 @@ class TestInstanceName(helpers.InvenTreeTestCase):
         InvenTreeSetting.set_setting("INVENTREE_INSTANCE", "Testing title", self.user)
 
         self.assertEqual(version.inventreeInstanceTitle(), 'Testing title')
+
+        # The site should also be changed
+        site_obj = Site.objects.all().order_by('id').first()
+        self.assertEqual(site_obj.name, 'Testing title')
+
+    def test_instance_url(self):
+        """Test instance url settings."""
+        # Set up required setting
+        InvenTreeSetting.set_setting("INVENTREE_BASE_URL", "http://127.1.2.3", self.user)
+
+        # The site should also be changed
+        site_obj = Site.objects.all().order_by('id').first()
+        self.assertEqual(site_obj.domain, 'http://127.1.2.3')
diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
index 038972e21a..f38597abe6 100644
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -21,6 +21,7 @@ from django.contrib.auth.models import Group, User
 from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.humanize.templatetags.humanize import naturaltime
+from django.contrib.sites.models import Site
 from django.core.cache import cache
 from django.core.exceptions import AppRegistryNotReady, ValidationError
 from django.core.validators import MinValueValidator, URLValidator
@@ -82,6 +83,14 @@ class BaseInvenTreeSetting(models.Model):
 
         super().save()
 
+        # Get after_save action
+        setting = self.get_setting_definition(self.key, *args, **kwargs)
+        after_save = setting.get('after_save', None)
+
+        # Execute if callable
+        if callable(after_save):
+            after_save(self)
+
     @property
     def cache_key(self):
         """Generate a unique cache key for this settings object"""
@@ -735,6 +744,20 @@ def settings_group_options():
     return [('', _('No group')), *[(str(a.id), str(a)) for a in Group.objects.all()]]
 
 
+def update_instance_url(setting):
+    """Update the first site objects domain to url."""
+    site_obj = Site.objects.all().order_by('id').first()
+    site_obj.domain = setting.value
+    site_obj.save()
+
+
+def update_instance_name(setting):
+    """Update the first site objects name to instance name."""
+    site_obj = Site.objects.all().order_by('id').first()
+    site_obj.name = setting.value
+    site_obj.save()
+
+
 class InvenTreeSetting(BaseInvenTreeSetting):
     """An InvenTreeSetting object is a key:value pair used for storing single values (e.g. one-off settings values).
 
@@ -782,6 +805,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
             'name': _('Server Instance Name'),
             'default': 'InvenTree',
             'description': _('String descriptor for the server instance'),
+            'after_save': update_instance_name,
         },
 
         'INVENTREE_INSTANCE_TITLE': {
@@ -809,6 +833,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
             'description': _('Base URL for server instance'),
             'validator': EmptyURLValidator(),
             'default': '',
+            'after_save': update_instance_url,
         },
 
         'INVENTREE_DEFAULT_CURRENCY': {
diff --git a/InvenTree/common/tests.py b/InvenTree/common/tests.py
index 95268625f6..70d19101ef 100644
--- a/InvenTree/common/tests.py
+++ b/InvenTree/common/tests.py
@@ -133,6 +133,7 @@ class SettingsTest(InvenTreeTestCase):
             'choices',
             'units',
             'requires_restart',
+            'after_save',
         ]
 
         for k in setting.keys():