Merge pull request #780 from Retrospring/feature/inbox-locking

This commit is contained in:
Andreas Nedbal 2022-11-13 15:01:08 +01:00 committed by GitHub
commit b1c0ba470c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 69 additions and 15 deletions

View file

@ -6,7 +6,8 @@ class Settings::PrivacyController < ApplicationController
def edit; end
def update
user_attributes = params.require(:user).permit(:privacy_allow_anonymous_questions,
user_attributes = params.require(:user).permit(:privacy_lock_inbox,
:privacy_allow_anonymous_questions,
:privacy_allow_public_timeline,
:privacy_allow_stranger_answers,
:privacy_show_in_search)

View file

@ -169,6 +169,10 @@ class User < ApplicationRecord
!self.export_processing
end
def inbox_locked?
privacy_lock_inbox
end
# %w[admin moderator].each do |m|
# define_method(m) { raise "not allowed: #{m}" }
# define_method(m+??) { raise "not allowed: #{m}?"}

View file

@ -14,6 +14,9 @@
- elsif user_signed_in? && user.blocking?(current_user)
.text-center
%strong= t(".status.blocked")
- elsif user.inbox_locked?
.text-center
%strong= t(".status.locked")
- else
- if user_signed_in? || user.privacy_allow_anonymous_questions?
#question-box{ data: { controller: "character-count", "character-count-max-value": 512 }}

View file

@ -1,6 +1,7 @@
.card
.card-body
= bootstrap_form_for(current_user, url: settings_privacy_path, method: :patch, data: { turbo: false }) do |f|
= f.check_box :privacy_lock_inbox
= f.check_box :privacy_allow_anonymous_questions
= f.check_box :privacy_allow_public_timeline
= f.check_box :privacy_allow_stranger_answers

View file

@ -12,6 +12,7 @@ class QuestionWorker
question = Question.find(question_id)
user.followers.each do |f|
next if f.inbox_locked?
next if f.banned?
next if MuteRule.where(user: f).any? { |rule| rule.applies_to? question }

View file

@ -67,6 +67,7 @@ en:
remember_created_at: "Remember me set at"
password: "Password"
password_confirmation: "Confirm your password"
privacy_lock_inbox: "Lock inbox and don't allow new questions"
privacy_allow_anonymous_questions: "Allow anonymous questions"
privacy_allow_public_timeline: "Show your answers in the public timeline"
privacy_allow_stranger_answers: "Allow other people to answer your questions"

View file

@ -6,6 +6,7 @@ en:
param_is_missing: "param is missing"
forbidden: "This is illegal, you know"
inbox_locked: "This user currently does not accept questions"
blocked: "You have been blocked from performing this request"
other_blocked_self: "You have been blocked by this user"
asking_other_blocked_self: "You have been blocked from asking this user questions"

View file

@ -123,6 +123,7 @@ en:
banned: "This user got hit with ye olde banhammer."
blocking: "You are blocking this user."
blocked: "This user has blocked you."
locked: "This user currently does not accept questions."
devise:
registrations:
edit:

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class AddInboxLockedToUsers < ActiveRecord::Migration[6.1]
def up
add_column :users, :privacy_lock_inbox, :boolean, default: false
end
def down
remove_column :users, :privacy_lock_inbox
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2022_08_20_163035) do
ActiveRecord::Schema.define(version: 2022_11_06_130744) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -31,8 +31,8 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.string "identifier"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "question_id"
t.bigint "user_id"
t.bigint "question_id"
t.index ["identifier"], name: "index_anonymous_blocks_on_identifier"
t.index ["question_id"], name: "index_anonymous_blocks_on_question_id"
t.index ["user_id"], name: "index_anonymous_blocks_on_user_id"
@ -46,8 +46,6 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "smile_count", default: 0, null: false
t.datetime "deleted_at"
t.index ["deleted_at"], name: "index_answers_on_deleted_at"
t.index ["question_id"], name: "index_answers_on_question_id"
t.index ["user_id", "created_at"], name: "index_answers_on_user_id_and_created_at"
end
@ -60,8 +58,6 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.text "content"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.datetime "deleted_at"
t.index ["deleted_at"], name: "index_appendables_on_deleted_at"
t.index ["parent_id", "parent_type"], name: "index_appendables_on_parent_id_and_parent_type"
t.index ["user_id", "created_at"], name: "index_appendables_on_user_id_and_created_at"
end
@ -73,9 +69,7 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "smile_count", default: 0, null: false
t.datetime "deleted_at"
t.index ["answer_id"], name: "index_comments_on_answer_id"
t.index ["deleted_at"], name: "index_comments_on_deleted_at"
t.index ["user_id", "created_at"], name: "index_comments_on_user_id_and_created_at"
end
@ -108,10 +102,10 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
end
create_table "mute_rules", id: :bigint, default: -> { "gen_timestamp_id('mute_rules'::text)" }, force: :cascade do |t|
t.bigint "user_id"
t.string "muted_phrase"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "user_id"
t.index ["user_id"], name: "index_mute_rules_on_user_id"
end
@ -150,8 +144,6 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.datetime "updated_at"
t.integer "answer_count", default: 0, null: false
t.boolean "direct", default: false, null: false
t.datetime "deleted_at"
t.index ["deleted_at"], name: "index_questions_on_deleted_at"
t.index ["user_id", "created_at"], name: "index_questions_on_user_id_and_created_at"
end
@ -300,9 +292,8 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.datetime "export_created_at"
t.string "otp_secret_key"
t.integer "otp_module", default: 0, null: false
t.datetime "deleted_at"
t.boolean "privacy_lock_inbox", default: false
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["deleted_at"], name: "index_users_on_deleted_at"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["screen_name"], name: "index_users_on_screen_name", unique: true
@ -316,5 +307,7 @@ ActiveRecord::Schema.define(version: 2022_08_20_163035) do
t.index ["user_id"], name: "index_users_roles_on_user_id"
end
add_foreign_key "anonymous_blocks", "questions"
add_foreign_key "anonymous_blocks", "users"
add_foreign_key "profiles", "users"
end

View file

@ -35,6 +35,9 @@ module Errors
class SelfAction < Forbidden
end
class InboxLocked < Forbidden
end
class FollowingSelf < SelfAction
end

View file

@ -14,6 +14,7 @@ module UseCase
option :direct, type: Types::Params::Bool, default: proc { true }
def call
check_lock
check_anonymous_rules
check_blocks
@ -42,6 +43,10 @@ module UseCase
private
def check_lock
raise Errors::InboxLocked if target_user.inbox_locked?
end
def check_anonymous_rules
if !source_user_id && !anonymous
# We can not create a non-anonymous question without a source user

View file

@ -328,6 +328,23 @@ describe Ajax::QuestionController, :ajax_controller, type: :controller do
include_examples "does not create the question"
end
end
context "when users inbox is locked" do
let(:user_allows_anonymous_questions) { true }
let(:expected_response) do
{
"success" => false,
"status" => "inbox_locked",
"message" => anything
}
end
before do
target_user.update(privacy_lock_inbox: true)
end
include_examples "does not create the question"
end
end
context "when rcpt is followers" do

View file

@ -6,7 +6,7 @@ describe QuestionWorker do
describe "#perform" do
let(:user) { FactoryBot.create(:user) }
let(:user_id) { user.id }
let(:question) { FactoryBot.create(:question, user: user) }
let(:question) { FactoryBot.create(:question, user:) }
let(:question_id) { question.id }
before do
@ -41,6 +41,18 @@ describe QuestionWorker do
)
end
it "respects inbox locks" do
user.followers.first.update(privacy_lock_inbox: true)
expect { subject }
.to(
change { Inbox.where(user_id: user.followers.ids, question_id:, new: true).count }
.from(0)
.to(4)
)
end
it "does not send questions to banned users" do
user.followers.first.ban