diff --git a/lib/philomena/users/ability.ex b/lib/philomena/users/ability.ex index 061d125c..211c834d 100644 --- a/lib/philomena/users/ability.ex +++ b/lib/philomena/users/ability.ex @@ -5,6 +5,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do alias Philomena.Images.Image alias Philomena.Forums.Forum alias Philomena.Topics.Topic + alias Philomena.Posts.Post alias Philomena.Filters.Filter alias Philomena.DnpEntries.DnpEntry @@ -85,6 +86,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do def can?(_user, :index, Forum), do: true def can?(_user, :show, %Forum{access_level: "normal"}), do: true def can?(_user, :show, %Topic{hidden_from_users: false}), do: true + def can?(_user, :show, %Post{hidden_from_users: false}), do: true # View profile pages def can?(_user, :show, %User{}), do: true diff --git a/lib/philomena_web/controllers/image/comment/report_controller.ex b/lib/philomena_web/controllers/image/comment/report_controller.ex new file mode 100644 index 00000000..ae8a00dd --- /dev/null +++ b/lib/philomena_web/controllers/image/comment/report_controller.ex @@ -0,0 +1,36 @@ +defmodule PhilomenaWeb.Image.Comment.ReportController do + use PhilomenaWeb, :controller + + alias PhilomenaWeb.ReportController + alias PhilomenaWeb.ReportView + alias Philomena.Comments.Comment + alias Philomena.Images.Image + alias Philomena.Reports.Report + alias Philomena.Reports + + plug PhilomenaWeb.FilterBannedUsersPlug + plug PhilomenaWeb.UserAttributionPlug + plug PhilomenaWeb.CaptchaPlug when action in [:create] + plug PhilomenaWeb.CanaryMapPlug, new: :show, create: :show + plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true, preload: [:tags] + plug :load_and_authorize_resource, model: Comment, id_name: "comment_id", persisted: true, preload: [:image] + + def new(conn, _params) do + comment = conn.assigns.comment + action = Routes.image_comment_report_path(conn, :create, comment.image, comment) + changeset = + %Report{reportable_type: "Comment", reportable_id: comment.id} + |> Reports.change_report() + + conn + |> put_view(ReportView) + |> render("new.html", reportable: comment, changeset: changeset, action: action) + end + + def create(conn, params) do + comment = conn.assigns.comment + action = Routes.image_comment_report_path(conn, :create, comment.image, comment) + + ReportController.create(conn, action, comment, "Comment", params) + end +end \ No newline at end of file diff --git a/lib/philomena_web/controllers/topic/post/report_controller.ex b/lib/philomena_web/controllers/topic/post/report_controller.ex new file mode 100644 index 00000000..20e6e23e --- /dev/null +++ b/lib/philomena_web/controllers/topic/post/report_controller.ex @@ -0,0 +1,85 @@ +defmodule PhilomenaWeb.Topic.Post.ReportController do + use PhilomenaWeb, :controller + + alias PhilomenaWeb.ReportController + alias PhilomenaWeb.ReportView + alias Philomena.Forums.Forum + alias Philomena.Topics.Topic + alias Philomena.Posts.Post + alias Philomena.Reports.Report + alias Philomena.Reports + alias Philomena.Repo + import Ecto.Query + + plug PhilomenaWeb.FilterBannedUsersPlug + plug PhilomenaWeb.UserAttributionPlug + plug PhilomenaWeb.CaptchaPlug when action in [:create] + plug PhilomenaWeb.CanaryMapPlug, new: :show, create: :show + plug :load_and_authorize_resource, model: Forum, id_name: "forum_id", id_field: "short_name", persisted: true + plug :load_topic + plug :load_post + + def new(conn, _params) do + topic = conn.assigns.topic + post = conn.assigns.post + action = Routes.forum_topic_post_report_path(conn, :create, topic.forum, topic, post) + changeset = + %Report{reportable_type: "Post", reportable_id: post.id} + |> Reports.change_report() + + conn + |> put_view(ReportView) + |> render("new.html", reportable: post, changeset: changeset, action: action) + end + + def create(conn, params) do + topic = conn.assigns.topic + post = conn.assigns.post + action = Routes.forum_topic_post_report_path(conn, :create, topic.forum, topic, post) + + ReportController.create(conn, action, post, "Post", params) + end + + defp load_topic(conn, _opts) do + user = conn.assigns.current_user + forum = conn.assigns.forum + topic = + Topic + |> where(forum_id: ^forum.id, slug: ^conn.params["topic_id"]) + |> preload(:forum) + |> Repo.one() + + cond do + is_nil(topic) -> + PhilomenaWeb.NotFoundPlug.call(conn) + + not Canada.Can.can?(user, :show, topic) -> + PhilomenaWeb.NotAuthorizedPlug.call(conn) + + true -> + Plug.Conn.assign(conn, :topic, topic) + end + end + + defp load_post(conn, _opts) do + user = conn.assigns.current_user + topic = conn.assigns.topic + + post = + Post + |> where(topic_id: ^topic.id, id: ^conn.params["post_id"]) + |> preload(topic: :forum) + |> Repo.one() + + cond do + is_nil(post) -> + PhilomenaWeb.NotFoundPlug.call(conn) + + not Canada.Can.can?(user, :show, post) -> + PhilomenaWeb.NotAuthorizedPlug.call(conn) + + true -> + Plug.Conn.assign(conn, :post, post) + end + end +end \ No newline at end of file diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index e2de7ac5..78686a42 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -129,7 +129,9 @@ defmodule PhilomenaWeb.Router do resources "/random", RandomController, only: [:index] end resources "/images", ImageController, only: [:index, :show, :new, :create] do - resources "/comments", Image.CommentController, only: [:index, :show, :create] + resources "/comments", Image.CommentController, only: [:index, :show, :create] do + resources "/reports", Image.Comment.ReportController, only: [:new, :create] + end resources "/tags", Image.TagController, only: [:update], singleton: true resources "/sources", Image.SourceController, only: [:update], singleton: true resources "/tag_changes", Image.TagChangeController, only: [:index] @@ -151,7 +153,9 @@ defmodule PhilomenaWeb.Router do resources "/search", SearchController, only: [:index] resources "/forums", ForumController, only: [:index, :show] do resources "/topics", TopicController, only: [:show] do - resources "/posts", Topic.PostController, only: [:create], singleton: true + resources "/posts", Topic.PostController, only: [:create] do + resources "/reports", Topic.Post.ReportController, only: [:new, :create] + end end end resources "/comments", CommentController, only: [:index] diff --git a/lib/philomena_web/templates/comment/_comment_options.html.slime b/lib/philomena_web/templates/comment/_comment_options.html.slime index 9ae1d97f..e5d41d30 100644 --- a/lib/philomena_web/templates/comment/_comment_options.html.slime +++ b/lib/philomena_web/templates/comment/_comment_options.html.slime @@ -1,9 +1,11 @@ div ' Posted => pretty_time(@comment.created_at) - /=<> link_to new_report_path(reportable_class: 'Comment', reportable_id: comment.id), class: 'communication__interaction' do - / i.fa.fa-flag - / =<> 'Report' + + a.communication__interaction href=Routes.image_comment_report_path(@conn, :new, @comment.image, @comment) + i.fa.fa-flag> + ' Report + /- if comment.edited_at && can?(:read, comment) / br / a href=image_comment_history_path(comment.image, comment) diff --git a/lib/philomena_web/templates/post/_post_options.html.slime b/lib/philomena_web/templates/post/_post_options.html.slime index b5bccffd..f0bc1374 100644 --- a/lib/philomena_web/templates/post/_post_options.html.slime +++ b/lib/philomena_web/templates/post/_post_options.html.slime @@ -1,9 +1,11 @@ div ' Posted => pretty_time(@post.created_at) - /=<> link_to new_report_path(reportable_class: 'Post', reportable_id: post.id), class: 'communication__interaction' do - / i.fa.fa-flag - / =<> 'Report' + + a.communication__interaction href=Routes.forum_topic_post_report_path(@conn, :new, @post.topic.forum, @post.topic, @post) + i.fa.fa-flag> + ' Report + /- if post.edited_at && can?(:read, post) / br / a href=forum_topic_post_history_path(post.topic.forum, post.topic, post) diff --git a/lib/philomena_web/views/report_view.ex b/lib/philomena_web/views/report_view.ex index 70b95db0..0905593f 100644 --- a/lib/philomena_web/views/report_view.ex +++ b/lib/philomena_web/views/report_view.ex @@ -40,22 +40,22 @@ defmodule PhilomenaWeb.ReportView do def pretty_state(%{state: "claimed"}), do: "Claimed" def pretty_state(_report), do: "Open" - def link_to_reported_thing(conn, %Image{} = r) when not is_nil(r), + def link_to_reported_thing(conn, %Image{} = r), do: link "Image >>#{r.id}", to: Routes.image_path(conn, :show, r) - def link_to_reported_thing(conn, %Comment{} = r) when not is_nil(r), - do: link "Comment on image >>#{r.image.id}", to: Routes.image_path(conn, :show, r.image) + def link_to_reported_thing(conn, %Comment{} = r), + do: link "Comment on image >>#{r.image.id}", to: Routes.image_path(conn, :show, r.image) <> "#comment_#{r.id}" - def link_to_reported_thing(conn, %Conversation{} = r) when not is_nil(r), + def link_to_reported_thing(conn, %Conversation{} = r), do: link "Conversation between #{r.from.name} and #{r.to.name}", to: Routes.conversation_path(conn, :show, r) - def link_to_reported_thing(conn, %Commission{} = r) when not is_nil(r), + def link_to_reported_thing(conn, %Commission{} = r), do: link "#{r.user}'s commission page", to: Routes.commission_path(conn, :show, r) - def link_to_reported_thing(conn, %Post{} = r) when not is_nil(r), + def link_to_reported_thing(conn, %Post{} = r), do: link "Post in #{r.topic.title}", to: Routes.forum_topic_path(conn, :show, r.topic.forum, r.topic, post_id: r.id) <> "#post_#{r.id}" - def link_to_reported_thing(conn, %User{} = r) when not is_nil(r), + def link_to_reported_thing(conn, %User{} = r), do: link "User '#{r.name}'", to: Routes.profile_path(conn, :show, r) def link_to_reported_thing(_conn, report) do