Log admin/moderator actions See merge request pleroma/pleroma!1582stable
commit
897bd7a15e
@ -0,0 +1,433 @@
|
|||||||
|
defmodule Pleroma.ModerationLog do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.ModerationLog
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
schema "moderation_log" do
|
||||||
|
field(:data, :map)
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_all(page, page_size) do
|
||||||
|
from(q in __MODULE__,
|
||||||
|
order_by: [desc: q.inserted_at],
|
||||||
|
limit: ^page_size,
|
||||||
|
offset: ^((page - 1) * page_size)
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
subject: %User{} = subject,
|
||||||
|
action: action,
|
||||||
|
permission: permission
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
subject: user_to_map(subject),
|
||||||
|
action: action,
|
||||||
|
permission: permission
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
action: "report_update",
|
||||||
|
subject: %Activity{data: %{"type" => "Flag"}} = subject
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: "report_update",
|
||||||
|
subject: report_to_map(subject)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
action: "report_response",
|
||||||
|
subject: %Activity{} = subject,
|
||||||
|
text: text
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: "report_response",
|
||||||
|
subject: report_to_map(subject),
|
||||||
|
text: text
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
action: "status_update",
|
||||||
|
subject: %Activity{} = subject,
|
||||||
|
sensitive: sensitive,
|
||||||
|
visibility: visibility
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: "status_update",
|
||||||
|
subject: status_to_map(subject),
|
||||||
|
sensitive: sensitive,
|
||||||
|
visibility: visibility
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
action: "status_delete",
|
||||||
|
subject_id: subject_id
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: "status_delete",
|
||||||
|
subject_id: subject_id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec insert_log(%{actor: User, subject: User, action: String.t()}) ::
|
||||||
|
{:ok, ModerationLog} | {:error, any}
|
||||||
|
def insert_log(%{actor: %User{} = actor, subject: subject, action: action}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: action,
|
||||||
|
subject: user_to_map(subject)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec insert_log(%{actor: User, subjects: [User], action: String.t()}) ::
|
||||||
|
{:ok, ModerationLog} | {:error, any}
|
||||||
|
def insert_log(%{actor: %User{} = actor, subjects: subjects, action: action}) do
|
||||||
|
subjects = Enum.map(subjects, &user_to_map/1)
|
||||||
|
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: action,
|
||||||
|
subjects: subjects
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
followed: %User{} = followed,
|
||||||
|
follower: %User{} = follower,
|
||||||
|
action: "follow"
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: "follow",
|
||||||
|
followed: user_to_map(followed),
|
||||||
|
follower: user_to_map(follower)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
followed: %User{} = followed,
|
||||||
|
follower: %User{} = follower,
|
||||||
|
action: "unfollow"
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: "unfollow",
|
||||||
|
followed: user_to_map(followed),
|
||||||
|
follower: user_to_map(follower)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
nicknames: nicknames,
|
||||||
|
tags: tags,
|
||||||
|
action: action
|
||||||
|
}) do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
nicknames: nicknames,
|
||||||
|
tags: tags,
|
||||||
|
action: action
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_log(%{
|
||||||
|
actor: %User{} = actor,
|
||||||
|
action: action,
|
||||||
|
target: target
|
||||||
|
})
|
||||||
|
when action in ["relay_follow", "relay_unfollow"] do
|
||||||
|
Repo.insert(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
actor: user_to_map(actor),
|
||||||
|
action: action,
|
||||||
|
target: target
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp user_to_map(%User{} = user) do
|
||||||
|
user
|
||||||
|
|> Map.from_struct()
|
||||||
|
|> Map.take([:id, :nickname])
|
||||||
|
|> Map.put(:type, "user")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp report_to_map(%Activity{} = report) do
|
||||||
|
%{
|
||||||
|
type: "report",
|
||||||
|
id: report.id,
|
||||||
|
state: report.data["state"]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp status_to_map(%Activity{} = status) do
|
||||||
|
%{
|
||||||
|
type: "status",
|
||||||
|
id: status.id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => action,
|
||||||
|
"followed" => %{"nickname" => followed_nickname},
|
||||||
|
"follower" => %{"nickname" => follower_nickname}
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} made @#{follower_nickname} #{action} @#{followed_nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "delete",
|
||||||
|
"subject" => %{"nickname" => subject_nickname, "type" => "user"}
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} deleted user @#{subject_nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "create",
|
||||||
|
"subjects" => subjects
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
nicknames =
|
||||||
|
subjects
|
||||||
|
|> Enum.map(&"@#{&1["nickname"]}")
|
||||||
|
|> Enum.join(", ")
|
||||||
|
|
||||||
|
"@#{actor_nickname} created users: #{nicknames}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "activate",
|
||||||
|
"subject" => %{"nickname" => subject_nickname, "type" => "user"}
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} activated user @#{subject_nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "deactivate",
|
||||||
|
"subject" => %{"nickname" => subject_nickname, "type" => "user"}
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} deactivated user @#{subject_nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"nicknames" => nicknames,
|
||||||
|
"tags" => tags,
|
||||||
|
"action" => "tag"
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
nicknames_string =
|
||||||
|
nicknames
|
||||||
|
|> Enum.map(&"@#{&1}")
|
||||||
|
|> Enum.join(", ")
|
||||||
|
|
||||||
|
tags_string = tags |> Enum.join(", ")
|
||||||
|
|
||||||
|
"@#{actor_nickname} added tags: #{tags_string} to users: #{nicknames_string}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"nicknames" => nicknames,
|
||||||
|
"tags" => tags,
|
||||||
|
"action" => "untag"
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
nicknames_string =
|
||||||
|
nicknames
|
||||||
|
|> Enum.map(&"@#{&1}")
|
||||||
|
|> Enum.join(", ")
|
||||||
|
|
||||||
|
tags_string = tags |> Enum.join(", ")
|
||||||
|
|
||||||
|
"@#{actor_nickname} removed tags: #{tags_string} from users: #{nicknames_string}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "grant",
|
||||||
|
"subject" => %{"nickname" => subject_nickname},
|
||||||
|
"permission" => permission
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} made @#{subject_nickname} #{permission}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "revoke",
|
||||||
|
"subject" => %{"nickname" => subject_nickname},
|
||||||
|
"permission" => permission
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} revoked #{permission} role from @#{subject_nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "relay_follow",
|
||||||
|
"target" => target
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} followed relay: #{target}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "relay_unfollow",
|
||||||
|
"target" => target
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} unfollowed relay: #{target}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "report_update",
|
||||||
|
"subject" => %{"id" => subject_id, "state" => state, "type" => "report"}
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} updated report ##{subject_id} with '#{state}' state"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "report_response",
|
||||||
|
"subject" => %{"id" => subject_id, "type" => "report"},
|
||||||
|
"text" => text
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} responded with '#{text}' to report ##{subject_id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "status_update",
|
||||||
|
"subject" => %{"id" => subject_id, "type" => "status"},
|
||||||
|
"sensitive" => nil,
|
||||||
|
"visibility" => visibility
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} updated status ##{subject_id}, set visibility: '#{visibility}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "status_update",
|
||||||
|
"subject" => %{"id" => subject_id, "type" => "status"},
|
||||||
|
"sensitive" => sensitive,
|
||||||
|
"visibility" => nil
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} updated status ##{subject_id}, set sensitive: '#{sensitive}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "status_update",
|
||||||
|
"subject" => %{"id" => subject_id, "type" => "status"},
|
||||||
|
"sensitive" => sensitive,
|
||||||
|
"visibility" => visibility
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} updated status ##{subject_id}, set sensitive: '#{sensitive}', visibility: '#{
|
||||||
|
visibility
|
||||||
|
}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "status_delete",
|
||||||
|
"subject_id" => subject_id
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} deleted status ##{subject_id}"
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,26 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.AdminAPI.ModerationLogView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
|
||||||
|
alias Pleroma.ModerationLog
|
||||||
|
|
||||||
|
def render("index.json", %{log: log}) do
|
||||||
|
render_many(log, __MODULE__, "show.json", as: :log_entry)
|
||||||
|
end
|
||||||
|
|
||||||
|
def render("show.json", %{log_entry: log_entry}) do
|
||||||
|
time =
|
||||||
|
log_entry.inserted_at
|
||||||
|
|> DateTime.from_naive!("Etc/UTC")
|
||||||
|
|> DateTime.to_unix()
|
||||||
|
|
||||||
|
%{
|
||||||
|
data: log_entry.data,
|
||||||
|
time: time,
|
||||||
|
message: ModerationLog.get_log_entry_message(log_entry)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,11 @@
|
|||||||
|
defmodule Pleroma.Repo.Migrations.CreateModerationLog do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
create table(:moderation_log) do
|
||||||
|
add(:data, :map)
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,301 @@
|
|||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.ModerationLogTest do
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.ModerationLog
|
||||||
|
|
||||||
|
use Pleroma.DataCase
|
||||||
|
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
describe "user moderation" do
|
||||||
|
setup do
|
||||||
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
moderator = insert(:user, info: %{is_moderator: true})
|
||||||
|
subject1 = insert(:user)
|
||||||
|
subject2 = insert(:user)
|
||||||
|
|
||||||
|
[admin: admin, moderator: moderator, subject1: subject1, subject2: subject2]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user deletion by moderator", %{moderator: moderator, subject1: subject1} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
subject: subject1,
|
||||||
|
action: "delete"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} deleted user @#{subject1.nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user creation by moderator", %{
|
||||||
|
moderator: moderator,
|
||||||
|
subject1: subject1,
|
||||||
|
subject2: subject2
|
||||||
|
} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
subjects: [subject1, subject2],
|
||||||
|
action: "create"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} created users: @#{subject1.nickname}, @#{subject2.nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user follow by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
followed: subject1,
|
||||||
|
follower: subject2,
|
||||||
|
action: "follow"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{admin.nickname} made @#{subject2.nickname} follow @#{subject1.nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user unfollow by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
followed: subject1,
|
||||||
|
follower: subject2,
|
||||||
|
action: "unfollow"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{admin.nickname} made @#{subject2.nickname} unfollow @#{subject1.nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user tagged by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
nicknames: [subject1.nickname, subject2.nickname],
|
||||||
|
tags: ["foo", "bar"],
|
||||||
|
action: "tag"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
users =
|
||||||
|
[subject1.nickname, subject2.nickname]
|
||||||
|
|> Enum.map(&"@#{&1}")
|
||||||
|
|> Enum.join(", ")
|
||||||
|
|
||||||
|
tags = ["foo", "bar"] |> Enum.join(", ")
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{admin.nickname} added tags: #{tags} to users: #{users}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user untagged by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
nicknames: [subject1.nickname, subject2.nickname],
|
||||||
|
tags: ["foo", "bar"],
|
||||||
|
action: "untag"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
users =
|
||||||
|
[subject1.nickname, subject2.nickname]
|
||||||
|
|> Enum.map(&"@#{&1}")
|
||||||
|
|> Enum.join(", ")
|
||||||
|
|
||||||
|
tags = ["foo", "bar"] |> Enum.join(", ")
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{admin.nickname} removed tags: #{tags} from users: #{users}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user grant by moderator", %{moderator: moderator, subject1: subject1} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
subject: subject1,
|
||||||
|
action: "grant",
|
||||||
|
permission: "moderator"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} made @#{subject1.nickname} moderator"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging user revoke by moderator", %{moderator: moderator, subject1: subject1} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
subject: subject1,
|
||||||
|
action: "revoke",
|
||||||
|
permission: "moderator"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} revoked moderator role from @#{subject1.nickname}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging relay follow", %{moderator: moderator} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "relay_follow",
|
||||||
|
target: "https://example.org/relay"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} followed relay: https://example.org/relay"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging relay unfollow", %{moderator: moderator} do
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "relay_unfollow",
|
||||||
|
target: "https://example.org/relay"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} unfollowed relay: https://example.org/relay"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging report update", %{moderator: moderator} do
|
||||||
|
report = %Activity{
|
||||||
|
id: "9m9I1F4p8ftrTP6QTI",
|
||||||
|
data: %{
|
||||||
|
"type" => "Flag",
|
||||||
|
"state" => "resolved"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "report_update",
|
||||||
|
subject: report
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} updated report ##{report.id} with 'resolved' state"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging report response", %{moderator: moderator} do
|
||||||
|
report = %Activity{
|
||||||
|
id: "9m9I1F4p8ftrTP6QTI",
|
||||||
|
data: %{
|
||||||
|
"type" => "Note"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "report_response",
|
||||||
|
subject: report,
|
||||||
|
text: "look at this"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} responded with 'look at this' to report ##{report.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging status sensitivity update", %{moderator: moderator} do
|
||||||
|
note = insert(:note_activity)
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "status_update",
|
||||||
|
subject: note,
|
||||||
|
sensitive: "true",
|
||||||
|
visibility: nil
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true'"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging status visibility update", %{moderator: moderator} do
|
||||||
|
note = insert(:note_activity)
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "status_update",
|
||||||
|
subject: note,
|
||||||
|
sensitive: nil,
|
||||||
|
visibility: "private"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} updated status ##{note.id}, set visibility: 'private'"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging status sensitivity & visibility update", %{moderator: moderator} do
|
||||||
|
note = insert(:note_activity)
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "status_update",
|
||||||
|
subject: note,
|
||||||
|
sensitive: "true",
|
||||||
|
visibility: "private"
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true', visibility: 'private'"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging status deletion", %{moderator: moderator} do
|
||||||
|
note = insert(:note_activity)
|
||||||
|
|
||||||
|
{:ok, _} =
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: moderator,
|
||||||
|
action: "status_delete",
|
||||||
|
subject_id: note.id
|
||||||
|
})
|
||||||
|
|
||||||
|
log = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log) ==
|
||||||
|
"@#{moderator.nickname} deleted status ##{note.id}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in new issue