From 6a84d334093f99f5df914d4e93387044f3c5f5d2 Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 23 Mar 2021 01:25:43 -0500 Subject: [PATCH] Fix #4770: Allow flaggers to update flag reason. --- app/controllers/post_flags_controller.rb | 13 +++++ app/policies/post_flag_policy.rb | 14 +++++- app/views/post_flags/_reasons.html.erb | 4 ++ app/views/post_flags/edit.html.erb | 15 ++++++ test/functional/post_flags_controller_test.rb | 47 ++++++++++++++++++- test/functional/posts_controller_test.rb | 7 +++ 6 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 app/views/post_flags/edit.html.erb diff --git a/app/controllers/post_flags_controller.rb b/app/controllers/post_flags_controller.rb index fcb3b9dfa..ecd772784 100644 --- a/app/controllers/post_flags_controller.rb +++ b/app/controllers/post_flags_controller.rb @@ -31,4 +31,17 @@ class PostFlagsController < ApplicationController fmt.html { redirect_to post_flags_path(search: { id: @post_flag.id }) } end end + + def edit + @post_flag = authorize PostFlag.find(params[:id]) + respond_with(@post_flag) + end + + def update + @post_flag = authorize PostFlag.find(params[:id]) + @post_flag.update(permitted_attributes(@post_flag)) + respond_with(@post_flag) do |fmt| + fmt.html { redirect_to post_path(@post_flag.post) } + end + end end diff --git a/app/policies/post_flag_policy.rb b/app/policies/post_flag_policy.rb index d23f92f92..937439bbc 100644 --- a/app/policies/post_flag_policy.rb +++ b/app/policies/post_flag_policy.rb @@ -1,4 +1,12 @@ class PostFlagPolicy < ApplicationPolicy + def edit? + update? + end + + def update? + unbanned? && record.pending? && record.creator_id == user.id + end + def can_search_flagger? user.is_moderator? end @@ -7,10 +15,14 @@ class PostFlagPolicy < ApplicationPolicy (user.is_moderator? || record.creator_id == user.id) && (record.post&.uploader_id != user.id) end - def permitted_attributes + def permitted_attributes_for_create [:post_id, :reason] end + def permitted_attributes_for_update + [:reason] + end + def api_attributes attributes = super + [:category] attributes -= [:creator_id] unless can_view_flagger? diff --git a/app/views/post_flags/_reasons.html.erb b/app/views/post_flags/_reasons.html.erb index e9f8f1327..d899c2266 100644 --- a/app/views/post_flags/_reasons.html.erb +++ b/app/views/post_flags/_reasons.html.erb @@ -2,6 +2,10 @@
  • <%= format_text(flag.reason, inline: true) %> + <% if policy(flag).edit? %> + (<%= link_to "edit", edit_post_flag_url(flag) %>) + <% end %> + <% if policy(flag).can_view_flagger? %> (<%= link_to_user(flag.creator) %>, <%= time_ago_in_words_tagged(flag.created_at) %>) <% else %> diff --git a/app/views/post_flags/edit.html.erb b/app/views/post_flags/edit.html.erb new file mode 100644 index 000000000..ad878b25a --- /dev/null +++ b/app/views/post_flags/edit.html.erb @@ -0,0 +1,15 @@ +
    +
    +

    Edit Flag

    + +

    + Editing flag for <%= link_to "post ##{@post_flag.post_id}", @post_flag.post %>. +

    + + <%= edit_form_for(@post_flag) do |f| %> + <%= f.input :reason, as: :dtext, inline: true %> + <%= f.button :submit, "Submit" %> + <%= dtext_preview_button "post_flag_reason" %> + <% end %> +
    +
    diff --git a/test/functional/post_flags_controller_test.rb b/test/functional/post_flags_controller_test.rb index fe74264ea..31a930f45 100644 --- a/test/functional/post_flags_controller_test.rb +++ b/test/functional/post_flags_controller_test.rb @@ -8,7 +8,7 @@ class PostFlagsControllerTest < ActionDispatch::IntegrationTest @uploader = create(:mod_user, name: "chen", created_at: 2.weeks.ago) @mod = create(:mod_user) @post = create(:post, id: 101, is_flagged: true, uploader: @uploader) - @post_flag = create(:post_flag, post: @post, creator: @flagger) + @post_flag = create(:post_flag, reason: "xxx", post: @post, creator: @flagger) end context "new action" do @@ -118,5 +118,50 @@ class PostFlagsControllerTest < ActionDispatch::IntegrationTest end end end + + context "edit action" do + should "allow the flagger to edit the flag" do + get_auth edit_post_flag_path(@post_flag), @flagger + + assert_response :success + end + + should "not allow the flagger to edit a resolved flag" do + @post_flag.update!(status: "rejected") + get_auth edit_post_flag_path(@post_flag), @flagger + + assert_response 403 + end + + should "not allow other users to edit the flag" do + get_auth edit_post_flag_path(@post_flag), @mod + + assert_response 403 + end + end + + context "update action" do + should "allow the flagger to update the flag" do + put_auth post_flag_path(@post_flag), @flagger, params: { post_flag: { reason: "no" }} + + assert_redirected_to @post_flag.post + assert_equal("no", @post_flag.reload.reason) + end + + should "not allow the flagger to update a resolved flag" do + @post_flag.update!(status: "rejected") + put_auth post_flag_path(@post_flag), @flagger, params: { post_flag: { reason: "no" }} + + assert_response 403 + assert_equal("xxx", @post_flag.reload.reason) + end + + should "not allow other users to update the flag" do + put_auth post_flag_path(@post_flag), @mod, params: { post_flag: { reason: "no" }} + + assert_response 403 + assert_equal("xxx", @post_flag.reload.reason) + end + end end end diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb index 1c694e83a..097e03dac 100644 --- a/test/functional/posts_controller_test.rb +++ b/test/functional/posts_controller_test.rb @@ -549,6 +549,13 @@ class PostsControllerTest < ActionDispatch::IntegrationTest get_auth post_path(@post, q: "tagme"), @builder assert_response :success end + + should "render the flag edit link for the flagger" do + get_auth post_path(@post), @user + + assert_response :success + assert_select ".post-flag-reason a:first", true, text: "edit" + end end context "a deleted post" do