Skip to content

Commit

Permalink
feat: quote audit log values to avoid auto linking
Browse files Browse the repository at this point in the history
Some e-mail services such as Gmail automatically convert things that
look like a link into links even in HTML mails. This could be
problematic for audit log entries as want to display the information as
is without turning that into links.

Adding <span> seems to help in this according to
https://stackoverflow.com/a/23404042/225718
  • Loading branch information
nijel committed Oct 15, 2024
1 parent 260e78b commit 1bde1b8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
5 changes: 3 additions & 2 deletions weblate/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from weblate.utils import messages
from weblate.utils.decorators import disable_for_loaddata
from weblate.utils.fields import EmailField
from weblate.utils.html import mail_quote_value
from weblate.utils.render import validate_editor
from weblate.utils.request import get_ip_address, get_user_agent
from weblate.utils.token import get_token
Expand Down Expand Up @@ -352,9 +353,9 @@ def get_params(self):
}
for name, value in self.params.items():
if name in {"old", "new", "name", "email", "username"}:
value = format_html("<code>{}</code>", value)
value = format_html("<code>{}</code>", mail_quote_value(value))
elif name in {"device", "project", "site_title", "method"}:
value = format_html("<strong>{}</strong>", value)
value = format_html("<strong>{}</strong>", mail_quote_value(value))

result[name] = value

Expand Down
24 changes: 24 additions & 0 deletions weblate/utils/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
from typing import TYPE_CHECKING

import nh3
from django.utils.html import format_html, format_html_join
from html2text import HTML2Text as _HTML2Text
from lxml.etree import HTMLParser

if TYPE_CHECKING:
from django.utils.safestring import SafeString
from lxml.etree import ParserTarget

from weblate.checks.flags import Flags
Expand Down Expand Up @@ -164,3 +166,25 @@ def handle_tag(self, tag: str, attrs: dict[str, str | None], start: bool) -> Non
self.o(WEBLATE_TAGS[tag][not start])
return
super().handle_tag(tag, attrs, start)


def mail_quote_char(text: str) -> str | SafeString:
if text in {":", "."}:
return format_html("<span>{}</span>", text)
return text


def mail_quote_value(text: str) -> str | SafeString:
"""
Quote value to be used in e-mail notifications.
This tries to avoid automatic conversion to links by Gmail
and similar services.
Solution based on https://stackoverflow.com/a/23404042/225718
"""
return format_html_join(
"",
"{}",
((mail_quote_char(part),) for part in re.split("([.:])", text)),
)
27 changes: 26 additions & 1 deletion weblate/utils/tests/test_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
from django.test import SimpleTestCase

from weblate.checks.flags import Flags
from weblate.utils.html import HTML2Text, HTMLSanitizer, extract_html_tags
from weblate.utils.html import (
HTML2Text,
HTMLSanitizer,
extract_html_tags,
mail_quote_value,
)


class HTMLSanitizerTestCase(SimpleTestCase):
Expand Down Expand Up @@ -104,3 +109,23 @@ def test_html2text_diff(self) -> None:
html2text.handle("text<ins> </ins>"),
"text{+ +}\n\n",
)


class MailQuoteTestCase(SimpleTestCase):
def test_plain(self):
self.assertEqual(
mail_quote_value("text"),
"text",
)

def test_dot(self):
self.assertEqual(
mail_quote_value("example.com"),
"example<span>.</span>com",
)

def test_url(self):
self.assertEqual(
mail_quote_value("https://test.example.com"),
"https<span>:</span>//test<span>.</span>example<span>.</span>com",
)

0 comments on commit 1bde1b8

Please sign in to comment.