From d517fb6ff5b174699e5820df65d6d755c602b940 Mon Sep 17 00:00:00 2001 From: Ralph Seichter Date: Thu, 19 May 2022 19:59:32 +0200 Subject: [PATCH] Fix content type verification Request content type verification now works if additional parameters like "charset" are passed. --- CHANGELOG | 3 ++- automx2/__init__.py | 2 +- automx2/views/__init__.py | 11 +++++++---- automx2/views/autodiscover.py | 5 ++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c7b80b9..1e57c8b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -27,5 +27,6 @@ 2021.6 (2021-12-17): Introduce "Encryption" element (see MS-OXDSCLI v20210817) in Autodiscover generator to better support server connections which require the use of STARTTLS. -2022.0 (2022-12-31): Simplified database initialisation is now possible via HTTP POST and a JSON payload. +2022.0 (2022-03-31): Simplified database initialisation is now possible via HTTP POST and a JSON payload. +2022.1 (2022-05-19): Request content type verification now works if additional parameters like "charset" are passed. diff --git a/automx2/__init__.py b/automx2/__init__.py index 896ac09..18fe09f 100644 --- a/automx2/__init__.py +++ b/automx2/__init__.py @@ -19,7 +19,7 @@ import logging IDENTIFIER = 'automx2' # Do not change this! -VERSION = '2022.0' +VERSION = '2022.1' PLACEHOLDER_ADDRESS = r'%EMAILADDRESS%' PLACEHOLDER_DOMAIN = r'%EMAILDOMAIN%' diff --git a/automx2/views/__init__.py b/automx2/views/__init__.py index 1c4190c..59989ab 100644 --- a/automx2/views/__init__.py +++ b/automx2/views/__init__.py @@ -16,6 +16,8 @@ You should have received a copy of the GNU General Public License along with automx2. If not, see . """ +import re + from flask import Response from flask import make_response from flask import request @@ -31,6 +33,8 @@ class MailConfig: + CONTENT_TYPE_RE = re.compile(r'\b(?:application|text)/xml\b', re.IGNORECASE) + def config_from_address(self, address: str, realname: str = '', password: str = '') -> Response: local_part, domain_part = parse_email_address(address) data = self.config_response(local_part, domain_part, realname, password) @@ -48,8 +52,7 @@ def response_with_type(self, data: object) -> Response: response.headers[CONTENT_TYPE] = self.response_type() return response - @staticmethod - def is_xml_request() -> bool: - if CONTENT_TYPE in request.headers: - return request.headers[CONTENT_TYPE] == CONTENT_TYPE_XML or request.headers[CONTENT_TYPE] == 'text/xml' + def is_expected_content_type(self) -> bool: + if CONTENT_TYPE in request.headers and self.CONTENT_TYPE_RE.search(request.headers[CONTENT_TYPE]): + return True return False diff --git a/automx2/views/autodiscover.py b/automx2/views/autodiscover.py index 23b488a..26acdaf 100644 --- a/automx2/views/autodiscover.py +++ b/automx2/views/autodiscover.py @@ -28,7 +28,6 @@ from automx2 import log from automx2.generators.outlook import NS_REQUEST from automx2.generators.outlook import OutlookGenerator -from automx2.views import CONTENT_TYPE_XML from automx2.views import EMAIL_OUTLOOK from automx2.views import MailConfig @@ -38,8 +37,8 @@ class OutlookView(MailConfig, MethodView): def post(self): """Outlook-style POST request is expected to contain XML.""" - if not self.is_xml_request(): - message = f'Required content type is "{CONTENT_TYPE_XML}"' + if not self.is_expected_content_type(): + message = 'Unexpected content type' log.error(message) return message, 400 element: Element = fromstring(str(request.data, encoding='utf-8', errors='strict'))