From cd5db076cead1ee80b50e5b7abde713a28014670 Mon Sep 17 00:00:00 2001 From: Deimos Date: Mon, 11 Mar 2019 01:18:31 -0600 Subject: [PATCH] Add tween to set theme cookie This is mostly motivated by recently enabling the themes from the main Tildes site on the Docs and Blog. To support users maintaining their theme between sites, we need to set the domain field on the cookie, which we weren't doing previously. This tween will automatically convert "old" cookies to "new" ones, but unfortunately there's no way to determine whether their cookie has domain set or not, so we just need to set a new-style cookie every time. This also will start setting the cookie if they don't already have one, but have a default theme set on their account. This is necessary to be able to have the default theme carry over to Docs/Blog. In the future (maybe in a month or so), we can change this so that it only does the default-theme function. --- tildes/tildes/__init__.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tildes/tildes/__init__.py b/tildes/tildes/__init__.py index 42026f7..a64341b 100644 --- a/tildes/tildes/__init__.py +++ b/tildes/tildes/__init__.py @@ -46,6 +46,7 @@ def main(global_config: Dict[str, str], **settings: str) -> PrefixMiddleware: config.add_tween("tildes.http_method_tween_factory") config.add_tween("tildes.metrics_tween_factory") + config.add_tween("tildes.theme_cookie_tween_factory") config.add_static_view("images", "/images") @@ -138,6 +139,38 @@ def metrics_tween_factory(handler: Callable, registry: Registry) -> Callable: return metrics_tween +def theme_cookie_tween_factory(handler: Callable, registry: Registry) -> Callable: + # pylint: disable=unused-argument + """Return a tween function that sets the theme cookie.""" + + def theme_cookie_tween(request: Request) -> Response: + """Set the theme cookie if needed (currently always, see comment below).""" + response = handler(request) + + current_theme = request.cookies.get("theme", "") + if not current_theme and request.user: + current_theme = request.user.theme_default + + # Currently, we want to always set the theme cookie. This is because we + # recently started setting the domain on this cookie (to be able to apply the + # user's theme to the Blog/Docs sites), and all older cookies won't have a + # domain set. This will basically let us convert the old no-domain cookies to + # new ones. After a decent amount of time (maybe sometime in April 2019), we + # can change this to only set the cookie when it's not already present and the + # user has a default theme set (so their default theme will work for Blog/Docs). + if current_theme: + response.set_cookie( + "theme", + current_theme, + max_age=315360000, + secure=True, + domain="." + request.domain, + ) + return response + + return theme_cookie_tween + + def get_redis_connection(request: Request) -> Redis: """Return a connection to the Redis server.""" socket = request.registry.settings["redis.unix_socket_path"]