diff --git a/changelog.d/4327.bugfix b/changelog.d/4327.bugfix
new file mode 100644
index 0000000000..03bf05e05c
--- /dev/null
+++ b/changelog.d/4327.bugfix
@@ -0,0 +1 @@
+Check jinja version for consent resource
diff --git a/synapse/app/__init__.py b/synapse/app/__init__.py
index 233bf43fc8..b45adafdd3 100644
--- a/synapse/app/__init__.py
+++ b/synapse/app/__init__.py
@@ -19,15 +19,8 @@ from synapse import python_dependencies # noqa: E402
sys.dont_write_bytecode = True
-
try:
python_dependencies.check_requirements()
except python_dependencies.DependencyException as e:
- message = "\n".join([
- "Missing Requirements: %s" % (", ".join(e.dependencies),),
- "To install run:",
- " pip install --upgrade --force %s" % (" ".join(e.dependencies),),
- "",
- ])
- sys.stderr.writelines(message)
+ sys.stderr.writelines(e.message)
sys.exit(1)
diff --git a/synapse/config/server.py b/synapse/config/server.py
index 120c2b81fc..fb57791098 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2014-2016 OpenMarket Ltd
-# Copyright 2017 New Vector Ltd
+# Copyright 2017-2018 New Vector Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ import logging
import os.path
from synapse.http.endpoint import parse_and_validate_server_name
+from synapse.python_dependencies import DependencyException, check_requirements
from ._base import Config, ConfigError
@@ -204,6 +205,8 @@ class ServerConfig(Config):
]
})
+ _check_resource_config(self.listeners)
+
def default_config(self, server_name, data_dir_path, **kwargs):
_, bind_port = parse_and_validate_server_name(server_name)
if bind_port is not None:
@@ -465,3 +468,36 @@ def _warn_if_webclient_configured(listeners):
if name == 'webclient':
logger.warning(NO_MORE_WEB_CLIENT_WARNING)
return
+
+
+KNOWN_RESOURCES = (
+ 'client',
+ 'consent',
+ 'federation',
+ 'keys',
+ 'media',
+ 'metrics',
+ 'replication',
+ 'static',
+ 'webclient',
+)
+
+
+def _check_resource_config(listeners):
+ resource_names = set(
+ res_name
+ for listener in listeners
+ for res in listener.get("resources", [])
+ for res_name in res.get("names", [])
+ )
+
+ for resource in resource_names:
+ if resource not in KNOWN_RESOURCES:
+ raise ConfigError(
+ "Unknown listener resource '%s'" % (resource, )
+ )
+ if resource == "consent":
+ try:
+ check_requirements('resources.consent')
+ except DependencyException as e:
+ raise ConfigError(e.message)
diff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py
index 2c65ef5856..69c5f9fe2e 100644
--- a/synapse/python_dependencies.py
+++ b/synapse/python_dependencies.py
@@ -65,9 +65,13 @@ REQUIREMENTS = [
]
CONDITIONAL_REQUIREMENTS = {
- "email.enable_notifs": ["Jinja2>=2.8", "bleach>=1.4.2"],
+ "email.enable_notifs": ["Jinja2>=2.9", "bleach>=1.4.2"],
"matrix-synapse-ldap3": ["matrix-synapse-ldap3>=0.1"],
"postgres": ["psycopg2>=2.6"],
+
+ # ConsentResource uses select_autoescape, which arrived in jinja 2.9
+ "resources.consent": ["Jinja2>=2.9"],
+
"saml2": ["pysaml2>=4.5.0"],
"url_preview": ["lxml>=3.5.0"],
"test": ["mock>=2.0"],
@@ -84,18 +88,30 @@ def list_requirements():
class DependencyException(Exception):
@property
+ def message(self):
+ return "\n".join([
+ "Missing Requirements: %s" % (", ".join(self.dependencies),),
+ "To install run:",
+ " pip install --upgrade --force %s" % (" ".join(self.dependencies),),
+ "",
+ ])
+
+ @property
def dependencies(self):
for i in self.args[0]:
yield '"' + i + '"'
-def check_requirements(_get_distribution=get_distribution):
-
+def check_requirements(for_feature=None, _get_distribution=get_distribution):
deps_needed = []
errors = []
- # Check the base dependencies exist -- they all must be installed.
- for dependency in REQUIREMENTS:
+ if for_feature:
+ reqs = CONDITIONAL_REQUIREMENTS[for_feature]
+ else:
+ reqs = REQUIREMENTS
+
+ for dependency in reqs:
try:
_get_distribution(dependency)
except VersionConflict as e:
@@ -108,23 +124,24 @@ def check_requirements(_get_distribution=get_distribution):
deps_needed.append(dependency)
errors.append("Needed %s but it was not installed" % (dependency,))
- # Check the optional dependencies are up to date. We allow them to not be
- # installed.
- OPTS = sum(CONDITIONAL_REQUIREMENTS.values(), [])
-
- for dependency in OPTS:
- try:
- _get_distribution(dependency)
- except VersionConflict:
- deps_needed.append(dependency)
- errors.append("Needed %s but it was not installed" % (dependency,))
- except DistributionNotFound:
- # If it's not found, we don't care
- pass
+ if not for_feature:
+ # Check the optional dependencies are up to date. We allow them to not be
+ # installed.
+ OPTS = sum(CONDITIONAL_REQUIREMENTS.values(), [])
+
+ for dependency in OPTS:
+ try:
+ _get_distribution(dependency)
+ except VersionConflict:
+ deps_needed.append(dependency)
+ errors.append("Needed %s but it was not installed" % (dependency,))
+ except DistributionNotFound:
+ # If it's not found, we don't care
+ pass
if deps_needed:
for e in errors:
- logging.exception(e)
+ logging.error(e)
raise DependencyException(deps_needed)
|