diff options
Diffstat (limited to 'priv')
4 files changed, 218 insertions, 3 deletions
diff --git a/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs b/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs index f3928a149..99102117f 100644 --- a/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs +++ b/priv/repo/migrations/20190414125034_migrate_old_bookmarks.exs @@ -8,10 +8,10 @@ defmodule Pleroma.Repo.Migrations.MigrateOldBookmarks do def up do query = - from(u in User, + from(u in "users", where: u.local == true, - where: fragment("array_length(bookmarks, 1)") > 0, - select: %{id: u.id, bookmarks: fragment("bookmarks")} + where: fragment("array_length(?, 1)", u.bookmarks) > 0, + select: %{id: u.id, bookmarks: u.bookmarks} ) Repo.stream(query) diff --git a/priv/repo/migrations/20191025143434_add_defaults_to_tables.exs b/priv/repo/migrations/20191025143434_add_defaults_to_tables.exs new file mode 100644 index 000000000..a5bc82335 --- /dev/null +++ b/priv/repo/migrations/20191025143434_add_defaults_to_tables.exs @@ -0,0 +1,68 @@ +defmodule Pleroma.Repo.Migrations.AddDefaultsToTables do + use Ecto.Migration + + def up do + execute("ALTER TABLE activities + ALTER COLUMN recipients SET DEFAULT ARRAY[]::character varying[]") + + execute("ALTER TABLE filters + ALTER COLUMN whole_word SET DEFAULT true") + + execute("ALTER TABLE push_subscriptions + ALTER COLUMN data SET DEFAULT '{}'::jsonb") + + execute(~s(ALTER TABLE users + ALTER COLUMN tags SET DEFAULT ARRAY[]::character varying[], + ALTER COLUMN notification_settings SET DEFAULT + '{"followers": true, "follows": true, "non_follows": true, "non_followers": true}'::jsonb)) + + # irreversible updates + + execute( + "UPDATE activities SET recipients = ARRAY[]::character varying[] WHERE recipients IS NULL" + ) + + execute("UPDATE filters SET whole_word = true WHERE whole_word IS NULL") + + execute("UPDATE push_subscriptions SET data = '{}'::jsonb WHERE data IS NULL") + + execute("UPDATE users SET source_data = '{}'::jsonb where source_data IS NULL") + execute("UPDATE users SET note_count = 0 where note_count IS NULL") + execute("UPDATE users SET background = '{}'::jsonb where background IS NULL") + execute("UPDATE users SET follower_count = 0 where follower_count IS NULL") + + execute( + "UPDATE users SET unread_conversation_count = 0 where unread_conversation_count IS NULL" + ) + + execute( + ~s(UPDATE users SET email_notifications = '{"digest": false}'::jsonb where email_notifications IS NULL) + ) + + execute("UPDATE users SET default_scope = 'public' where default_scope IS NULL") + + execute( + "UPDATE users SET pleroma_settings_store = '{}'::jsonb where pleroma_settings_store IS NULL" + ) + + execute("UPDATE users SET tags = ARRAY[]::character varying[] WHERE tags IS NULL") + execute(~s(UPDATE users SET notification_settings = + '{"followers": true, "follows": true, "non_follows": true, "non_followers": true}'::jsonb + WHERE notification_settings = '{}'::jsonb)) + end + + def down do + execute("ALTER TABLE activities + ALTER COLUMN recipients DROP DEFAULT") + + execute("ALTER TABLE filters + ALTER COLUMN whole_word DROP DEFAULT") + + execute("ALTER TABLE push_subscriptions + ALTER COLUMN data DROP DEFAULT") + + execute("ALTER TABLE users + ALTER COLUMN tags DROP DEFAULT, + ALTER COLUMN notification_settings SET DEFAULT '{}'::jsonb") + end +end diff --git a/priv/repo/migrations/20191029101340_migrate_missing_follow_requests.exs b/priv/repo/migrations/20191029101340_migrate_missing_follow_requests.exs new file mode 100644 index 000000000..90b18efc8 --- /dev/null +++ b/priv/repo/migrations/20191029101340_migrate_missing_follow_requests.exs @@ -0,0 +1,35 @@ +defmodule Pleroma.Repo.Migrations.MigrateMissingFollowingRelationships do + use Ecto.Migration + + def change do + execute(import_pending_follows_from_activities(), "") + end + + defp import_pending_follows_from_activities do + """ + INSERT INTO + following_relationships ( + follower_id, + following_id, + state, + inserted_at, + updated_at + ) + SELECT + followers.id, + following.id, + activities.data ->> 'state', + (activities.data ->> 'published') :: timestamp, + now() + FROM + activities + JOIN users AS followers ON (activities.actor = followers.ap_id) + JOIN users AS following ON (activities.data ->> 'object' = following.ap_id) + WHERE + activities.data ->> 'type' = 'Follow' + AND activities.data ->> 'state' = 'pending' + ORDER BY activities.updated_at DESC + ON CONFLICT DO NOTHING + """ + end +end diff --git a/priv/repo/migrations/20191029172832_fix_blocked_follows.exs b/priv/repo/migrations/20191029172832_fix_blocked_follows.exs new file mode 100644 index 000000000..71f8f1330 --- /dev/null +++ b/priv/repo/migrations/20191029172832_fix_blocked_follows.exs @@ -0,0 +1,112 @@ +defmodule Pleroma.Repo.Migrations.FixBlockedFollows do + use Ecto.Migration + + import Ecto.Query + alias Pleroma.Config + alias Pleroma.Repo + + def up do + unfollow_blocked = Config.get([:activitypub, :unfollow_blocked]) + + if unfollow_blocked do + "activities" + |> where([activity], fragment("? ->> 'type' = 'Block'", activity.data)) + |> distinct([activity], [ + activity.actor, + fragment( + "coalesce((?)->'object'->>'id', (?)->>'object')", + activity.data, + activity.data + ) + ]) + |> order_by([activity], [fragment("? desc nulls last", activity.id)]) + |> select([activity], %{ + blocker: activity.actor, + blocked: + fragment("coalesce((?)->'object'->>'id', (?)->>'object')", activity.data, activity.data), + created_at: activity.id + }) + |> Repo.stream() + |> Enum.map(&unfollow_if_blocked/1) + |> Enum.uniq() + |> Enum.each(&update_follower_count/1) + end + end + + def down do + end + + def unfollow_if_blocked(%{blocker: blocker_id, blocked: blocked_id, created_at: blocked_at}) do + query = + from( + activity in "activities", + where: fragment("? ->> 'type' = 'Follow'", activity.data), + where: activity.actor == ^blocked_id, + # this is to use the index + where: + fragment( + "coalesce((?)->'object'->>'id', (?)->>'object') = ?", + activity.data, + activity.data, + ^blocker_id + ), + where: activity.id > ^blocked_at, + where: fragment("(?)->>'state' = 'accept'", activity.data), + order_by: [fragment("? desc nulls last", activity.id)] + ) + + unless Repo.exists?(query) do + blocker = "users" |> select([:id, :local]) |> Repo.get_by(ap_id: blocker_id) + blocked = "users" |> select([:id]) |> Repo.get_by(ap_id: blocked_id) + + if !is_nil(blocker) && !is_nil(blocked) do + unfollow(blocked, blocker) + end + end + end + + def unfollow(%{id: follower_id}, %{id: followed_id} = followed) do + following_relationship = + "following_relationships" + |> where(follower_id: ^follower_id, following_id: ^followed_id, state: "accept") + |> select([:id]) + |> Repo.one() + + case following_relationship do + nil -> + {:ok, nil} + + %{id: following_relationship_id} -> + "following_relationships" + |> where(id: ^following_relationship_id) + |> Repo.delete_all() + + followed + end + end + + def update_follower_count(%{id: user_id} = user) do + if user.local or !Pleroma.Config.get([:instance, :external_user_synchronization]) do + follower_count_query = + "users" + |> where([u], u.id != ^user_id) + |> where([u], u.deactivated != ^true) + |> join(:inner, [u], r in "following_relationships", + as: :relationships, + on: r.following_id == ^user_id and r.follower_id == u.id + ) + |> where([relationships: r], r.state == "accept") + |> select([u], %{count: count(u.id)}) + + "users" + |> where(id: ^user_id) + |> join(:inner, [u], s in subquery(follower_count_query)) + |> update([u, s], + set: [follower_count: s.count] + ) + |> Repo.update_all([]) + end + end + + def update_follower_count(_), do: :noop +end |