diff --git a/CHANGES.rst b/CHANGES.rst index 62e3a6c9274b1f4ca0c8cfa4a62abb096e8e7f88..dd8daae8075104cd8a1b795428151a2ce328f3fc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,12 @@ Changes ======= + +Version 2025.1.1 (released 2025-02-04) + +- Override `Flask.create_url_adapter()` to match v3.1 regarding `SERVER_NAME` + + Version 2025.1.0 (released 2025-01-31) - Add `Invenio-Curations` as a dependency diff --git a/invenio_config_tuw/__init__.py b/invenio_config_tuw/__init__.py index 300d048a61bc7ed3c888286fad327b6521f8b5fe..0e0113e1397dffca74c8b82c04f9eb1da2668034 100644 --- a/invenio_config_tuw/__init__.py +++ b/invenio_config_tuw/__init__.py @@ -9,6 +9,6 @@ from .ext import InvenioConfigTUW -__version__ = "2025.1.0" +__version__ = "2025.1.1" __all__ = ("__version__", "InvenioConfigTUW") diff --git a/invenio_config_tuw/startup.py b/invenio_config_tuw/startup.py index 03c5677202dc9f986fd4db3f3d4359aa779c0ee3..4fa84a41b32b3397ebfcb06abe4fc40abbab406f 100644 --- a/invenio_config_tuw/startup.py +++ b/invenio_config_tuw/startup.py @@ -16,6 +16,7 @@ initialized, and thus we can rely on them being already available. from logging import ERROR from logging.handlers import SMTPHandler +import importlib_metadata from invenio_rdm_records.services.search_params import MyDraftsParam from invenio_requests.proxies import current_request_type_registry @@ -106,3 +107,56 @@ def register_menu_entries(app): def customize_curation_request_type(app): """Override the rdm-curations request type with our own version.""" current_request_type_registry.register_type(TUWCurationRequest(), force=True) + + +def patch_flask_create_url_adapter(app): + """Patch Flask's {host,subdomain}_matching with 3.1 behavior. + + See: https://github.com/pallets/flask/pull/5634 + + This can be removed once we get Flask 3.1+ in. + """ + flask_version = importlib_metadata.version("flask").split(".", 2) + major = int(flask_version[0]) + minor = int(flask_version[1]) + if (major == 3 and minor >= 1) or (major > 3): + app.logger.info( + f"Flask version is {flask_version} (>= 3.1). " + "Skipping monkey patching app.create_url_adapter()." + ) + return + + def create_url_adapter(self, request): + """Create a URL adapter for the given request. + + This function is from Flask 3.1, which is licensed under the 3-clause BSD. + """ + if request is not None: + subdomain = None + server_name = self.config["SERVER_NAME"] + + if self.url_map.host_matching: + # Don't pass SERVER_NAME, otherwise it's used and the actual + # host is ignored, which breaks host matching. + server_name = None + elif not self.subdomain_matching: + # Werkzeug doesn't implement subdomain matching yet. Until then, + # disable it by forcing the current subdomain to the default, or + # the empty string. + subdomain = self.url_map.default_subdomain or "" + + return self.url_map.bind_to_environ( + request.environ, server_name=server_name, subdomain=subdomain + ) + + # Need at least SERVER_NAME to match/build outside a request. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + app.create_url_adapter = create_url_adapter.__get__(app, type(app)) diff --git a/pyproject.toml b/pyproject.toml index a754736ddf5dab89fdfe2ba9ed8f6b82e880a65e..e3e12dabc32de84686bda4e7f85270dbc9a43c7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,11 +81,13 @@ invenio_config_tuw_mail_handler = "invenio_config_tuw.startup:register_smtp_erro invenio_config_tuw_search_drafts = "invenio_config_tuw.startup:override_search_drafts_options" invenio_config_tuw_curation_settings = "invenio_config_tuw.startup:register_menu_entries" invenio_config_tuw_curation_request = "invenio_config_tuw.startup:customize_curation_request_type" +invenio_config_tuw_patch_flask = "invenio_config_tuw.startup:patch_flask_create_url_adapter" [project.entry-points."invenio_base.api_finalize_app"] invenio_config_tuw_mail_handler = "invenio_config_tuw.startup:register_smtp_error_handler" invenio_config_tuw_search_drafts = "invenio_config_tuw.startup:override_search_drafts_options" invenio_config_tuw_curation_request = "invenio_config_tuw.startup:customize_curation_request_type" +invenio_config_tuw_patch_flask = "invenio_config_tuw.startup:patch_flask_create_url_adapter" [project.entry-points."invenio_celery.tasks"] invenio_config_tuw = "invenio_config_tuw.tasks"