Changeset - 5fa226284bcb
[Not reviewed]
1 7 0
Ben Sturmfels (bsturmfels) - 2 months ago 2024-03-20 03:54:54
ben@sturm.com.au
Delegate management of canonical URLs to Apache

This middleware is mostly redundant:

* redirecting to canonical URLs can be done more simply in Apache
* appending a forward slash is a default in CommonMiddleware now
* we're no longer using Squid cache

May need to update Apache to strip/redirect trailing "index.html".
8 files changed with 4 insertions and 85 deletions:
0 comments (0 inline, 0 general)
TODO.md
Show inline comments
 
# To-do
 

	
 
* remove `ForceCanonicalHostnameMiddleware` by ensuring canonical redirect and HTTPS redirect is done by Apache
 
* ask Denver about why so many license files
 
* serve a 400 in Apache for a hostname we don't explicitly support
 
* use `<detail>` elements for supporter page hidden sections, rather than complex jQuery - or consider Alpine.js
 
* replace `internalNavigate` with inline flexbox layout
 
* add tests for main pages returning 200
 

	
 

	
 
# Done
 

	
 
* remove `ForceCanonicalHostnameMiddleware` by ensuring canonical redirect and HTTPS redirect is done by Apache
 
* standardise settings to replace `settings.py` and `djangocommonsettings.py`
 
  with `settings/prod.py` and move `SECRET_KEY` to an environment variable
 
* migrate to Django 4.2 LTS
 
* review `apache2` directory - may be unused
 
* add deployment script that runs migrations and collects static files
 
* switch `ParameterValidator` to use `SECRET_KEY` if possible to minimize
 
  non-standard settings
 
* install staticfiles app
conservancy/blog/views.py
Show inline comments
...
 
@@ -105,29 +105,26 @@ def query(request):
 

	
 
        return relative_redirect(request, '{}{}{}'.format(base_url, '?' if query_string else '', query_string))
 

	
 
    else:
 
        authors = sorted(Person.objects.filter(currently_employed=True,
 
                                               entry__isnull=False).distinct(),
 
                         key=last_name)
 
        tags = EntryTag.objects.all().order_by('label')
 
        return render(request, 'blog/query.html', {'authors': authors, 'tags': tags})
 

	
 
def relative_redirect(request, path):
 
    from django import http
 
    from django.conf import settings
 

	
 
    host = request.get_host()
 
    if settings.FORCE_CANONICAL_HOSTNAME:
 
        host = settings.FORCE_CANONICAL_HOSTNAME
 

	
 
    url = "{}://{}{}".format(request.is_secure() and 'https' or 'http', host, path)
 
    return http.HttpResponseRedirect(url)
 

	
 
class BlogYearArchiveView(YearArchiveView):
 
    make_object_list = True
 
    allow_future = True
 
    extra_context = {}
 
    
 
    def get_context_data(self, **kwargs):
 
        context = super().get_context_data(**kwargs)
 
        context.update(self.extra_context)
conservancy/local_context_processors.py
Show inline comments
 
from datetime import datetime as DateTime
 

	
 
from django.conf import settings
 

	
 
from .fundgoal.models import FundraisingGoal
 

	
 
SITE_FUNDGOAL = 'cy2023-end-year-match'
 

	
 
def fundgoal_lookup(fundraiser_sought):
 
    try:
 
        return FundraisingGoal.objects.get(fundraiser_code_name=fundraiser_sought)
 
    except FundraisingGoal.DoesNotExist:
 
        # we have no object!  do something
 
        return None
 

	
 
def sitefundraiser(request):
 
    return {
 
        'datetime_now': DateTime.now(),
 
        'sitefundgoal': fundgoal_lookup(SITE_FUNDGOAL),
 
    }
 

	
 
if settings.FORCE_CANONICAL_HOSTNAME:
 
    _HOST_URL_VAR = {'host_url': 'https://' + settings.FORCE_CANONICAL_HOSTNAME}
 
    def host_url(request):
 
        return _HOST_URL_VAR
 
else:
 
    def host_url(request):
 
        return {'host_url': request.build_absolute_uri('/').rstrip('/')}
 
def host_url(request):
 
    return {'host_url': request.build_absolute_uri('/').rstrip('/')}
conservancy/middleware.py
Show inline comments
 
deleted file
conservancy/podjango/views.py
Show inline comments
...
 
@@ -96,20 +96,17 @@ def query(request):
 

	
 
        query_string = d.urlencode()
 

	
 
        return relative_redirect(request, '%s%s%s' % (base_url, '?' if query_string else '', query_string))
 

	
 
    else:
 
        tags = CastTag.objects.all().order_by('label')
 
        return render(request, 'podjango/cast/query.html', {'tags': tags})
 

	
 

	
 
def relative_redirect(request, path):
 
    from django import http
 
    from django.conf import settings
 

	
 
    host = http.get_host(request)
 
    if settings.FORCE_CANONICAL_HOSTNAME:
 
        host = settings.FORCE_CANONICAL_HOSTNAME
 

	
 
    url = "%s://%s%s" % (request.is_secure() and 'https' or 'http', host, path)
 
    return http.HttpResponseRedirect(url)
conservancy/settings/base.py
Show inline comments
...
 
@@ -13,28 +13,24 @@
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
 
# General Public License for more details.
 
#
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program in a file in the toplevel directory called
 
# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from pathlib import Path
 

	
 
SITE_ID = 2
 
ROOT_URLCONF = 'conservancy.urls'
 

	
 
REDIRECT_TABLE = {
 
    'www.sf-conservancy.org': 'sfconservancy.org',
 
}
 

	
 
LOGGING = {
 
    'version': 1,
 
    'disable_existing_loggers': False,
 
    'formatters': {
 
        'default': {
 
            'format': '%(asctime)s %(levelname)s %(name)s: %(message)s',
 
            'datefmt': '%Y-%m-%d %H:%M:%S',
 
        },
 
    },
 
    'filters': {
 
        'require_debug_false': {
 
            '()': 'django.utils.log.RequireDebugFalse'
...
 
@@ -127,19 +123,18 @@ STATIC_URL = '/static/'
 
STATIC_ROOT = BASE_DIR.parent / 'collected_static'
 
STATICFILES_DIRS = [
 
    BASE_DIR / 'static',
 
]
 

	
 
MEDIA_URL = '/media/'
 

	
 
MIDDLEWARE = [
 
    'django.middleware.common.CommonMiddleware',
 
    'django.contrib.sessions.middleware.SessionMiddleware',
 
    'django.contrib.auth.middleware.AuthenticationMiddleware',
 
    'django.contrib.messages.middleware.MessageMiddleware',
 
    'conservancy.middleware.ForceCanonicalHostnameMiddleware',
 
]
 

	
 
USETHESOURCE = {
 
    'SENDER': 'compliance@sfconservancy.org',
 
    'LIST_RECIPIENT': 'ccs-review@lists.sfconservancy.org',
 
}
conservancy/settings/dev.py
Show inline comments
 
from .base import *
 

	
 
DEBUG = True
 
ALLOWED_HOSTS = ['*']
 

	
 
FORCE_CANONICAL_HOSTNAME = False
 

	
 
DATABASES = {
 
    'default': {
 
        'NAME': 'conservancy-website.sqlite3',
 
        'ENGINE': 'django.db.backends.sqlite3',
 
    }
 
}
 

	
 
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
 

	
 
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
conservancy/settings/prod.py
Show inline comments
 
import json
 

	
 
from django.core.exceptions import ImproperlyConfigured
 

	
 
from .base import *
 

	
 
DEBUG = False
 
ALLOWED_HOSTS = ['www.sfconservancy.org', 'sfconservancy.org']
 

	
 
FORCE_CANONICAL_HOSTNAME = 'sfconservancy.org'
 

	
 
ADMINS = [
 
    ('Bradley M. Kuhn', 'sysadmin@sfconservancy.org'),
 
    ('Ben Sturmfels', 'sysadmin+conservancy@sturm.com.au'),
 
]
 

	
 
MANAGERS = [
 
    ('Bradley M. Kuhn', 'sysadmin@sfconservancy.org'),
 
]
 

	
 
DATABASES = {
 
    'default': {
 
        'NAME': '/var/lib/www/database/conservancy-website.sqlite3',
0 comments (0 inline, 0 general)