This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Test room alias deletion #11327
Merged
Merged
Test room alias deletion #11327
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4a4d62b
Prefer `HTTPStatus` over plain `int`
f33f171
`--disallow-untyped-defs` for `tests.rest.client.test_directory`
533faee
Improve synapse's annotations for deleting aliases
6ccc156
Test case for deleting a room alias
ec1ad88
Changelog
bc4bf29
Handle the race condition properly
18b82e0
Use import compatible with old twisted
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Test that room alias deletion works as intended. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,6 +204,10 @@ async def delete_association( | |
) | ||
|
||
room_id = await self._delete_association(room_alias) | ||
# The call to `_user_can_delete_alias` above ensures the alias exists. | ||
# `_delete_association` returns `None` only if the alias doesn't exist. | ||
# We leave the assert here for mypy's benefit. | ||
assert room_id is not None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this actually hiding a race condition? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, you're right. Maybe something deletes the alias after we get |
||
|
||
try: | ||
await self._update_canonical_alias(requester, user_id, room_id, room_alias) | ||
|
@@ -225,7 +229,7 @@ async def delete_appservice_association( | |
) | ||
await self._delete_association(room_alias) | ||
|
||
async def _delete_association(self, room_alias: RoomAlias) -> str: | ||
async def _delete_association(self, room_alias: RoomAlias) -> Optional[str]: | ||
if not self.hs.is_mine(room_alias): | ||
raise SynapseError(400, "Room alias must be local") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,12 +11,16 @@ | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import json | ||
from http import HTTPStatus | ||
|
||
from twisted.internet.testing import MemoryReactor | ||
|
||
from synapse.rest import admin | ||
from synapse.rest.client import directory, login, room | ||
from synapse.server import HomeServer | ||
from synapse.types import RoomAlias | ||
from synapse.util import Clock | ||
from synapse.util.stringutils import random_string | ||
|
||
from tests import unittest | ||
|
@@ -32,15 +36,19 @@ class DirectoryTestCase(unittest.HomeserverTestCase): | |
room.register_servlets, | ||
] | ||
|
||
def make_homeserver(self, reactor, clock): | ||
def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer: | ||
config = self.default_config() | ||
config["require_membership_for_aliases"] = True | ||
|
||
self.hs = self.setup_test_homeserver(config=config) | ||
|
||
return self.hs | ||
|
||
def prepare(self, reactor, clock, homeserver): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW It might be easy to do a PR that modifies this (and |
||
def prepare( | ||
self, reactor: MemoryReactor, clock: Clock, homeserver: HomeServer | ||
) -> None: | ||
"""Create two local users and access tokens for them. | ||
One of them creates a room.""" | ||
self.room_owner = self.register_user("room_owner", "test") | ||
self.room_owner_tok = self.login("room_owner", "test") | ||
|
||
|
@@ -51,39 +59,39 @@ def prepare(self, reactor, clock, homeserver): | |
self.user = self.register_user("user", "test") | ||
self.user_tok = self.login("user", "test") | ||
|
||
def test_state_event_not_in_room(self): | ||
def test_state_event_not_in_room(self) -> None: | ||
self.ensure_user_left_room() | ||
self.set_alias_via_state_event(403) | ||
self.set_alias_via_state_event(HTTPStatus.FORBIDDEN) | ||
|
||
def test_directory_endpoint_not_in_room(self): | ||
def test_directory_endpoint_not_in_room(self) -> None: | ||
self.ensure_user_left_room() | ||
self.set_alias_via_directory(403) | ||
self.set_alias_via_directory(HTTPStatus.FORBIDDEN) | ||
|
||
def test_state_event_in_room_too_long(self): | ||
def test_state_event_in_room_too_long(self) -> None: | ||
self.ensure_user_joined_room() | ||
self.set_alias_via_state_event(400, alias_length=256) | ||
self.set_alias_via_state_event(HTTPStatus.BAD_REQUEST, alias_length=256) | ||
|
||
def test_directory_in_room_too_long(self): | ||
def test_directory_in_room_too_long(self) -> None: | ||
self.ensure_user_joined_room() | ||
self.set_alias_via_directory(400, alias_length=256) | ||
self.set_alias_via_directory(HTTPStatus.BAD_REQUEST, alias_length=256) | ||
|
||
@override_config({"default_room_version": 5}) | ||
def test_state_event_user_in_v5_room(self): | ||
def test_state_event_user_in_v5_room(self) -> None: | ||
"""Test that a regular user can add alias events before room v6""" | ||
self.ensure_user_joined_room() | ||
self.set_alias_via_state_event(200) | ||
self.set_alias_via_state_event(HTTPStatus.OK) | ||
|
||
@override_config({"default_room_version": 6}) | ||
def test_state_event_v6_room(self): | ||
def test_state_event_v6_room(self) -> None: | ||
"""Test that a regular user can *not* add alias events from room v6""" | ||
self.ensure_user_joined_room() | ||
self.set_alias_via_state_event(403) | ||
self.set_alias_via_state_event(HTTPStatus.FORBIDDEN) | ||
|
||
def test_directory_in_room(self): | ||
def test_directory_in_room(self) -> None: | ||
self.ensure_user_joined_room() | ||
self.set_alias_via_directory(200) | ||
self.set_alias_via_directory(HTTPStatus.OK) | ||
|
||
def test_room_creation_too_long(self): | ||
def test_room_creation_too_long(self) -> None: | ||
url = "/_matrix/client/r0/createRoom" | ||
|
||
# We use deliberately a localpart under the length threshold so | ||
|
@@ -93,9 +101,9 @@ def test_room_creation_too_long(self): | |
channel = self.make_request( | ||
"POST", url, request_data, access_token=self.user_tok | ||
) | ||
self.assertEqual(channel.code, 400, channel.result) | ||
self.assertEqual(channel.code, HTTPStatus.BAD_REQUEST, channel.result) | ||
|
||
def test_room_creation(self): | ||
def test_room_creation(self) -> None: | ||
url = "/_matrix/client/r0/createRoom" | ||
|
||
# Check with an alias of allowed length. There should already be | ||
|
@@ -106,9 +114,46 @@ def test_room_creation(self): | |
channel = self.make_request( | ||
"POST", url, request_data, access_token=self.user_tok | ||
) | ||
self.assertEqual(channel.code, 200, channel.result) | ||
self.assertEqual(channel.code, HTTPStatus.OK, channel.result) | ||
|
||
def test_deleting_alias_via_directory(self) -> None: | ||
# Add an alias for the room. We must be joined to do so. | ||
self.ensure_user_joined_room() | ||
alias = self.set_alias_via_directory(HTTPStatus.OK) | ||
|
||
# Then try to remove the alias | ||
channel = self.make_request( | ||
"DELETE", | ||
f"/_matrix/client/r0/directory/room/{alias}", | ||
access_token=self.user_tok, | ||
) | ||
self.assertEqual(channel.code, HTTPStatus.OK, channel.result) | ||
|
||
def test_deleting_nonexistant_alias(self) -> None: | ||
# Check that no alias exists | ||
alias = "#potato:test" | ||
channel = self.make_request( | ||
"GET", | ||
f"/_matrix/client/r0/directory/room/{alias}", | ||
access_token=self.user_tok, | ||
) | ||
self.assertEqual(channel.code, HTTPStatus.NOT_FOUND, channel.result) | ||
self.assertIn("error", channel.json_body, channel.json_body) | ||
self.assertEqual(channel.json_body["errcode"], "M_NOT_FOUND", channel.json_body) | ||
|
||
# Then try to remove the alias | ||
channel = self.make_request( | ||
"DELETE", | ||
f"/_matrix/client/r0/directory/room/{alias}", | ||
access_token=self.user_tok, | ||
) | ||
self.assertEqual(channel.code, HTTPStatus.NOT_FOUND, channel.result) | ||
self.assertIn("error", channel.json_body, channel.json_body) | ||
self.assertEqual(channel.json_body["errcode"], "M_NOT_FOUND", channel.json_body) | ||
|
||
def set_alias_via_state_event(self, expected_code, alias_length=5): | ||
def set_alias_via_state_event( | ||
self, expected_code: HTTPStatus, alias_length: int = 5 | ||
) -> None: | ||
url = "/_matrix/client/r0/rooms/%s/state/m.room.aliases/%s" % ( | ||
self.room_id, | ||
self.hs.hostname, | ||
|
@@ -122,26 +167,30 @@ def set_alias_via_state_event(self, expected_code, alias_length=5): | |
) | ||
self.assertEqual(channel.code, expected_code, channel.result) | ||
|
||
def set_alias_via_directory(self, expected_code, alias_length=5): | ||
url = "/_matrix/client/r0/directory/room/%s" % self.random_alias(alias_length) | ||
def set_alias_via_directory( | ||
self, expected_code: HTTPStatus, alias_length: int = 5 | ||
) -> str: | ||
alias = self.random_alias(alias_length) | ||
url = "/_matrix/client/r0/directory/room/%s" % alias | ||
data = {"room_id": self.room_id} | ||
request_data = json.dumps(data) | ||
|
||
channel = self.make_request( | ||
"PUT", url, request_data, access_token=self.user_tok | ||
) | ||
self.assertEqual(channel.code, expected_code, channel.result) | ||
return alias | ||
|
||
def random_alias(self, length): | ||
def random_alias(self, length: int) -> str: | ||
return RoomAlias(random_string(length), self.hs.hostname).to_string() | ||
|
||
def ensure_user_left_room(self): | ||
def ensure_user_left_room(self) -> None: | ||
self.ensure_membership("leave") | ||
|
||
def ensure_user_joined_room(self): | ||
def ensure_user_joined_room(self) -> None: | ||
self.ensure_membership("join") | ||
|
||
def ensure_membership(self, membership): | ||
def ensure_membership(self, membership: str) -> None: | ||
try: | ||
if membership == "leave": | ||
self.helper.leave(room=self.room_id, user=self.user, tok=self.user_tok) | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is unnecessary with #11322?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OH NO! That had a bug in it....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing a
.*
I think? Ouch!