Add page for managing site-wide anonymous-blocks

This commit is contained in:
Karina Kwiatek 2022-08-13 20:01:22 +02:00
parent ae5d8931af
commit 136eac8bdd
10 changed files with 88 additions and 17 deletions

View File

@ -6,10 +6,12 @@ class Ajax::AnonymousBlockController < AjaxController
question = Question.find(params[:question]) question = Question.find(params[:question])
raise Errors::Forbidden if params[:global] && !current_user.has_role?(:moderator)
AnonymousBlock.create!( AnonymousBlock.create!(
user: current_user, user: params[:global] ? nil : current_user,
identifier: question.author_identifier, identifier: question.author_identifier,
question: question question:,
) )
question.inboxes.first.destroy question.inboxes.first.destroy

View File

@ -0,0 +1,5 @@
class Moderation::AnonymousBlockController < ApplicationController
def index
@anonymous_blocks = AnonymousBlock.where(user: nil)
end
end

View File

@ -0,0 +1,10 @@
- provide(:title, generate_title(t(".title")))
.container-lg.container--main
.card
.card-body
#entries
- if @anonymous_blocks.empty?
.text-center= t(".empty")
- @anonymous_blocks.each do |block|
= render "shared/anonymous_block", block:

View File

@ -32,7 +32,7 @@
= t(".unmask.enable") = t(".unmask.enable")
%a.dropdown-item{ href: mod_anon_block_index_path } %a.dropdown-item{ href: mod_anon_block_index_path }
%i.fa.fa-fw.fa-volume-off %i.fa.fa-fw.fa-volume-off
= t("views.navigation.blocks") = t(".site_wide_blocks")
%a.dropdown-item{ href: moderation_path } %a.dropdown-item{ href: moderation_path }
%i.fa.fa-fw.fa-gavel %i.fa.fa-fw.fa-gavel
= t(".moderation") = t(".moderation")

View File

@ -22,17 +22,7 @@
%p= t(".section.anon_blocks.body") %p= t(".section.anon_blocks.body")
%ul.list-group %ul.list-group
- @anonymous_blocks.each do |block| - @anonymous_blocks.each do |block|
%li.list-group-item = render "shared/anonymous_block", block:
.d-flex
%div
- if block.question.present?
%p.mb-0= block.question.content
- else
%p.mb-0.text-muted.font-italic= t(".deleted_question")
%p.text-muted.mb-0= t(".blocked", time: time_ago_in_words(block.created_at))
.ml-auto.d-inline-flex
%button.btn.btn-default.align-self-center{ data: { action: "anon-unblock", target: block.id } }
%span.pe-none= t("voc.unblock")
- if @anonymous_blocks.empty? - if @anonymous_blocks.empty?
%p.text-muted.text-center= t(".none") %p.text-muted.text-center= t(".none")

View File

@ -0,0 +1,11 @@
%li.list-group-item
.d-flex
%div
- if block.question.present?
%p.mb-0= block.question.content
- else
%p.mb-0.text-muted.font-italic= t(".deleted_question")
%p.text-muted.mb-0= t(".blocked", time: time_ago_in_words(block.created_at))
.ml-auto.d-inline-flex
%button.btn.btn-default.align-self-center{ data: { action: "anon-unblock", target: block.id } }
%span.pe-none= t("voc.unblock")

View File

@ -305,6 +305,7 @@ en:
heading: "Feedback" heading: "Feedback"
bugs: "Bugs" bugs: "Bugs"
features: "Feature Requests" features: "Feature Requests"
site_wide_blocks: "Site-wide anonymous blocks"
desktop: desktop:
ask_question: "Ask a question" ask_question: "Ask a question"
list: :user.actions.list list: :user.actions.list
@ -348,7 +349,6 @@ en:
blocks: blocks:
index: index:
title: "Blocks" title: "Blocks"
blocked: "blocked %{time} ago"
none: "You are not blocking anyone." none: "You are not blocking anyone."
section: section:
blocks: blocks:
@ -357,7 +357,6 @@ en:
anon_blocks: anon_blocks:
heading: "Anonymous Blocks" heading: "Anonymous Blocks"
body: "Each anonymous user you've blocked is listed here, along with a way to unblock them. We also display the question they asked you to add some more context. You can block anonymous users directly from the question in your inbox." body: "Each anonymous user you've blocked is listed here, along with a way to unblock them. We also display the question they asked you to add some more context. You can block anonymous users directly from the question in your inbox."
deleted_question: "Deleted question"
data: data:
index: index:
title: "Your Data" title: "Your Data"
@ -511,6 +510,9 @@ en:
source: "Source code" source: "Source code"
terms: "Terms of Service" terms: "Terms of Service"
privacy: "Privacy Policy" privacy: "Privacy Policy"
anonymous_block:
deleted_question: "Deleted question"
blocked: "blocked %{time} ago"
sidebar: sidebar:
list: list:
title: "Members" title: "Members"
@ -572,6 +574,10 @@ en:
heading: "Reason:" heading: "Reason:"
none: "No reason provided" none: "No reason provided"
view: "View reported %{content}" view: "View reported %{content}"
anonymous_block:
index:
title: "Site-wide anonymous blocks"
empty: "There are currently no users blocked site-wide."
user: user:
actions: actions:
view_inbox: "View inbox" view_inbox: "View inbox"

View File

@ -2,6 +2,7 @@ en:
voc: voc:
answer: "Answer" answer: "Answer"
block: "Block" block: "Block"
block_site_wide: "Block user site-wide"
cancel: "Cancel" cancel: "Cancel"
close: "Close" close: "Close"
confirm: "Are you sure?" confirm: "Are you sure?"

View File

@ -23,6 +23,7 @@ Rails.application.routes.draw do
# Routes only accessible by moderators (moderation panel) # Routes only accessible by moderators (moderation panel)
authenticate :user, ->(user) { user.mod? } do authenticate :user, ->(user) { user.mod? } do
post "/moderation/unmask", to: "moderation#toggle_unmask", as: :moderation_toggle_unmask post "/moderation/unmask", to: "moderation#toggle_unmask", as: :moderation_toggle_unmask
get "/moderation/blocks", to: "moderation/anonymous_block#index", as: :mod_anon_block_index
get "/moderation(/:type)", to: "moderation#index", as: :moderation, defaults: { type: "all" } get "/moderation(/:type)", to: "moderation#index", as: :moderation, defaults: { type: "all" }
get "/moderation/inbox/:user", to: "moderation/inbox#index", as: :mod_inbox_index get "/moderation/inbox/:user", to: "moderation/inbox#index", as: :mod_inbox_index
namespace :ajax do namespace :ajax do

View File

@ -13,7 +13,7 @@ describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
sign_in(user) sign_in(user)
end end
context "when all parameters are given" do context "when all required parameters are given" do
let(:question) { FactoryBot.create(:question, author_identifier: "someidentifier") } let(:question) { FactoryBot.create(:question, author_identifier: "someidentifier") }
let!(:inbox) { FactoryBot.create(:inbox, user: user, question: question) } let!(:inbox) { FactoryBot.create(:inbox, user: user, question: question) }
let(:params) do let(:params) do
@ -35,6 +35,51 @@ describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
include_examples "returns the expected response" include_examples "returns the expected response"
end end
context "when blocking a user globally" do
let(:question) { FactoryBot.create(:question, author_identifier: "someidentifier") }
let!(:inbox) { FactoryBot.create(:inbox, user: user, question: question) }
let(:params) do
{ question: question.id, global: "true" }
end
context "as a moderator" do
let(:expected_response) do
{
"success" => true,
"status" => "okay",
"message" => anything
}
end
before do
user.add_role(:moderator)
end
it "creates an site-wide anonymous block" do
expect { subject }.to(change { AnonymousBlock.count }.by(1))
expect(AnonymousBlock.last.user_id).to be_nil
end
include_examples "returns the expected response"
end
context "as a regular user" do
let(:expected_response) do
{
"success" => false,
"status" => "forbidden",
"message" => anything
}
end
it "does not create an anonymous block" do
expect { subject }.not_to(change { AnonymousBlock.count })
end
include_examples "returns the expected response"
end
end
context "when parameters are missing" do context "when parameters are missing" do
let(:params) { {} } let(:params) { {} }
let(:expected_response) do let(:expected_response) do