@@ -13,6 +13,8 @@ defmodule Pleroma.User do | |||||
alias Pleroma.Web.{OStatus, Websub, OAuth} | alias Pleroma.Web.{OStatus, Websub, OAuth} | ||||
alias Pleroma.Web.ActivityPub.{Utils, ActivityPub} | alias Pleroma.Web.ActivityPub.{Utils, ActivityPub} | ||||
require Logger | |||||
@type t :: %__MODULE__{} | @type t :: %__MODULE__{} | ||||
@email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ | @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ | ||||
@@ -331,6 +333,24 @@ defmodule Pleroma.User do | |||||
Enum.member?(follower.following, followed.follower_address) | Enum.member?(follower.following, followed.follower_address) | ||||
end | end | ||||
def follow_import(%User{} = follower, followed_identifiers) | |||||
when is_list(followed_identifiers) do | |||||
Enum.map( | |||||
followed_identifiers, | |||||
fn followed_identifier -> | |||||
with %User{} = followed <- get_or_fetch(followed_identifier), | |||||
{:ok, follower} <- maybe_direct_follow(follower, followed), | |||||
{:ok, _} <- ActivityPub.follow(follower, followed) do | |||||
followed | |||||
else | |||||
err -> | |||||
Logger.debug("follow_import failed for #{followed_identifier} with: #{inspect(err)}") | |||||
err | |||||
end | |||||
end | |||||
) | |||||
end | |||||
def locked?(%User{} = user) do | def locked?(%User{} = user) do | ||||
user.info.locked || false | user.info.locked || false | ||||
end | end | ||||
@@ -596,6 +616,23 @@ defmodule Pleroma.User do | |||||
Repo.all(q) | Repo.all(q) | ||||
end | end | ||||
def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do | |||||
Enum.map( | |||||
blocked_identifiers, | |||||
fn blocked_identifier -> | |||||
with %User{} = blocked <- get_or_fetch(blocked_identifier), | |||||
{:ok, blocker} <- block(blocker, blocked), | |||||
{:ok, _} <- ActivityPub.block(blocker, blocked) do | |||||
blocked | |||||
else | |||||
err -> | |||||
Logger.debug("blocks_import failed for #{blocked_identifier} with: #{inspect(err)}") | |||||
err | |||||
end | |||||
end | |||||
) | |||||
end | |||||
def block(blocker, %User{ap_id: ap_id} = blocked) do | def block(blocker, %User{ap_id: ap_id} = blocked) do | ||||
# sever any follow relationships to prevent leaks per activitypub (Pleroma issue #213) | # sever any follow relationships to prevent leaks per activitypub (Pleroma issue #213) | ||||
blocker = | blocker = | ||||
@@ -240,48 +240,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do | |||||
follow_import(conn, %{"list" => File.read!(listfile.path)}) | follow_import(conn, %{"list" => File.read!(listfile.path)}) | ||||
end | end | ||||
def follow_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do | |||||
Task.start(fn -> | |||||
follower = User.get_cached_by_ap_id(user.ap_id) | |||||
list | |||||
|> String.split() | |||||
|> Enum.map(fn account -> | |||||
with %User{} <- follower, | |||||
%User{} = followed <- User.get_or_fetch(account), | |||||
{:ok, follower} <- User.maybe_direct_follow(follower, followed) do | |||||
ActivityPub.follow(follower, followed) | |||||
else | |||||
err -> Logger.debug("follow_import: following #{account} failed with #{inspect(err)}") | |||||
end | |||||
end) | |||||
end) | |||||
json(conn, "job started") | |||||
def follow_import(%{assigns: %{user: follower}} = conn, %{"list" => list}) do | |||||
with followed_identifiers <- String.split(list), | |||||
{:ok, _} = Task.start(fn -> User.follow_import(follower, followed_identifiers) end) do | |||||
json(conn, "job started") | |||||
end | |||||
end | end | ||||
def blocks_import(conn, %{"list" => %Plug.Upload{} = listfile}) do | def blocks_import(conn, %{"list" => %Plug.Upload{} = listfile}) do | ||||
blocks_import(conn, %{"list" => File.read!(listfile.path)}) | blocks_import(conn, %{"list" => File.read!(listfile.path)}) | ||||
end | end | ||||
def blocks_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do | |||||
Task.start(fn -> | |||||
blocker = User.get_cached_by_ap_id(user.ap_id) | |||||
list | |||||
|> String.split() | |||||
|> Enum.map(fn account -> | |||||
with %User{} <- blocker, | |||||
%User{} = blocked <- User.get_or_fetch(account), | |||||
{:ok, blocker} <- User.block(blocker, blocked) do | |||||
ActivityPub.block(blocker, blocked) | |||||
else | |||||
err -> Logger.debug("blocks_import: blocking #{account} failed with #{inspect(err)}") | |||||
end | |||||
end) | |||||
end) | |||||
json(conn, "job started") | |||||
def blocks_import(%{assigns: %{user: blocker}} = conn, %{"list" => list}) do | |||||
with blocked_identifiers <- String.split(list), | |||||
{:ok, _} = Task.start(fn -> User.blocks_import(blocker, blocked_identifiers) end) do | |||||
json(conn, "job started") | |||||
end | |||||
end | end | ||||
def change_password(%{assigns: %{user: user}} = conn, params) do | def change_password(%{assigns: %{user: user}} = conn, params) do | ||||
@@ -485,6 +485,21 @@ defmodule Pleroma.UserTest do | |||||
end | end | ||||
end | end | ||||
describe "follow_import" do | |||||
test "it imports user followings from list" do | |||||
[user1, user2, user3] = insert_list(3, :user) | |||||
identifiers = [ | |||||
user2.ap_id, | |||||
user3.nickname | |||||
] | |||||
result = User.follow_import(user1, identifiers) | |||||
assert is_list(result) | |||||
assert result == [user2, user3] | |||||
end | |||||
end | |||||
describe "blocks" do | describe "blocks" do | ||||
test "it blocks people" do | test "it blocks people" do | ||||
user = insert(:user) | user = insert(:user) | ||||
@@ -584,6 +599,21 @@ defmodule Pleroma.UserTest do | |||||
end | end | ||||
end | end | ||||
describe "blocks_import" do | |||||
test "it imports user blocks from list" do | |||||
[user1, user2, user3] = insert_list(3, :user) | |||||
identifiers = [ | |||||
user2.ap_id, | |||||
user3.nickname | |||||
] | |||||
result = User.blocks_import(user1, identifiers) | |||||
assert is_list(result) | |||||
assert result == [user2, user3] | |||||
end | |||||
end | |||||
test "get recipients from activity" do | test "get recipients from activity" do | ||||
actor = insert(:user) | actor = insert(:user) | ||||
user = insert(:user, local: true) | user = insert(:user, local: true) | ||||
@@ -0,0 +1,35 @@ | |||||
defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do | |||||
use Pleroma.Web.ConnCase | |||||
import Pleroma.Factory | |||||
describe "POST /api/pleroma/follow_import" do | |||||
test "it returns HTTP 200", %{conn: conn} do | |||||
user1 = insert(:user) | |||||
user2 = insert(:user) | |||||
response = | |||||
conn | |||||
|> assign(:user, user1) | |||||
|> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"}) | |||||
|> json_response(:ok) | |||||
assert response == "job started" | |||||
end | |||||
end | |||||
describe "POST /api/pleroma/blocks_import" do | |||||
test "it returns HTTP 200", %{conn: conn} do | |||||
user1 = insert(:user) | |||||
user2 = insert(:user) | |||||
response = | |||||
conn | |||||
|> assign(:user, user1) | |||||
|> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"}) | |||||
|> json_response(:ok) | |||||
assert response == "job started" | |||||
end | |||||
end | |||||
end |