unsubscribe users from privileged topics when their role is updated, fixes #30

This commit is contained in:
byte[] 2020-04-29 23:05:19 -04:00
parent 1ef368c286
commit be520b1d7c
3 changed files with 36 additions and 5 deletions

View file

@ -9,6 +9,8 @@ defmodule Philomena.Users do
alias Philomena.Users.Uploader alias Philomena.Users.Uploader
alias Philomena.Users.User alias Philomena.Users.User
alias Philomena.{Forums, Forums.Forum}
alias Philomena.Topics
alias Philomena.Roles.Role alias Philomena.Roles.Role
use Pow.Ecto.Context, use Pow.Ecto.Context,
@ -80,9 +82,16 @@ defmodule Philomena.Users do
|> where([r], r.id in ^clean_roles(attrs["roles"])) |> where([r], r.id in ^clean_roles(attrs["roles"]))
|> Repo.all() |> Repo.all()
user changeset =
|> User.update_changeset(attrs, roles) user
|> Repo.update() |> User.update_changeset(attrs, roles)
Multi.new()
|> Multi.update(:user, changeset)
|> Multi.run(:unsubscribe, fn _repo, %{user: user} ->
unsubscribe_restricted_actors(user)
end)
|> Repo.isolated_transaction(:serializable)
end end
defp clean_roles(nil), do: [] defp clean_roles(nil), do: []
@ -215,4 +224,26 @@ defmodule Philomena.Users do
%{user | role_map: role_map} %{user | role_map: role_map}
end end
defp unsubscribe_restricted_actors(%User{} = user) do
forum_ids =
Forum
|> order_by(asc: :name)
|> Repo.all()
|> Enum.reject(&Canada.Can.can?(user, :show, &1))
|> Enum.map(& &1.id)
{_count, nil} =
Forums.Subscription
|> where([s], s.user_id == ^user.id and s.forum_id in ^forum_ids)
|> Repo.delete_all()
{_count, nil} =
Topics.Subscription
|> join(:inner, [s], _ in assoc(s, :topic))
|> where([s, t], s.user_id == ^user.id and t.forum_id in ^forum_ids)
|> Repo.delete_all()
{:ok, nil}
end
end end

View file

@ -64,7 +64,7 @@ defmodule PhilomenaWeb.Admin.UserController do
|> put_flash(:info, "User successfully updated.") |> put_flash(:info, "User successfully updated.")
|> redirect(to: Routes.admin_user_path(conn, :index)) |> redirect(to: Routes.admin_user_path(conn, :index))
{:error, changeset} -> {:error, %{user: changeset}} ->
render(conn, "edit.html", changeset: changeset) render(conn, "edit.html", changeset: changeset)
end end
end end

View file

@ -64,7 +64,7 @@ defmodule Search.Evaluator do
|> Enum.any?(&String.contains?(&1, query_val)) |> Enum.any?(&String.contains?(&1, query_val))
end end
def hits?(doc, %{nested: _}) do def hits?(_doc, %{nested: _}) do
# No way to tell without a wildly expensive database query # No way to tell without a wildly expensive database query
false false
end end