fixed handling of non-standard matrix:// ports (#1450)

This commit is contained in:
Chris Caron
2025-11-15 12:41:29 -05:00
committed by GitHub
parent f3ae780a8e
commit dfe933cbb4
2 changed files with 93 additions and 22 deletions

View File

@@ -462,17 +462,11 @@ class NotifyMatrix(NotifyBase):
# Acquire our access token from our URL
access_token = self.password if self.password else self.user
default_port = 443 if self.secure else 80
# Prepare our URL
url = "{schema}://{hostname}:{port}{webhook_path}/{token}".format(
url = "{schema}://{hostname}{port}{webhook_path}/{token}".format(
schema="https" if self.secure else "http",
hostname=self.host,
port=(
""
if self.port is None or self.port == default_port
else self.port
),
port=("" if not self.port else f":{self.port}"),
webhook_path=MATRIX_V1_WEBHOOK_PATH,
token=access_token,
)
@@ -1568,7 +1562,6 @@ class NotifyMatrix(NotifyBase):
),
)
default_port = 443 if self.secure else 80
return "{schema}://{auth}{hostname}{port}/{rooms}?{params}".format(
schema=self.secure_protocol if self.secure else self.protocol,
auth=auth,
@@ -1577,11 +1570,7 @@ class NotifyMatrix(NotifyBase):
if self.mode != MatrixWebhookMode.T2BOT
else self.pprint(self.access_token, privacy, safe="")
),
port=(
""
if self.port is None or self.port == default_port
else f":{self.port}"
),
port=("" if not self.port else f":{self.port}"),
rooms=NotifyMatrix.quote("/".join(self.rooms)),
params=NotifyMatrix.urlencode(params),
)
@@ -1724,9 +1713,14 @@ class NotifyMatrix(NotifyBase):
# We can use our cached value and return early
return base_url
# 1. Extract the server name from the user's Matrix ID by splitting
# the Matrix ID at the first colon.
verify_url = f"https://{self.host}/.well-known/matrix/client"
verify_url = \
"{schema}://{hostname}{port}/.well-known/matrix/client".format(
schema="https" if self.secure else "http",
hostname=self.host,
port=("" if not self.port else f":{self.port}"),
)
code, wk_response = self._fetch(
None, method="GET", url_override=verify_url
)
@@ -1910,15 +1904,10 @@ class NotifyMatrix(NotifyBase):
# If we get hear, we need to build our URL dynamically based on what
# was provided to us during the plugins initialization
default_port = 443 if self.secure else 80
return "{schema}://{hostname}{port}".format(
schema="https" if self.secure else "http",
hostname=self.host,
port=(
""
if self.port is None or self.port == default_port
else f":{self.port}"
),
port=("" if not self.port else f":{self.port}"),
)
@property

View File

@@ -1759,3 +1759,85 @@ def test_plugin_matrix_transaction_ids_api_v3_w_cache(
assert mock_get.call_count == 0
assert mock_post.call_count == 0
assert mock_put.call_count == 0
@mock.patch("requests.put")
@mock.patch("requests.get")
@mock.patch("requests.post")
def test_plugin_matrix_v3_url_with_port_assembly(
mock_post, mock_get, mock_put, tmpdir
):
"""NotifyMatrix() URL with Port Assembly Checks (v3)"""
# Prepare a good response
response = mock.Mock()
response.status_code = requests.codes.ok
response.content = MATRIX_GOOD_RESPONSE.encode("utf-8")
# Prepare Mock return object
mock_post.return_value = response
mock_get.return_value = response
mock_put.return_value = response
asset = AppriseAsset(
storage_mode=PersistentStoreMode.FLUSH,
storage_path=str(tmpdir),
)
# Instantiate our object
obj = Apprise.instantiate(
"matrixs://user1:pass123@example.ca:8080/#general?v=3", asset=asset
)
# Performs a login
assert (
obj.notify(body="body", title="title", notify_type=NotifyType.INFO)
is True
)
# Secure Connections have a bit of additional overhead to verify
# the authenticity of the server through discovery
assert mock_get.call_count == 3
assert (
mock_get.call_args_list[0][0][0]
== "https://example.ca:8080/.well-known/matrix/client"
)
assert (
mock_get.call_args_list[1][0][0]
== "https://matrix.example.com/_matrix/client/versions"
)
assert (
mock_get.call_args_list[2][0][0]
== "https://vector.im/_matrix/identity/v2"
)
assert mock_post.call_count == 2
# matrix.example.com comes from our MATRIX_GOOD_RESPONSE
# response which defines wht our .well-known returned to us
assert (
mock_post.call_args_list[0][0][0]
== "https://matrix.example.com/_matrix/client/v3/login"
)
assert (
mock_post.call_args_list[1][0][0]
== "https://matrix.example.com/_matrix/client/v3/"
"join/%23general%3Alocalhost"
)
assert mock_put.call_count == 1
assert (
mock_put.call_args_list[0][0][0]
== "https://matrix.example.com/_matrix/client/v3/rooms/"
+ "%21abc123%3Alocalhost/send/m.room.message/0"
)
mock_post.reset_mock()
mock_get.reset_mock()
mock_put.reset_mock()
assert obj.base_url == "https://matrix.example.com"
# Cache is used under the hood; no second discover is performed
assert mock_put.call_count == 0
assert mock_get.call_count == 0
assert mock_post.call_count == 0
# Cleanup
del obj