forked from mirrors/akkoma
Add logic for keeping follow_request_count up-to-date on the follow
,
`approve_friend_request`, and `deny_friend_request` actions. Add follow_request_count to the user view.
This commit is contained in:
parent
ea2698beb7
commit
ecdf0657ba
|
@ -618,6 +618,32 @@ def get_follow_requests_query(%User{} = user) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_follow_request_count(%User{} = user) do
|
||||||
|
subquery =
|
||||||
|
user
|
||||||
|
|> User.get_follow_requests_query()
|
||||||
|
|> select([a], %{count: count(a.id)})
|
||||||
|
|
||||||
|
User
|
||||||
|
|> where(id: ^user.id)
|
||||||
|
|> join(:inner, [u], s in subquery(subquery))
|
||||||
|
|> update([u, s],
|
||||||
|
set: [
|
||||||
|
info:
|
||||||
|
fragment(
|
||||||
|
"jsonb_set(?, '{follow_request_count}', ?::varchar::jsonb, true)",
|
||||||
|
u.info,
|
||||||
|
s.count
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|> Repo.update_all([], returning: true)
|
||||||
|
|> case do
|
||||||
|
{1, [user]} -> {:ok, user}
|
||||||
|
_ -> {:error, user}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def get_follow_requests(%User{} = user) do
|
def get_follow_requests(%User{} = user) do
|
||||||
q = get_follow_requests_query(user)
|
q = get_follow_requests_query(user)
|
||||||
reqs = Repo.all(q)
|
reqs = Repo.all(q)
|
||||||
|
|
|
@ -12,6 +12,7 @@ defmodule Pleroma.User.Info do
|
||||||
field(:source_data, :map, default: %{})
|
field(:source_data, :map, default: %{})
|
||||||
field(:note_count, :integer, default: 0)
|
field(:note_count, :integer, default: 0)
|
||||||
field(:follower_count, :integer, default: 0)
|
field(:follower_count, :integer, default: 0)
|
||||||
|
field(:follow_request_count, :integer, default: 0)
|
||||||
field(:locked, :boolean, default: false)
|
field(:locked, :boolean, default: false)
|
||||||
field(:confirmation_pending, :boolean, default: false)
|
field(:confirmation_pending, :boolean, default: false)
|
||||||
field(:confirmation_token, :string, default: nil)
|
field(:confirmation_token, :string, default: nil)
|
||||||
|
|
|
@ -172,9 +172,10 @@ def accept(%{to: to, actor: actor, object: object} = params) do
|
||||||
# only accept false as false value
|
# only accept false as false value
|
||||||
local = !(params[:local] == false)
|
local = !(params[:local] == false)
|
||||||
|
|
||||||
with data <- %{"to" => to, "type" => "Accept", "actor" => actor, "object" => object},
|
with data <- %{"to" => to, "type" => "Accept", "actor" => actor.ap_id, "object" => object},
|
||||||
{:ok, activity} <- insert(data, local),
|
{:ok, activity} <- insert(data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity),
|
||||||
|
_ <- User.update_follow_request_count(actor) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -183,9 +184,10 @@ def reject(%{to: to, actor: actor, object: object} = params) do
|
||||||
# only accept false as false value
|
# only accept false as false value
|
||||||
local = !(params[:local] == false)
|
local = !(params[:local] == false)
|
||||||
|
|
||||||
with data <- %{"to" => to, "type" => "Reject", "actor" => actor, "object" => object},
|
with data <- %{"to" => to, "type" => "Reject", "actor" => actor.ap_id, "object" => object},
|
||||||
{:ok, activity} <- insert(data, local),
|
{:ok, activity} <- insert(data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity),
|
||||||
|
_ <- User.update_follow_request_count(actor) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -283,7 +285,8 @@ def unannounce(
|
||||||
def follow(follower, followed, activity_id \\ nil, local \\ true) do
|
def follow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||||
with data <- make_follow_data(follower, followed, activity_id),
|
with data <- make_follow_data(follower, followed, activity_id),
|
||||||
{:ok, activity} <- insert(data, local),
|
{:ok, activity} <- insert(data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity),
|
||||||
|
_ <- User.update_follow_request_count(followed) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -293,7 +296,8 @@ def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||||
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
|
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
|
||||||
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
|
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
|
||||||
{:ok, activity} <- insert(unfollow_data, local),
|
{:ok, activity} <- insert(unfollow_data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity),
|
||||||
|
_ <- User.update_follow_request_count(followed) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -406,7 +406,7 @@ def handle_incoming(
|
||||||
if not User.locked?(followed) do
|
if not User.locked?(followed) do
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: data,
|
object: data,
|
||||||
local: true
|
local: true
|
||||||
})
|
})
|
||||||
|
@ -432,7 +432,7 @@ def handle_incoming(
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: follow_activity.data["to"],
|
to: follow_activity.data["to"],
|
||||||
type: "Accept",
|
type: "Accept",
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: follow_activity.data["id"],
|
object: follow_activity.data["id"],
|
||||||
local: false
|
local: false
|
||||||
}) do
|
}) do
|
||||||
|
@ -458,7 +458,7 @@ def handle_incoming(
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: follow_activity.data["to"],
|
to: follow_activity.data["to"],
|
||||||
type: "Reject",
|
type: "Reject",
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: follow_activity.data["id"],
|
object: follow_activity.data["id"],
|
||||||
local: false
|
local: false
|
||||||
}) do
|
}) do
|
||||||
|
|
|
@ -680,7 +680,7 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}
|
||||||
{:ok, _activity} <-
|
{:ok, _activity} <-
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: follow_activity.data["id"],
|
object: follow_activity.data["id"],
|
||||||
type: "Accept"
|
type: "Accept"
|
||||||
}) do
|
}) do
|
||||||
|
@ -702,7 +702,7 @@ def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) d
|
||||||
{:ok, _activity} <-
|
{:ok, _activity} <-
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: follow_activity.data["id"],
|
object: follow_activity.data["id"],
|
||||||
type: "Reject"
|
type: "Reject"
|
||||||
}) do
|
}) do
|
||||||
|
|
|
@ -570,7 +570,7 @@ def approve_friend_request(conn, %{"user_id" => uid} = _params) do
|
||||||
{:ok, _activity} <-
|
{:ok, _activity} <-
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: follow_activity.data["id"],
|
object: follow_activity.data["id"],
|
||||||
type: "Accept"
|
type: "Accept"
|
||||||
}) do
|
}) do
|
||||||
|
@ -590,7 +590,7 @@ def deny_friend_request(conn, %{"user_id" => uid} = _params) do
|
||||||
{:ok, _activity} <-
|
{:ok, _activity} <-
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
actor: followed.ap_id,
|
actor: followed,
|
||||||
object: follow_activity.data["id"],
|
object: follow_activity.data["id"],
|
||||||
type: "Reject"
|
type: "Reject"
|
||||||
}) do
|
}) do
|
||||||
|
|
|
@ -113,10 +113,12 @@ defp do_render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
"fields" => fields,
|
"fields" => fields,
|
||||||
|
|
||||||
# Pleroma extension
|
# Pleroma extension
|
||||||
"pleroma" => %{
|
"pleroma" =>
|
||||||
"confirmation_pending" => user_info.confirmation_pending,
|
%{
|
||||||
"tags" => user.tags
|
"confirmation_pending" => user_info.confirmation_pending,
|
||||||
}
|
"tags" => user.tags
|
||||||
|
}
|
||||||
|
|> maybe_with_follow_request_count(user, for_user)
|
||||||
}
|
}
|
||||||
|
|
||||||
data =
|
data =
|
||||||
|
@ -132,6 +134,14 @@ defp do_render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp maybe_with_follow_request_count(data, %User{id: id, info: %{locked: true}} = user, %User{
|
||||||
|
id: id
|
||||||
|
}) do
|
||||||
|
Map.put(data, "follow_request_count", user.info.follow_request_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_with_follow_request_count(data, _, _), do: data
|
||||||
|
|
||||||
defp maybe_with_role(data, %User{id: id} = user, %User{id: id}) do
|
defp maybe_with_role(data, %User{id: id} = user, %User{id: id}) do
|
||||||
Map.merge(data, %{"role" => role(user), "show_role" => user.info.show_role})
|
Map.merge(data, %{"role" => role(user), "show_role" => user.info.show_role})
|
||||||
end
|
end
|
||||||
|
|
|
@ -937,7 +937,7 @@ test "/api/v1/follow_requests works" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/api/v1/follow_requests/:id/authorize works" do
|
test "/api/v1/follow_requests/:id/authorize works" do
|
||||||
user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
|
user = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||||
|
@ -946,6 +946,7 @@ test "/api/v1/follow_requests/:id/authorize works" do
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
|
||||||
assert User.following?(other_user, user) == false
|
assert User.following?(other_user, user) == false
|
||||||
|
assert user.info.follow_request_count == 1
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -959,6 +960,7 @@ test "/api/v1/follow_requests/:id/authorize works" do
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
|
||||||
assert User.following?(other_user, user) == true
|
assert User.following?(other_user, user) == true
|
||||||
|
assert user.info.follow_request_count == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
test "verify_credentials", %{conn: conn} do
|
test "verify_credentials", %{conn: conn} do
|
||||||
|
@ -979,6 +981,9 @@ test "/api/v1/follow_requests/:id/reject works" do
|
||||||
|
|
||||||
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||||
|
|
||||||
|
user = Repo.get(User, user.id)
|
||||||
|
assert user.info.follow_request_count == 1
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|
@ -991,6 +996,7 @@ test "/api/v1/follow_requests/:id/reject works" do
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
|
||||||
assert User.following?(other_user, user) == false
|
assert User.following?(other_user, user) == false
|
||||||
|
assert user.info.follow_request_count == 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -640,6 +640,24 @@ test "with credentials", %{conn: conn, user: current_user} do
|
||||||
assert json_response(conn, 200) ==
|
assert json_response(conn, 200) ==
|
||||||
UserView.render("show.json", %{user: followed, for: current_user})
|
UserView.render("show.json", %{user: followed, for: current_user})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "for restricted account", %{conn: conn, user: current_user} do
|
||||||
|
followed = insert(:user, info: %User.Info{locked: true})
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> with_credentials(current_user.nickname, "test")
|
||||||
|
|> post("/api/friendships/create.json", %{user_id: followed.id})
|
||||||
|
|
||||||
|
current_user = Repo.get(User, current_user.id)
|
||||||
|
followed = Repo.get(User, followed.id)
|
||||||
|
|
||||||
|
refute User.ap_followers(followed) in current_user.following
|
||||||
|
assert followed.info.follow_request_count == 1
|
||||||
|
|
||||||
|
assert json_response(conn, 200) ==
|
||||||
|
UserView.render("show.json", %{user: followed, for: current_user})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /friendships/destroy.json" do
|
describe "POST /friendships/destroy.json" do
|
||||||
|
@ -1676,15 +1694,19 @@ test "it approves a friend request" do
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
|
||||||
assert User.following?(other_user, user) == false
|
assert User.following?(other_user, user) == false
|
||||||
|
assert user.info.follow_request_count == 1
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
|
|> post("/api/pleroma/friendships/approve", %{"user_id" => other_user.id})
|
||||||
|
|
||||||
|
user = Repo.get(User, user.id)
|
||||||
|
|
||||||
assert relationship = json_response(conn, 200)
|
assert relationship = json_response(conn, 200)
|
||||||
assert other_user.id == relationship["id"]
|
assert other_user.id == relationship["id"]
|
||||||
assert relationship["follows_you"] == true
|
assert relationship["follows_you"] == true
|
||||||
|
assert user.info.follow_request_count == 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1699,15 +1721,19 @@ test "it denies a friend request" do
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
|
||||||
assert User.following?(other_user, user) == false
|
assert User.following?(other_user, user) == false
|
||||||
|
assert user.info.follow_request_count == 1
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
|
|> post("/api/pleroma/friendships/deny", %{"user_id" => other_user.id})
|
||||||
|
|
||||||
|
user = Repo.get(User, user.id)
|
||||||
|
|
||||||
assert relationship = json_response(conn, 200)
|
assert relationship = json_response(conn, 200)
|
||||||
assert other_user.id == relationship["id"]
|
assert other_user.id == relationship["id"]
|
||||||
assert relationship["follows_you"] == false
|
assert relationship["follows_you"] == false
|
||||||
|
assert user.info.follow_request_count == 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue