From be520b1d7c752f5bbde41ed478f5c1badb423166 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Wed, 29 Apr 2020 23:05:19 -0400 Subject: [PATCH] unsubscribe users from privileged topics when their role is updated, fixes #30 --- lib/philomena/users.ex | 37 +++++++++++++++++-- .../controllers/admin/user_controller.ex | 2 +- lib/search/evaluator.ex | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/philomena/users.ex b/lib/philomena/users.ex index 4c3a4622..d02e3657 100644 --- a/lib/philomena/users.ex +++ b/lib/philomena/users.ex @@ -9,6 +9,8 @@ defmodule Philomena.Users do alias Philomena.Users.Uploader alias Philomena.Users.User + alias Philomena.{Forums, Forums.Forum} + alias Philomena.Topics alias Philomena.Roles.Role use Pow.Ecto.Context, @@ -80,9 +82,16 @@ defmodule Philomena.Users do |> where([r], r.id in ^clean_roles(attrs["roles"])) |> Repo.all() - user - |> User.update_changeset(attrs, roles) - |> Repo.update() + changeset = + user + |> 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 defp clean_roles(nil), do: [] @@ -215,4 +224,26 @@ defmodule Philomena.Users do %{user | role_map: role_map} 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 diff --git a/lib/philomena_web/controllers/admin/user_controller.ex b/lib/philomena_web/controllers/admin/user_controller.ex index 8fa7e7f4..8bc6a920 100644 --- a/lib/philomena_web/controllers/admin/user_controller.ex +++ b/lib/philomena_web/controllers/admin/user_controller.ex @@ -64,7 +64,7 @@ defmodule PhilomenaWeb.Admin.UserController do |> put_flash(:info, "User successfully updated.") |> redirect(to: Routes.admin_user_path(conn, :index)) - {:error, changeset} -> + {:error, %{user: changeset}} -> render(conn, "edit.html", changeset: changeset) end end diff --git a/lib/search/evaluator.ex b/lib/search/evaluator.ex index aa1f4fdc..51f483e2 100644 --- a/lib/search/evaluator.ex +++ b/lib/search/evaluator.ex @@ -64,7 +64,7 @@ defmodule Search.Evaluator do |> Enum.any?(&String.contains?(&1, query_val)) end - def hits?(doc, %{nested: _}) do + def hits?(_doc, %{nested: _}) do # No way to tell without a wildly expensive database query false end