diff --git a/selfprivacy_api/dependencies.py b/selfprivacy_api/dependencies.py index f27bef3..74252c7 100644 --- a/selfprivacy_api/dependencies.py +++ b/selfprivacy_api/dependencies.py @@ -27,4 +27,4 @@ async def get_token_header( def get_api_version() -> str: """Get API version""" - return "2.1.0" + return "2.1.1" diff --git a/selfprivacy_api/rest/services.py b/selfprivacy_api/rest/services.py index ca2bc9b..317cba0 100644 --- a/selfprivacy_api/rest/services.py +++ b/selfprivacy_api/rest/services.py @@ -117,7 +117,7 @@ async def get_mailserver_dkim(): """Get the DKIM record for the mailserver""" domain = get_domain() - dkim = get_dkim_key(domain) + dkim = get_dkim_key(domain, parse=False) if dkim is None: raise HTTPException(status_code=404, detail="DKIM record not found") dkim = base64.b64encode(dkim.encode("utf-8")).decode("utf-8") diff --git a/selfprivacy_api/utils/__init__.py b/selfprivacy_api/utils/__init__.py index 83213d7..96bf9d8 100644 --- a/selfprivacy_api/utils/__init__.py +++ b/selfprivacy_api/utils/__init__.py @@ -164,13 +164,25 @@ def parse_date(date_str: str) -> datetime.datetime: raise ValueError("Invalid date string") -def get_dkim_key(domain): +def get_dkim_key(domain, parse=True): """Get DKIM key from /var/dkim/.selector.txt""" if os.path.exists("/var/dkim/" + domain + ".selector.txt"): cat_process = subprocess.Popen( ["cat", "/var/dkim/" + domain + ".selector.txt"], stdout=subprocess.PIPE ) dkim = cat_process.communicate()[0] + if parse: + # Extract key from file + dkim = dkim.split(b"(")[1] + dkim = dkim.split(b")")[0] + # Replace all quotes with nothing + dkim = dkim.replace(b'"', b"") + # Trim whitespace, remove newlines and tabs + dkim = dkim.strip() + dkim = dkim.replace(b"\n", b"") + dkim = dkim.replace(b"\t", b"") + # Remove all redundant spaces + dkim = b" ".join(dkim.split()) return str(dkim, "utf-8") return None diff --git a/setup.py b/setup.py index 9b819c4..e0c5716 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="selfprivacy_api", - version="2.1.0", + version="2.1.1", packages=find_packages(), scripts=[ "selfprivacy_api/app.py", diff --git a/tests/test_rest_endpoints/services/test_mailserver.py b/tests/test_rest_endpoints/services/test_mailserver.py index 36cf615..2803683 100644 --- a/tests/test_rest_endpoints/services/test_mailserver.py +++ b/tests/test_rest_endpoints/services/test_mailserver.py @@ -2,6 +2,8 @@ import base64 import json import pytest +from selfprivacy_api.utils import get_dkim_key + ############################################################################### @@ -13,7 +15,10 @@ class ProcessMock: self.kwargs = kwargs def communicate(): - return (b"I am a DKIM key", None) + return ( + b'selector._domainkey\tIN\tTXT\t( "v=DKIM1; k=rsa; "\n\t "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNn/IhEz1SxgHxxxI8vlPYC2dNueiLe1GC4SYz8uHimC8SDkMvAwm7rqi2SimbFgGB5nccCNOqCkrIqJTCB9vufqBnVKAjshHqpOr5hk4JJ1T/AGQKWinstmDbfTLPYTbU8ijZrwwGeqQLlnXR5nSN0GB9GazheA9zaPsT6PV+aQIDAQAB" ) ; ----- DKIM key selector for example.com\n', + None, + ) class NoFileMock(ProcessMock): @@ -63,11 +68,27 @@ def test_illegal_methods(authorized_client, mock_subproccess_popen): assert response.status_code == 405 -def test_dkim_key(authorized_client, mock_subproccess_popen): +def test_get_dkim_key(mock_subproccess_popen): """Test DKIM key""" + dkim_key = get_dkim_key("example.com") + assert ( + dkim_key + == "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNn/IhEz1SxgHxxxI8vlPYC2dNueiLe1GC4SYz8uHimC8SDkMvAwm7rqi2SimbFgGB5nccCNOqCkrIqJTCB9vufqBnVKAjshHqpOr5hk4JJ1T/AGQKWinstmDbfTLPYTbU8ijZrwwGeqQLlnXR5nSN0GB9GazheA9zaPsT6PV+aQIDAQAB" + ) + assert mock_subproccess_popen.call_args[0][0] == [ + "cat", + "/var/dkim/example.com.selector.txt", + ] + + +def test_dkim_key(authorized_client, mock_subproccess_popen): + """Test old REST DKIM key endpoint""" response = authorized_client.get("/services/mailserver/dkim") assert response.status_code == 200 - assert base64.b64decode(response.text) == b"I am a DKIM key" + assert ( + base64.b64decode(response.text) + == b'selector._domainkey\tIN\tTXT\t( "v=DKIM1; k=rsa; "\n\t "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNn/IhEz1SxgHxxxI8vlPYC2dNueiLe1GC4SYz8uHimC8SDkMvAwm7rqi2SimbFgGB5nccCNOqCkrIqJTCB9vufqBnVKAjshHqpOr5hk4JJ1T/AGQKWinstmDbfTLPYTbU8ijZrwwGeqQLlnXR5nSN0GB9GazheA9zaPsT6PV+aQIDAQAB" ) ; ----- DKIM key selector for example.com\n' + ) assert mock_subproccess_popen.call_args[0][0] == [ "cat", "/var/dkim/example.com.selector.txt",