See #852: improved routing logic for federation messages (support multiple objects types for one route)

This commit is contained in:
Eliot Berriot 2019-09-21 16:20:49 +02:00
commit 9f3182caf7
19 changed files with 561 additions and 54 deletions

View file

@ -220,13 +220,3 @@ def test_user_get_quota_status(factories, preferences, mocker):
"errored": 3,
"finished": 4,
}
def test_deleting_users_deletes_associated_actor(factories):
actor = factories["federation.Actor"]()
user = factories["users.User"](actor=actor)
user.delete()
with pytest.raises(actor.DoesNotExist):
actor.refresh_from_db()

View file

@ -0,0 +1,33 @@
from funkwhale_api.users import tasks
def test_delete_account_mutation(mocker, factories, now):
user = factories["users.User"](subsonic_api_token="test", password="test")
actor = user.create_actor()
on_commit = mocker.patch("funkwhale_api.common.utils.on_commit")
secret_key = user.secret_key
set_unusable_password = mocker.spy(user, "set_unusable_password")
factories["users.Grant"](user=user)
factories["users.AccessToken"](user=user)
factories["users.RefreshToken"](user=user)
mutation = factories["common.Mutation"](
type="delete_account", target=actor, payload={}
)
mutation.apply()
user.refresh_from_db()
set_unusable_password.assert_called_once_with()
assert user.has_usable_password() is False
assert user.subsonic_api_token is None
assert user.secret_key is not None and user.secret_key != secret_key
assert user.users_grant.count() == 0
assert user.users_refreshtoken.count() == 0
assert user.users_accesstoken.count() == 0
on_commit.assert_called_once_with(tasks.delete_account.delay, user_id=user.pk)
assert mutation.previous_state == {
"actor": {"preferred_username": actor.preferred_username},
"user": {"username": user.username, "id": user.pk},
}

View file

@ -0,0 +1,32 @@
import pytest
from funkwhale_api.federation import routes
from funkwhale_api.users import tasks
def test_delete_account(factories, mocker):
user = factories["users.User"]()
actor = user.create_actor()
library = factories["music.Library"](actor=actor)
unrelated_library = factories["music.Library"]()
dispatch = mocker.patch.object(routes.outbox, "dispatch")
tasks.delete_account(user_id=user.pk)
dispatch.assert_called_once_with(
{"type": "Delete", "object": {"type": actor.type}}, context={"actor": actor}
)
with pytest.raises(user.DoesNotExist):
user.refresh_from_db()
with pytest.raises(library.DoesNotExist):
library.refresh_from_db()
# this one shouldn't be deleted
unrelated_library.refresh_from_db()
actor.refresh_from_db()
assert actor.type == "Tombstone"
assert actor.name is None
assert actor.summary is None

View file

@ -39,7 +39,7 @@ def test_username_only_accepts_letters_and_underscores(
def test_can_restrict_usernames(settings, preferences, db, api_client):
url = reverse("rest_register")
preferences["users__registration_enabled"] = True
settings.USERNAME_BLACKLIST = ["funkwhale"]
settings.ACCOUNT_USERNAME_BLACKLIST = ["funkwhale"]
data = {
"username": "funkwhale",
"email": "contact@funkwhale.io",
@ -333,3 +333,57 @@ def test_creating_user_sends_confirmation_email(
confirmation_message = mailoutbox[-1]
assert "Hello world" in confirmation_message.body
assert settings.FUNKWHALE_HOSTNAME in confirmation_message.body
def test_user_account_deletion_requires_valid_password(logged_in_api_client):
user = logged_in_api_client.user
user.set_password("mypassword")
url = reverse("api:v1:users:users-me")
payload = {"password": "invalid", "confirm": True}
response = logged_in_api_client.delete(url, payload)
assert response.status_code == 400
def test_user_account_deletion_requires_confirmation(logged_in_api_client):
user = logged_in_api_client.user
user.set_password("mypassword")
url = reverse("api:v1:users:users-me")
payload = {"password": "mypassword", "confirm": False}
response = logged_in_api_client.delete(url, payload)
assert response.status_code == 400
def test_user_account_deletion_triggers_delete_account(logged_in_api_client, mocker):
user = logged_in_api_client.user
user.set_password("mypassword")
url = reverse("api:v1:users:users-me")
payload = {"password": "mypassword", "confirm": True}
delete_account = mocker.patch("funkwhale_api.users.tasks.delete_account.delay")
response = logged_in_api_client.delete(url, payload)
assert response.status_code == 204
delete_account.assert_called_once_with(user_id=user.pk)
def test_username_with_existing_local_account_are_invalid(
settings, preferences, factories, api_client
):
actor = factories["users.User"]().create_actor()
user = actor.user
user.delete()
url = reverse("rest_register")
preferences["users__registration_enabled"] = True
settings.ACCOUNT_USERNAME_BLACKLIST = []
data = {
"username": user.username,
"email": "contact@funkwhale.io",
"password1": "testtest",
"password2": "testtest",
}
response = api_client.post(url, data)
assert response.status_code == 400
assert "username" in response.data