diff --git a/app/controllers/admin/watched_words_controller.rb b/app/controllers/admin/watched_words_controller.rb index 5423c329729..c2cdd25ea50 100644 --- a/app/controllers/admin/watched_words_controller.rb +++ b/app/controllers/admin/watched_words_controller.rb @@ -14,6 +14,7 @@ class Admin::WatchedWordsController < Admin::AdminController def create watched_word = WatchedWord.create_or_update_word(watched_words_params) if watched_word.valid? + StaffActionLogger.new(current_user).log_watched_words_creation(watched_word) render json: watched_word, root: false else render_json_error(watched_word) @@ -24,6 +25,7 @@ class Admin::WatchedWordsController < Admin::AdminController watched_word = WatchedWord.find_by(id: params[:id]) raise Discourse::InvalidParameters.new(:id) unless watched_word watched_word.destroy! + StaffActionLogger.new(current_user).log_watched_words_deletion(watched_word) render json: success_json end @@ -36,11 +38,14 @@ class Admin::WatchedWordsController < Admin::AdminController begin CSV.foreach(file.tempfile, encoding: "bom|utf-8") do |row| if row[0].present? && (!has_replacement || row[1].present?) - WatchedWord.create_or_update_word( + watched_word = WatchedWord.create_or_update_word( word: row[0], replacement: has_replacement ? row[1] : nil, action_key: action_key ) + if watched_word.valid? + StaffActionLogger.new(current_user).log_watched_words_creation(watched_word) + end end end @@ -79,7 +84,10 @@ class Admin::WatchedWordsController < Admin::AdminController action = WatchedWord.actions[name] raise Discourse::NotFound if !action - WatchedWord.where(action: action).delete_all + WatchedWord.where(action: action).find_each do |watched_word| + watched_word.destroy! + StaffActionLogger.new(current_user).log_watched_words_deletion(watched_word) + end WordWatcher.clear_cache! render json: success_json end diff --git a/app/models/user_history.rb b/app/models/user_history.rb index c84b326653b..a0403c7b48a 100644 --- a/app/models/user_history.rb +++ b/app/models/user_history.rb @@ -114,7 +114,9 @@ class UserHistory < ActiveRecord::Base topic_archived: 93, topic_unarchived: 94, post_staff_note_create: 95, - post_staff_note_destroy: 96 + post_staff_note_destroy: 96, + watched_word_create: 97, + watched_word_destroy: 98 ) end @@ -205,7 +207,9 @@ class UserHistory < ActiveRecord::Base :topic_archived, :topic_unarchived, :post_staff_note_create, - :post_staff_note_destroy + :post_staff_note_destroy, + :watched_word_create, + :watched_word_destroy ] end diff --git a/app/models/watched_word.rb b/app/models/watched_word.rb index 9251d7d2b6a..f08f523b1c8 100644 --- a/app/models/watched_word.rb +++ b/app/models/watched_word.rb @@ -68,10 +68,17 @@ class WatchedWord < ActiveRecord::Base self.action = self.class.actions[arg.to_sym] end + def action_log_details + if replacement.present? + "#{word} → #{replacement}" + else + word + end + end + def clear_cache WordWatcher.clear_cache! end - end # == Schema Information diff --git a/app/services/staff_action_logger.rb b/app/services/staff_action_logger.rb index e859f42cbdf..01c4e2bab10 100644 --- a/app/services/staff_action_logger.rb +++ b/app/services/staff_action_logger.rb @@ -803,6 +803,28 @@ class StaffActionLogger ) end + def log_watched_words_creation(watched_word) + raise Discourse::InvalidParameters.new(:watched_word) unless watched_word + + UserHistory.create!( + action: UserHistory.actions[:watched_word_create], + acting_user_id: @admin.id, + details: watched_word.action_log_details, + context: WatchedWord.actions[watched_word.action] + ) + end + + def log_watched_words_deletion(watched_word) + raise Discourse::InvalidParameters.new(:watched_word) unless watched_word + + UserHistory.create!( + action: UserHistory.actions[:watched_word_destroy], + acting_user_id: @admin.id, + details: watched_word.action_log_details, + context: WatchedWord.actions[watched_word.action] + ) + end + private def get_changes(changes) @@ -829,5 +851,4 @@ class StaffActionLogger def validate_category(category) raise Discourse::InvalidParameters.new(:category) unless category && category.is_a?(Category) end - end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 6d3f72afabd..58e07eaa28e 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -4699,6 +4699,8 @@ en: post_staff_note_create: "add staff note" post_staff_note_destroy: "destroy staff note" delete_group: "delete group" + add_watched_word: "add watched word" + delete_watched_word: "delete watched word" screened_emails: title: "Screened Emails" description: "When someone tries to create a new account, the following email addresses will be checked and the registration will be blocked, or some other action performed." diff --git a/spec/requests/admin/watched_words_controller_spec.rb b/spec/requests/admin/watched_words_controller_spec.rb index 417e19a0b0b..0acaea6dd78 100644 --- a/spec/requests/admin/watched_words_controller_spec.rb +++ b/spec/requests/admin/watched_words_controller_spec.rb @@ -24,6 +24,7 @@ RSpec.describe Admin::WatchedWordsController do expect(response.status).to eq(200) expect(WatchedWord.find_by(id: watched_word.id)).to eq(nil) + expect(UserHistory.where(action: UserHistory.actions[:watched_word_destroy]).count).to eq(1) end end @@ -47,6 +48,7 @@ RSpec.describe Admin::WatchedWordsController do ) expect(WatchedWord.pluck(:action).uniq).to eq([WatchedWord.actions[:flag]]) + expect(UserHistory.where(action: UserHistory.actions[:watched_word_create]).count).to eq(6) end it 'creates the words from the file' do @@ -64,6 +66,7 @@ RSpec.describe Admin::WatchedWordsController do ) expect(WatchedWord.pluck(:action).uniq).to eq([WatchedWord.actions[:tag]]) + expect(UserHistory.where(action: UserHistory.actions[:watched_word_create]).count).to eq(2) end end end @@ -129,6 +132,7 @@ RSpec.describe Admin::WatchedWordsController do delete "/admin/customize/watched_words/action/block.json" expect(response.status).to eq(200) expect(WatchedWord.pluck(:word)).not_to include(word.word) + expect(UserHistory.where(action: UserHistory.actions[:watched_word_destroy]).count).to eq(1) end it "doesn't delete words of multiple actions in one call" do @@ -140,6 +144,7 @@ RSpec.describe Admin::WatchedWordsController do all_words = WatchedWord.pluck(:word) expect(all_words).to include(block_word.word) expect(all_words).not_to include(flag_word.word) + expect(UserHistory.where(action: UserHistory.actions[:watched_word_destroy]).count).to eq(1) end end end diff --git a/spec/services/staff_action_logger_spec.rb b/spec/services/staff_action_logger_spec.rb index 1c0553734eb..d40d382a727 100644 --- a/spec/services/staff_action_logger_spec.rb +++ b/spec/services/staff_action_logger_spec.rb @@ -544,7 +544,6 @@ describe StaffActionLogger do expect(user_history.action).to eq(UserHistory.actions[:post_rejected]) expect(user_history.details).to include(reviewable.payload['raw']) end - end describe 'log_topic_closed' do @@ -617,4 +616,43 @@ describe StaffActionLogger do end end + describe '#log_watched_words_creation' do + fab!(:watched_word) { Fabricate(:watched_word, action: WatchedWord.actions[:block]) } + + it "raises an error when watched_word is missing" do + expect { logger.log_watched_words_creation(nil) }.to raise_error(Discourse::InvalidParameters) + end + + it "creates a new UserHistory record" do + logger.log_watched_words_creation(watched_word) + + expect(UserHistory.count).to eq(1) + user_history = UserHistory.last + + expect(user_history.subject).to eq(nil) + expect(user_history.details).to include(watched_word.word) + expect(user_history.context).to eq("block") + expect(user_history.action).to eq(UserHistory.actions[:watched_word_create]) + end + end + + describe '#log_watched_words_deletion' do + fab!(:watched_word) { Fabricate(:watched_word, action: WatchedWord.actions[:block]) } + + it "raises an error when watched_word is missing" do + expect { logger.log_watched_words_deletion(nil) }.to raise_error(Discourse::InvalidParameters) + end + + it "creates a new UserHistory record" do + logger.log_watched_words_deletion(watched_word) + + expect(UserHistory.count).to eq(1) + user_history = UserHistory.last + + expect(user_history.subject).to eq(nil) + expect(user_history.details).to include(watched_word.word) + expect(user_history.context).to eq("block") + expect(user_history.action).to eq(UserHistory.actions[:watched_word_destroy]) + end + end end