Repository: mozilla/kitsune

Issue:
Redirect support.mozilla.com to support.mozilla.org



Discussion:
https://bugzilla.mozilla.org/show_bug.cgi?id=1428134
How do we plan to make this redirect? @metadave can you do this on the k8s level?
We talked a bit more in the meeting and decided to do it via a middleware in kitsune itself. This has a few benefits:

* Nothing else to run and monitor
* No need to make sure one is running in any other region
* It's fairly trivial to write as a Django Middleware

I'll see if I can knock it out soon.
I believe we can just use [this app](https://github.com/dabapps/django-enforce-host). I have a middleware I've used in another project, but this is basically that and just installable. 
Re-opening. As far as I can tell this is currently not working.
Indeed it is not. Thanks Ben. I'll investigate.
it looks like we never set the `ENFORCE_HOST` setting: https://github.com/mozilla/kitsune/commit/289a400abffd44937c884dca7f6ef409cb7abaa0#diff-1b868c345b3f49304922084d892d74caR1046

Resolving patch:
diff --git a/kitsune/settings.py b/kitsune/settings.py
--- a/kitsune/settings.py
+++ b/kitsune/settings.py
@@ -495,7 +495,7 @@ def parse_conn_max_age(value):
     'multidb.middleware.PinningRouterMiddleware',
     'django_statsd.middleware.GraphiteMiddleware',
     'commonware.request.middleware.SetRemoteAddrFromForwardedFor',
-    'enforce_host.EnforceHostMiddleware',
+    'kitsune.sumo.middleware.EnforceHostIPMiddleware',
 
     # VaryNoCacheMiddleware must be above LocaleURLMiddleware
     # so that it can see the response has a vary on accept-language
diff --git a/kitsune/sumo/middleware.py b/kitsune/sumo/middleware.py
--- a/kitsune/sumo/middleware.py
+++ b/kitsune/sumo/middleware.py
@@ -7,9 +7,11 @@
 from django.contrib import messages
 from django.core.exceptions import MiddlewareNotUsed
 from django.core.urlresolvers import is_valid_path
+from django.core.validators import validate_ipv4_address, ValidationError
 from django.db.utils import DatabaseError
 from django.http import (HttpResponse, HttpResponseRedirect,
                          HttpResponsePermanentRedirect, HttpResponseForbidden)
+from django.http.request import split_domain_port
 from django.shortcuts import render
 from django.utils import translation
 from django.utils.cache import add_never_cache_headers, patch_response_headers, patch_vary_headers
@@ -17,6 +19,7 @@
 
 import mobility
 from mozilla_django_oidc.middleware import RefreshIDToken
+from enforce_host import EnforceHostMiddleware
 
 from kitsune.sumo.templatetags.jinja_helpers import urlparams
 from kitsune.sumo.urlresolvers import Prefixer, set_url_prefixer, split_path
@@ -29,6 +32,21 @@
     MiddlewareMixin = object
 
 
+class EnforceHostIPMiddleware(EnforceHostMiddleware):
+    """Modify the `EnforceHostMiddleware` to allow IP addresses"""
+    def process_request(self, request):
+        host = request.get_host()
+        domain, port = split_domain_port(host)
+        try:
+            validate_ipv4_address(domain)
+        except ValidationError:
+            # not an IP address. Call the superclass
+            return super(EnforceHostIPMiddleware, self).process_request(request)
+
+        # it is an IP address
+        return
+
+
 class HttpResponseRateLimited(HttpResponse):
     status_code = 429
 


Test patch:
diff --git a/kitsune/sumo/tests/test_middleware.py b/kitsune/sumo/tests/test_middleware.py
--- a/kitsune/sumo/tests/test_middleware.py
+++ b/kitsune/sumo/tests/test_middleware.py
@@ -9,10 +9,34 @@
     PlusToSpaceMiddleware,
     DetectMobileMiddleware,
     CacheHeadersMiddleware,
+    EnforceHostIPMiddleware,
 )
 from kitsune.sumo.tests import TestCase, PyQuery as pq
 
 
+@override_settings(ENFORCE_HOST=['support.mozilla.org', 'all-your-base.are-belong-to.us'])
+class EnforceHostIPMiddlewareTestCase(TestCase):
+    def _get_response(self, hostname):
+        mw = EnforceHostIPMiddleware()
+        rf = RequestFactory()
+        return mw.process_request(rf.get('/', HTTP_HOST=hostname))
+
+    def test_valid_domain(self):
+        resp = self._get_response('support.mozilla.org')
+        self.assertIsNone(resp)
+
+    def test_valid_ip_address(self):
+        resp = self._get_response('192.168.200.200')
+        self.assertIsNone(resp)
+        # with port
+        resp = self._get_response('192.168.200.200:443')
+        self.assertIsNone(resp)
+
+    def test_invalid_domain(self):
+        resp = self._get_response('none-of-ur-base.are-belong-to.us')
+        assert isinstance(resp, HttpResponsePermanentRedirect)
+
+
 class CacheHeadersMiddlewareTestCase(TestCase):
     def setUp(self):
         self.rf = RequestFactory()