forked from MirrorHub/synapse
Check jinja version for consent resource (#4327)
* Raise a ConfigError if an invalid resource is specified * Require Jinja 2.9 for the consent resource * changelog
This commit is contained in:
parent
a27e501b09
commit
b7c0218812
4 changed files with 74 additions and 27 deletions
1
changelog.d/4327.bugfix
Normal file
1
changelog.d/4327.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Check jinja version for consent resource
|
|
@ -19,15 +19,8 @@ from synapse import python_dependencies # noqa: E402
|
||||||
|
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
python_dependencies.check_requirements()
|
python_dependencies.check_requirements()
|
||||||
except python_dependencies.DependencyException as e:
|
except python_dependencies.DependencyException as e:
|
||||||
message = "\n".join([
|
sys.stderr.writelines(e.message)
|
||||||
"Missing Requirements: %s" % (", ".join(e.dependencies),),
|
|
||||||
"To install run:",
|
|
||||||
" pip install --upgrade --force %s" % (" ".join(e.dependencies),),
|
|
||||||
"",
|
|
||||||
])
|
|
||||||
sys.stderr.writelines(message)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright 2014-2016 OpenMarket Ltd
|
# 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");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -18,6 +18,7 @@ import logging
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from synapse.http.endpoint import parse_and_validate_server_name
|
from synapse.http.endpoint import parse_and_validate_server_name
|
||||||
|
from synapse.python_dependencies import DependencyException, check_requirements
|
||||||
|
|
||||||
from ._base import Config, ConfigError
|
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):
|
def default_config(self, server_name, data_dir_path, **kwargs):
|
||||||
_, bind_port = parse_and_validate_server_name(server_name)
|
_, bind_port = parse_and_validate_server_name(server_name)
|
||||||
if bind_port is not None:
|
if bind_port is not None:
|
||||||
|
@ -465,3 +468,36 @@ def _warn_if_webclient_configured(listeners):
|
||||||
if name == 'webclient':
|
if name == 'webclient':
|
||||||
logger.warning(NO_MORE_WEB_CLIENT_WARNING)
|
logger.warning(NO_MORE_WEB_CLIENT_WARNING)
|
||||||
return
|
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)
|
||||||
|
|
|
@ -65,9 +65,13 @@ REQUIREMENTS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
CONDITIONAL_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"],
|
"matrix-synapse-ldap3": ["matrix-synapse-ldap3>=0.1"],
|
||||||
"postgres": ["psycopg2>=2.6"],
|
"postgres": ["psycopg2>=2.6"],
|
||||||
|
|
||||||
|
# ConsentResource uses select_autoescape, which arrived in jinja 2.9
|
||||||
|
"resources.consent": ["Jinja2>=2.9"],
|
||||||
|
|
||||||
"saml2": ["pysaml2>=4.5.0"],
|
"saml2": ["pysaml2>=4.5.0"],
|
||||||
"url_preview": ["lxml>=3.5.0"],
|
"url_preview": ["lxml>=3.5.0"],
|
||||||
"test": ["mock>=2.0"],
|
"test": ["mock>=2.0"],
|
||||||
|
@ -83,19 +87,31 @@ def list_requirements():
|
||||||
|
|
||||||
|
|
||||||
class DependencyException(Exception):
|
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
|
@property
|
||||||
def dependencies(self):
|
def dependencies(self):
|
||||||
for i in self.args[0]:
|
for i in self.args[0]:
|
||||||
yield '"' + i + '"'
|
yield '"' + i + '"'
|
||||||
|
|
||||||
|
|
||||||
def check_requirements(_get_distribution=get_distribution):
|
def check_requirements(for_feature=None, _get_distribution=get_distribution):
|
||||||
|
|
||||||
deps_needed = []
|
deps_needed = []
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
# Check the base dependencies exist -- they all must be installed.
|
if for_feature:
|
||||||
for dependency in REQUIREMENTS:
|
reqs = CONDITIONAL_REQUIREMENTS[for_feature]
|
||||||
|
else:
|
||||||
|
reqs = REQUIREMENTS
|
||||||
|
|
||||||
|
for dependency in reqs:
|
||||||
try:
|
try:
|
||||||
_get_distribution(dependency)
|
_get_distribution(dependency)
|
||||||
except VersionConflict as e:
|
except VersionConflict as e:
|
||||||
|
@ -108,23 +124,24 @@ def check_requirements(_get_distribution=get_distribution):
|
||||||
deps_needed.append(dependency)
|
deps_needed.append(dependency)
|
||||||
errors.append("Needed %s but it was not installed" % (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
|
if not for_feature:
|
||||||
# installed.
|
# Check the optional dependencies are up to date. We allow them to not be
|
||||||
OPTS = sum(CONDITIONAL_REQUIREMENTS.values(), [])
|
# installed.
|
||||||
|
OPTS = sum(CONDITIONAL_REQUIREMENTS.values(), [])
|
||||||
|
|
||||||
for dependency in OPTS:
|
for dependency in OPTS:
|
||||||
try:
|
try:
|
||||||
_get_distribution(dependency)
|
_get_distribution(dependency)
|
||||||
except VersionConflict:
|
except VersionConflict:
|
||||||
deps_needed.append(dependency)
|
deps_needed.append(dependency)
|
||||||
errors.append("Needed %s but it was not installed" % (dependency,))
|
errors.append("Needed %s but it was not installed" % (dependency,))
|
||||||
except DistributionNotFound:
|
except DistributionNotFound:
|
||||||
# If it's not found, we don't care
|
# If it's not found, we don't care
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if deps_needed:
|
if deps_needed:
|
||||||
for e in errors:
|
for e in errors:
|
||||||
logging.exception(e)
|
logging.error(e)
|
||||||
|
|
||||||
raise DependencyException(deps_needed)
|
raise DependencyException(deps_needed)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue