~linuxgoose/bocpress

ref: 173992755765eadcdc6d2a0a95a8d94f64c249b2 bocpress/main/middleware.py -rw-r--r-- 5.3 KiB
17399275Jordan Robinson fix middleware 8 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
from timeit import default_timer as timer

from django.conf import settings
from django.http import Http404, HttpResponseBadRequest
from django.shortcuts import redirect

from main import denylist, models, scheme


def host_middleware(get_response):
    def middleware(request):
        host = request.META.get("HTTP_HOST")

        # no http Host header in testing
        if not host:
            return get_response(request)
        
        # allow localhost for webhooks in local development
        if host.startswith("localhost:") or host.startswith("127.0.0.1:"):
            return get_response(request)

        # allow localhost for webhooks and Caddy on-demand TLS validation
        if (host.startswith("localhost:") or host.startswith("127.0.0.1:")) and (
            request.path.startswith("/webhook/")
            or request.path.startswith("/accounts/domain/")
        ):
            return get_response(request)

        host_parts = host.split(".")
        canonical_parts = settings.CANONICAL_HOST.split(".")

        if host == settings.CANONICAL_HOST:
            # this case is for bocpress.co.uk landing and dashboard pages
            # * don't set request.subdomain
            # * set theme if logged in
            # * return immediately
            if request.user.is_authenticated:
                request.theme_zialucia = request.user.theme_zialucia
                request.theme_sansserif = request.user.theme_sansserif
            return get_response(request)
        elif (
            len(host_parts) == 4
            and host_parts[1] == canonical_parts[0]  # should be "bocpress"
            and host_parts[2] == canonical_parts[1]  # should be "co"
            and host_parts[3] == canonical_parts[2]  # should be "uk"
        ):
            # this case is for <subdomain>.bocpress.co.uk:
            # * set subdomain to given subdomain
            # * the lists indexes are different because CANONICAL_HOST has no subdomain
            # * also validation will happen inside views
            request.subdomain = host_parts[0]

            allow_docs_user = False
            if request.subdomain == "docs" and settings.ALLOW_DOCS_USER:
                allow_docs_user = True

            # check if subdomain is disallowed
            if request.subdomain in denylist.DISALLOWED_USERNAMES:
                return redirect(f"{scheme.get_protocol()}//{settings.CANONICAL_HOST}")
            # check if subdomain exists as blog
            elif models.User.objects.filter(username=request.subdomain).exists():
                request.blog_user = models.User.objects.get(username=request.subdomain)

                # set theme
                request.theme_zialucia = request.blog_user.theme_zialucia
                request.theme_sansserif = request.blog_user.theme_sansserif

                # redirect to custom and/or retired urls for cases:
                # * logged out / anon users
                # * logged in but on other user's subdomain
                if not request.user.is_authenticated or (
                    request.user.is_authenticated
                    and request.user.username != request.subdomain
                ):
                    redir_domain = ""
                    if request.blog_user.custom_domain:  # user has set custom domain
                        redir_domain = (
                            request.blog_user.custom_domain + request.path_info
                        )

                    # user has retired their bocpress blog, redirect to new domain
                    if request.blog_user.redirect_domain:
                        redir_domain = (
                            request.blog_user.redirect_domain + request.path_info[5:]
                        )

                    # if there is no protocol prefix,
                    # prepend double slashes to indicate other domain
                    if redir_domain and "://" not in redir_domain:
                        redir_domain = "//" + redir_domain

                    if redir_domain:
                        return redirect(redir_domain)
            else:
                raise Http404()
        elif models.User.objects.filter(custom_domain=host).exists():
            # custom domain case
            request.blog_user = models.User.objects.get(custom_domain=host)
            request.subdomain = request.blog_user.username
            request.theme_zialucia = request.blog_user.theme_zialucia
            request.theme_sansserif = request.blog_user.theme_sansserif

            # if user has retired their bocpress blog (and keeps the custom domain)
            # redirect to new domain
            if request.blog_user.redirect_domain:
                redir_domain = request.blog_user.redirect_domain + request.path_info[5:]

                # if there is no protocol prefix,
                # prepend double slashes to indicate other domain
                if "://" not in redir_domain:
                    redir_domain = "//" + redir_domain

                return redirect(redir_domain)

        else:
            return HttpResponseBadRequest()

        return get_response(request)

    return middleware


def speed_middleware(get_response):
    def middleware(request):
        request.start = timer()

        response = get_response(request)

        end = timer()
        response["X-Request-Time"] = end - request.start
        return response

    return middleware