From 339ce1c4e90605b736745b1f04493a247b2627ec Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 8 Mar 2020 15:17:39 +0100 Subject: Add specific rate limits for posting and following (#13172) --- config/initializers/rack_attack.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'config/initializers') diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 3cd7ea3a6..8bc1104d4 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -70,7 +70,6 @@ class Rack::Attack req.remote_ip if req.post? && req.path == '/api/v1/accounts' end - # Throttle paging, as it is mainly used for public pages and AP collections throttle('throttle_authenticated_paging', limit: 300, period: 15.minutes) do |req| req.authenticated_user_id if req.paging_request? end -- cgit From 56531d646ecd2d261740ea561afe23207416c548 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2020 12:04:54 +0900 Subject: Bump sidekiq from 5.2.7 to 6.0.4 (#11727) * Bump sidekiq from 5.2.7 to 6.0.0 Bumps [sidekiq](https://github.com/mperham/sidekiq) from 5.2.7 to 6.0.0. - [Release notes](https://github.com/mperham/sidekiq/releases) - [Changelog](https://github.com/mperham/sidekiq/blob/master/Changes.md) - [Commits](https://github.com/mperham/sidekiq/compare/v5.2.7...v6.0.0) Signed-off-by: dependabot-preview[bot] * Sidekiq::Logger.logger -> Sidekiq.logger * Drop support Ruby 2.4 * update Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Yamagishi Kazutoshi --- Gemfile | 2 +- Gemfile.lock | 12 ++++++------ config/initializers/sidekiq.rb | 2 +- spec/rails_helper.rb | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'config/initializers') diff --git a/Gemfile b/Gemfile index 04cf1d38e..91b45464a 100644 --- a/Gemfile +++ b/Gemfile @@ -84,7 +84,7 @@ gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' gem 'rqrcode', '~> 1.1' gem 'ruby-progressbar', '~> 1.10' gem 'sanitize', '~> 5.1' -gem 'sidekiq', '~> 5.2' +gem 'sidekiq', '~> 6.0' gem 'sidekiq-scheduler', '~> 3.0' gem 'sidekiq-unique-jobs', '~> 6.0' gem 'sidekiq-bulk', '~>0.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 1dacceaeb..63e78a4e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -562,11 +562,11 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.8.0) nokogumbo (~> 2.0) - sidekiq (5.2.7) - connection_pool (~> 2.2, >= 2.2.2) - rack (>= 1.5.0) - rack-protection (>= 1.5.0) - redis (>= 3.3.5, < 5) + sidekiq (6.0.4) + connection_pool (>= 2.2.2) + rack (>= 2.0.0) + rack-protection (>= 2.0.0) + redis (>= 4.1.0) sidekiq-bulk (0.2.0) sidekiq sidekiq-scheduler (3.0.1) @@ -767,7 +767,7 @@ DEPENDENCIES rubocop-rails (~> 2.4) ruby-progressbar (~> 1.10) sanitize (~> 5.1) - sidekiq (~> 5.2) + sidekiq (~> 6.0) sidekiq-bulk (~> 0.2.0) sidekiq-scheduler (~> 3.0) sidekiq-unique-jobs (~> 6.0) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 7f8a40d7b..288453a04 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -19,4 +19,4 @@ Sidekiq.configure_client do |config| config.redis = redis_params end -Sidekiq::Logging.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s) +Sidekiq.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6fbceca53..40ddf1f95 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -15,7 +15,7 @@ ActiveRecord::Migration.maintain_test_schema! WebMock.disable_net_connect!(allow: Chewy.settings[:host]) Redis.current = Redis::Namespace.new("mastodon_test#{ENV['TEST_ENV_NUMBER']}", redis: Redis.current) Sidekiq::Testing.inline! -Sidekiq::Logging.logger = nil +Sidekiq.logger = nil Devise::Test::ControllerHelpers.module_eval do alias_method :original_sign_in, :sign_in -- cgit From 7ddbbdea6d4591e6cfe032a0dd212703776e5bb4 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 27 Mar 2020 22:35:57 +0100 Subject: Fix OCR not working on Safari because of unsupported worker-src CSP (#13323) Fixes #13321 --- config/initializers/content_security_policy.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'config/initializers') diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index af7d16aaf..654e2e8cd 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -32,10 +32,12 @@ Rails.application.config.content_security_policy do |p| p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls p.script_src :self, :unsafe_inline, :unsafe_eval, assets_host + p.child_src :self, :blob, assets_host p.worker_src :self, :blob, assets_host else p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url p.script_src :self, assets_host + p.child_src :self, :blob, assets_host p.worker_src :self, :blob, assets_host end end -- cgit From 9241cbf8616cc58e0b909326a767fc59be9a9d58 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 31 Mar 2020 18:20:48 +0200 Subject: Fix re-sending of e-mail confirmation not being rate limited (#13360) Fix #13330 --- config/initializers/rack_attack.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'config/initializers') diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 8bc1104d4..09458c540 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -42,6 +42,7 @@ class Rack::Attack /auth/sign_in /auth /auth/password + /auth/confirmation ).freeze PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ }) -- cgit From 9014367bd87e07941134259d87f4d2c327ff37d4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 31 Mar 2020 21:59:03 +0200 Subject: Fix background jobs not using locks like they are supposed to (#13361) Also: - Fix locks not being removed when jobs go to the dead job queue - Add UI for managing locks to the Sidekiq dashboard - Remove unused Sidekiq workers Fix #13349 --- app/workers/activitypub/distribute_poll_update_worker.rb | 2 +- .../activitypub/synchronize_featured_collection_worker.rb | 2 +- app/workers/after_remote_follow_request_worker.rb | 9 --------- app/workers/after_remote_follow_worker.rb | 9 --------- app/workers/notification_worker.rb | 9 --------- app/workers/poll_expiration_notify_worker.rb | 2 +- app/workers/processing_worker.rb | 9 --------- app/workers/publish_scheduled_status_worker.rb | 2 +- app/workers/pubsubhubbub/confirmation_worker.rb | 9 --------- app/workers/pubsubhubbub/delivery_worker.rb | 9 --------- app/workers/pubsubhubbub/distribution_worker.rb | 9 --------- app/workers/pubsubhubbub/raw_distribution_worker.rb | 9 --------- app/workers/pubsubhubbub/subscribe_worker.rb | 9 --------- app/workers/pubsubhubbub/unsubscribe_worker.rb | 9 --------- app/workers/regeneration_worker.rb | 2 +- app/workers/remote_profile_update_worker.rb | 9 --------- app/workers/resolve_account_worker.rb | 2 +- app/workers/salmon_worker.rb | 9 --------- app/workers/scheduler/backup_cleanup_scheduler.rb | 2 +- app/workers/scheduler/doorkeeper_cleanup_scheduler.rb | 2 +- app/workers/scheduler/email_scheduler.rb | 2 +- app/workers/scheduler/feed_cleanup_scheduler.rb | 2 +- app/workers/scheduler/ip_cleanup_scheduler.rb | 2 +- app/workers/scheduler/media_cleanup_scheduler.rb | 2 +- app/workers/scheduler/pghero_scheduler.rb | 2 +- app/workers/scheduler/scheduled_statuses_scheduler.rb | 2 +- app/workers/scheduler/subscriptions_cleanup_scheduler.rb | 9 --------- app/workers/scheduler/subscriptions_scheduler.rb | 9 --------- app/workers/scheduler/trending_tags_scheduler.rb | 2 +- app/workers/scheduler/user_cleanup_scheduler.rb | 2 +- app/workers/verify_account_links_worker.rb | 2 +- config/initializers/sidekiq.rb | 5 +++++ config/routes.rb | 2 +- spec/services/import_service_spec.rb | 8 -------- 34 files changed, 23 insertions(+), 152 deletions(-) delete mode 100644 app/workers/after_remote_follow_request_worker.rb delete mode 100644 app/workers/after_remote_follow_worker.rb delete mode 100644 app/workers/notification_worker.rb delete mode 100644 app/workers/processing_worker.rb delete mode 100644 app/workers/pubsubhubbub/confirmation_worker.rb delete mode 100644 app/workers/pubsubhubbub/delivery_worker.rb delete mode 100644 app/workers/pubsubhubbub/distribution_worker.rb delete mode 100644 app/workers/pubsubhubbub/raw_distribution_worker.rb delete mode 100644 app/workers/pubsubhubbub/subscribe_worker.rb delete mode 100644 app/workers/pubsubhubbub/unsubscribe_worker.rb delete mode 100644 app/workers/remote_profile_update_worker.rb delete mode 100644 app/workers/salmon_worker.rb delete mode 100644 app/workers/scheduler/subscriptions_cleanup_scheduler.rb delete mode 100644 app/workers/scheduler/subscriptions_scheduler.rb (limited to 'config/initializers') diff --git a/app/workers/activitypub/distribute_poll_update_worker.rb b/app/workers/activitypub/distribute_poll_update_worker.rb index 1e87fa4bf..25dee4ee2 100644 --- a/app/workers/activitypub/distribute_poll_update_worker.rb +++ b/app/workers/activitypub/distribute_poll_update_worker.rb @@ -4,7 +4,7 @@ class ActivityPub::DistributePollUpdateWorker include Sidekiq::Worker include Payloadable - sidekiq_options queue: 'push', unique: :until_executed, retry: 0 + sidekiq_options queue: 'push', lock: :until_executed, retry: 0 def perform(status_id) @status = Status.find(status_id) diff --git a/app/workers/activitypub/synchronize_featured_collection_worker.rb b/app/workers/activitypub/synchronize_featured_collection_worker.rb index 7b16d3426..7a0898e89 100644 --- a/app/workers/activitypub/synchronize_featured_collection_worker.rb +++ b/app/workers/activitypub/synchronize_featured_collection_worker.rb @@ -3,7 +3,7 @@ class ActivityPub::SynchronizeFeaturedCollectionWorker include Sidekiq::Worker - sidekiq_options queue: 'pull', unique: :until_executed + sidekiq_options queue: 'pull', lock: :until_executed def perform(account_id) ActivityPub::FetchFeaturedCollectionService.new.call(Account.find(account_id)) diff --git a/app/workers/after_remote_follow_request_worker.rb b/app/workers/after_remote_follow_request_worker.rb deleted file mode 100644 index ce9c65834..000000000 --- a/app/workers/after_remote_follow_request_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class AfterRemoteFollowRequestWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull', retry: 5 - - def perform(follow_request_id); end -end diff --git a/app/workers/after_remote_follow_worker.rb b/app/workers/after_remote_follow_worker.rb deleted file mode 100644 index d9719f2bf..000000000 --- a/app/workers/after_remote_follow_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class AfterRemoteFollowWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull', retry: 5 - - def perform(follow_id); end -end diff --git a/app/workers/notification_worker.rb b/app/workers/notification_worker.rb deleted file mode 100644 index 1c0f001cf..000000000 --- a/app/workers/notification_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class NotificationWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push', retry: 5 - - def perform(xml, source_account_id, target_account_id); end -end diff --git a/app/workers/poll_expiration_notify_worker.rb b/app/workers/poll_expiration_notify_worker.rb index e08f0c249..64b4cbd7e 100644 --- a/app/workers/poll_expiration_notify_worker.rb +++ b/app/workers/poll_expiration_notify_worker.rb @@ -3,7 +3,7 @@ class PollExpirationNotifyWorker include Sidekiq::Worker - sidekiq_options unique: :until_executed + sidekiq_options lock: :until_executed def perform(poll_id) poll = Poll.find(poll_id) diff --git a/app/workers/processing_worker.rb b/app/workers/processing_worker.rb deleted file mode 100644 index cf3bd8397..000000000 --- a/app/workers/processing_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class ProcessingWorker - include Sidekiq::Worker - - sidekiq_options backtrace: true - - def perform(account_id, body); end -end diff --git a/app/workers/publish_scheduled_status_worker.rb b/app/workers/publish_scheduled_status_worker.rb index 850610c4e..ce42f7be7 100644 --- a/app/workers/publish_scheduled_status_worker.rb +++ b/app/workers/publish_scheduled_status_worker.rb @@ -3,7 +3,7 @@ class PublishScheduledStatusWorker include Sidekiq::Worker - sidekiq_options unique: :until_executed + sidekiq_options lock: :until_executed def perform(scheduled_status_id) scheduled_status = ScheduledStatus.find(scheduled_status_id) diff --git a/app/workers/pubsubhubbub/confirmation_worker.rb b/app/workers/pubsubhubbub/confirmation_worker.rb deleted file mode 100644 index 783a8c95f..000000000 --- a/app/workers/pubsubhubbub/confirmation_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Pubsubhubbub::ConfirmationWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push', retry: false - - def perform(subscription_id, mode, secret = nil, lease_seconds = nil); end -end diff --git a/app/workers/pubsubhubbub/delivery_worker.rb b/app/workers/pubsubhubbub/delivery_worker.rb deleted file mode 100644 index 1260060bd..000000000 --- a/app/workers/pubsubhubbub/delivery_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Pubsubhubbub::DeliveryWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push', retry: 3, dead: false - - def perform(subscription_id, payload); end -end diff --git a/app/workers/pubsubhubbub/distribution_worker.rb b/app/workers/pubsubhubbub/distribution_worker.rb deleted file mode 100644 index 75bac5d6f..000000000 --- a/app/workers/pubsubhubbub/distribution_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Pubsubhubbub::DistributionWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push' - - def perform(stream_entry_ids); end -end diff --git a/app/workers/pubsubhubbub/raw_distribution_worker.rb b/app/workers/pubsubhubbub/raw_distribution_worker.rb deleted file mode 100644 index ece9c80ac..000000000 --- a/app/workers/pubsubhubbub/raw_distribution_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Pubsubhubbub::RawDistributionWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push' - - def perform(xml, source_account_id); end -end diff --git a/app/workers/pubsubhubbub/subscribe_worker.rb b/app/workers/pubsubhubbub/subscribe_worker.rb deleted file mode 100644 index b861b5e67..000000000 --- a/app/workers/pubsubhubbub/subscribe_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Pubsubhubbub::SubscribeWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push', retry: 10, unique: :until_executed, dead: false - - def perform(account_id); end -end diff --git a/app/workers/pubsubhubbub/unsubscribe_worker.rb b/app/workers/pubsubhubbub/unsubscribe_worker.rb deleted file mode 100644 index 0c1c263f6..000000000 --- a/app/workers/pubsubhubbub/unsubscribe_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Pubsubhubbub::UnsubscribeWorker - include Sidekiq::Worker - - sidekiq_options queue: 'push', retry: false, unique: :until_executed, dead: false - - def perform(account_id); end -end diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb index 5c6a040bd..5c13c894f 100644 --- a/app/workers/regeneration_worker.rb +++ b/app/workers/regeneration_worker.rb @@ -3,7 +3,7 @@ class RegenerationWorker include Sidekiq::Worker - sidekiq_options unique: :until_executed + sidekiq_options lock: :until_executed def perform(account_id, _ = :home) account = Account.find(account_id) diff --git a/app/workers/remote_profile_update_worker.rb b/app/workers/remote_profile_update_worker.rb deleted file mode 100644 index 01e8daf8f..000000000 --- a/app/workers/remote_profile_update_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class RemoteProfileUpdateWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull' - - def perform(account_id, body, resubscribe); end -end diff --git a/app/workers/resolve_account_worker.rb b/app/workers/resolve_account_worker.rb index cd7c4d7dd..2b5be6d1b 100644 --- a/app/workers/resolve_account_worker.rb +++ b/app/workers/resolve_account_worker.rb @@ -3,7 +3,7 @@ class ResolveAccountWorker include Sidekiq::Worker - sidekiq_options queue: 'pull', unique: :until_executed + sidekiq_options queue: 'pull', lock: :until_executed def perform(uri) ResolveAccountService.new.call(uri) diff --git a/app/workers/salmon_worker.rb b/app/workers/salmon_worker.rb deleted file mode 100644 index 10200b06c..000000000 --- a/app/workers/salmon_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class SalmonWorker - include Sidekiq::Worker - - sidekiq_options backtrace: true - - def perform(account_id, body); end -end diff --git a/app/workers/scheduler/backup_cleanup_scheduler.rb b/app/workers/scheduler/backup_cleanup_scheduler.rb index d43660699..d69ca2556 100644 --- a/app/workers/scheduler/backup_cleanup_scheduler.rb +++ b/app/workers/scheduler/backup_cleanup_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::BackupCleanupScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform old_backups.reorder(nil).find_each(&:destroy!) diff --git a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb index e5e5f6bc4..94788a85b 100644 --- a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb +++ b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::DoorkeeperCleanupScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all diff --git a/app/workers/scheduler/email_scheduler.rb b/app/workers/scheduler/email_scheduler.rb index 1eeeee412..9a7355524 100644 --- a/app/workers/scheduler/email_scheduler.rb +++ b/app/workers/scheduler/email_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::EmailScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 FREQUENCY = 7.days.freeze SIGN_IN_OFFSET = 1.day.freeze diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb index bf5e20757..458fe6193 100644 --- a/app/workers/scheduler/feed_cleanup_scheduler.rb +++ b/app/workers/scheduler/feed_cleanup_scheduler.rb @@ -4,7 +4,7 @@ class Scheduler::FeedCleanupScheduler include Sidekiq::Worker include Redisable - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform clean_home_feeds! diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb index 4f44078d8..6d38b52a2 100644 --- a/app/workers/scheduler/ip_cleanup_scheduler.rb +++ b/app/workers/scheduler/ip_cleanup_scheduler.rb @@ -5,7 +5,7 @@ class Scheduler::IpCleanupScheduler RETENTION_PERIOD = 1.year - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform time_ago = RETENTION_PERIOD.ago diff --git a/app/workers/scheduler/media_cleanup_scheduler.rb b/app/workers/scheduler/media_cleanup_scheduler.rb index fb01aa70c..671ebf6e0 100644 --- a/app/workers/scheduler/media_cleanup_scheduler.rb +++ b/app/workers/scheduler/media_cleanup_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::MediaCleanupScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform unattached_media.find_each(&:destroy) diff --git a/app/workers/scheduler/pghero_scheduler.rb b/app/workers/scheduler/pghero_scheduler.rb index 4453bf2cd..cf5570048 100644 --- a/app/workers/scheduler/pghero_scheduler.rb +++ b/app/workers/scheduler/pghero_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::PgheroScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform PgHero.capture_space_stats diff --git a/app/workers/scheduler/scheduled_statuses_scheduler.rb b/app/workers/scheduler/scheduled_statuses_scheduler.rb index 9cfe949de..25df3c07d 100644 --- a/app/workers/scheduler/scheduled_statuses_scheduler.rb +++ b/app/workers/scheduler/scheduled_statuses_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::ScheduledStatusesScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform publish_scheduled_statuses! diff --git a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb deleted file mode 100644 index 75fe681a9..000000000 --- a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Scheduler::SubscriptionsCleanupScheduler - include Sidekiq::Worker - - sidekiq_options unique: :until_executed, retry: 0 - - def perform; end -end diff --git a/app/workers/scheduler/subscriptions_scheduler.rb b/app/workers/scheduler/subscriptions_scheduler.rb deleted file mode 100644 index 6903cadc7..000000000 --- a/app/workers/scheduler/subscriptions_scheduler.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class Scheduler::SubscriptionsScheduler - include Sidekiq::Worker - - sidekiq_options unique: :until_executed, retry: 0 - - def perform; end -end diff --git a/app/workers/scheduler/trending_tags_scheduler.rb b/app/workers/scheduler/trending_tags_scheduler.rb index 77f0d5747..e9891424e 100644 --- a/app/workers/scheduler/trending_tags_scheduler.rb +++ b/app/workers/scheduler/trending_tags_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::TrendingTagsScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform TrendingTags.update! if Setting.trends diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb index 881b911be..6113edde1 100644 --- a/app/workers/scheduler/user_cleanup_scheduler.rb +++ b/app/workers/scheduler/user_cleanup_scheduler.rb @@ -3,7 +3,7 @@ class Scheduler::UserCleanupScheduler include Sidekiq::Worker - sidekiq_options unique: :until_executed, retry: 0 + sidekiq_options lock: :until_executed, retry: 0 def perform User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch| diff --git a/app/workers/verify_account_links_worker.rb b/app/workers/verify_account_links_worker.rb index 901498583..8114d59be 100644 --- a/app/workers/verify_account_links_worker.rb +++ b/app/workers/verify_account_links_worker.rb @@ -3,7 +3,7 @@ class VerifyAccountLinksWorker include Sidekiq::Worker - sidekiq_options queue: 'pull', retry: false, unique: :until_executed + sidekiq_options queue: 'pull', retry: false, lock: :until_executed def perform(account_id) account = Account.find(account_id) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 288453a04..f2733562f 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -13,6 +13,11 @@ Sidekiq.configure_server do |config| config.server_middleware do |chain| chain.add SidekiqErrorHandler end + + config.death_handlers << lambda do |job, _ex| + digest = job['lock_digest'] + SidekiqUniqueJobs::Digests.delete_by_digest(digest) if digest + end end Sidekiq.configure_client do |config| diff --git a/config/routes.rb b/config/routes.rb index 89d446d10..49ab851e2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'sidekiq/web' +require 'sidekiq_unique_jobs/web' require 'sidekiq-scheduler/web' Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base] diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index 5355133f4..7618e9076 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -91,10 +91,6 @@ RSpec.describe ImportService, type: :service do let(:csv) { attachment_fixture('mute-imports.txt') } - before do - allow(NotificationWorker).to receive(:perform_async) - end - describe 'when no accounts are followed' do let(:import) { Import.create(account: account, type: 'following', data: csv) } it 'follows the listed accounts, including boosts' do @@ -135,10 +131,6 @@ RSpec.describe ImportService, type: :service do let(:csv) { attachment_fixture('new-following-imports.txt') } - before do - allow(NotificationWorker).to receive(:perform_async) - end - describe 'when no accounts are followed' do let(:import) { Import.create(account: account, type: 'following', data: csv) } it 'follows the listed accounts, respecting boosts' do -- cgit From f65568f1d400be2e101bd8b533a1b53807f5c757 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 3 Apr 2020 13:06:34 +0200 Subject: Add ability to filter audit log in admin UI (#13381) --- app/controllers/admin/action_logs_controller.rb | 14 +- app/helpers/admin/action_logs_helper.rb | 75 +------ app/helpers/admin/filter_helper.rb | 1 + app/javascript/packs/admin.js | 4 + app/javascript/styles/mastodon/admin.scss | 68 ++----- app/models/admin/action_log_filter.rb | 81 ++++++++ app/views/admin/accounts/show.html.haml | 2 +- app/views/admin/action_logs/_action_log.html.haml | 6 - app/views/admin/action_logs/index.html.haml | 24 ++- config/initializers/kaminari_config.rb | 2 +- config/locales/en.yml | 39 ++++ spec/helpers/admin/action_log_helper_spec.rb | 238 ---------------------- 12 files changed, 177 insertions(+), 377 deletions(-) create mode 100644 app/models/admin/action_log_filter.rb (limited to 'config/initializers') diff --git a/app/controllers/admin/action_logs_controller.rb b/app/controllers/admin/action_logs_controller.rb index e273dfeae..2d77620df 100644 --- a/app/controllers/admin/action_logs_controller.rb +++ b/app/controllers/admin/action_logs_controller.rb @@ -2,8 +2,18 @@ module Admin class ActionLogsController < BaseController - def index - @action_logs = Admin::ActionLog.page(params[:page]) + before_action :set_action_logs + + def index; end + + private + + def set_action_logs + @action_logs = Admin::ActionLogFilter.new(filter_params).results.page(params[:page]) + end + + def filter_params + params.slice(:page, *Admin::ActionLogFilter::KEYS).permit(:page, *Admin::ActionLogFilter::KEYS) end end end diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index 6bc75aa56..88d6e4580 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -9,79 +9,8 @@ module Admin::ActionLogsHelper end end - def relevant_log_changes(log) - if log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action) - log.recorded_changes.slice('domain') - elsif log.target_type == 'CustomEmoji' && log.action == :update - log.recorded_changes.slice('domain', 'visible_in_picker') - elsif log.target_type == 'User' && [:promote, :demote].include?(log.action) - log.recorded_changes.slice('moderator', 'admin') - elsif log.target_type == 'User' && [:change_email].include?(log.action) - log.recorded_changes.slice('email', 'unconfirmed_email') - elsif log.target_type == 'DomainBlock' - log.recorded_changes.slice('severity', 'reject_media') - elsif log.target_type == 'Status' && log.action == :update - log.recorded_changes.slice('sensitive') - elsif log.target_type == 'Announcement' && log.action == :update - log.recorded_changes.slice('text', 'starts_at', 'ends_at', 'all_day') - end - end - - def log_extra_attributes(hash) - safe_join(hash.to_a.map { |key, value| safe_join([content_tag(:span, key, class: 'diff-key'), '=', log_change(value)]) }, ' ') - end - - def log_change(val) - return content_tag(:span, val, class: 'diff-neutral') unless val.is_a?(Array) - safe_join([content_tag(:span, val.first, class: 'diff-old'), content_tag(:span, val.last, class: 'diff-new')], '→') - end - - def icon_for_log(log) - case log.target_type - when 'Account', 'User' - 'user' - when 'CustomEmoji' - 'file' - when 'Report' - 'flag' - when 'DomainBlock' - 'lock' - when 'DomainAllow' - 'plus-circle' - when 'EmailDomainBlock' - 'envelope' - when 'Status' - 'pencil' - when 'AccountWarning' - 'warning' - when 'Announcement' - 'bullhorn' - end - end - - def class_for_log_icon(log) - case log.action - when :enable, :unsuspend, :unsilence, :confirm, :promote, :resolve - 'positive' - when :create - opposite_verbs?(log) ? 'negative' : 'positive' - when :update, :reset_password, :disable_2fa, :memorialize, :change_email - 'neutral' - when :demote, :silence, :disable, :suspend, :remove_avatar, :remove_header, :reopen - 'negative' - when :destroy - opposite_verbs?(log) ? 'positive' : 'negative' - else - '' - end - end - private - def opposite_verbs?(log) - %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type) - end - def linkable_log_target(record) case record.class.name when 'Account' @@ -99,7 +28,7 @@ module Admin::ActionLogsHelper when 'AccountWarning' link_to record.target_account.acct, admin_account_path(record.target_account_id) when 'Announcement' - link_to "##{record.id}", edit_admin_announcement_path(record.id) + link_to truncate(record.text), edit_admin_announcement_path(record.id) end end @@ -118,7 +47,7 @@ module Admin::ActionLogsHelper I18n.t('admin.action_logs.deleted_status') end when 'Announcement' - "##{attributes['id']}" + truncate(attributes['text']) end end end diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb index 6ab92939d..ba0ca9638 100644 --- a/app/helpers/admin/filter_helper.rb +++ b/app/helpers/admin/filter_helper.rb @@ -10,6 +10,7 @@ module Admin::FilterHelper InviteFilter::KEYS, RelationshipFilter::KEYS, AnnouncementFilter::KEYS, + Admin::ActionLogFilter::KEYS, ].flatten.freeze def filter_link_to(text, link_to_params, link_class_params = link_to_params) diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.js index 061287f89..51f92de8a 100644 --- a/app/javascript/packs/admin.js +++ b/app/javascript/packs/admin.js @@ -30,6 +30,10 @@ delegate(document, '.media-spoiler-hide-button', 'click', () => { }); }); +delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => { + target.form.submit(); +}); + const onDomainBlockSeverityChange = (target) => { const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media'); const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports'); diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index b0307fb71..cee44f436 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -418,6 +418,11 @@ body, } } + &--with-select strong { + display: block; + margin-bottom: 10px; + } + a { display: inline-block; color: $darker-text-color; @@ -551,19 +556,22 @@ body, } .log-entry { - margin-bottom: 20px; line-height: 20px; + padding: 15px 0; + background: $ui-base-color; + border-bottom: 1px solid lighten($ui-base-color, 4%); + + &:last-child { + border-bottom: 0; + } &__header { display: flex; justify-content: flex-start; align-items: center; - padding: 10px; - background: $ui-base-color; color: $darker-text-color; - border-radius: 4px 4px 0 0; font-size: 14px; - position: relative; + padding: 0 10px; } &__avatar { @@ -590,44 +598,6 @@ body, color: $dark-text-color; } - &__extras { - background: lighten($ui-base-color, 6%); - border-radius: 0 0 4px 4px; - padding: 10px; - color: $darker-text-color; - font-family: $font-monospace, monospace; - font-size: 12px; - word-wrap: break-word; - min-height: 20px; - } - - &__icon { - font-size: 28px; - margin-right: 10px; - color: $dark-text-color; - } - - &__icon__overlay { - position: absolute; - top: 10px; - right: 10px; - width: 10px; - height: 10px; - border-radius: 50%; - - &.positive { - background: $success-green; - } - - &.negative { - background: lighten($error-red, 12%); - } - - &.neutral { - background: $ui-highlight-color; - } - } - a, .username, .target { @@ -635,18 +605,6 @@ body, text-decoration: none; font-weight: 500; } - - .diff-old { - color: lighten($error-red, 12%); - } - - .diff-neutral { - color: $secondary-text-color; - } - - .diff-new { - color: $success-green; - } } a.name-tag, diff --git a/app/models/admin/action_log_filter.rb b/app/models/admin/action_log_filter.rb new file mode 100644 index 000000000..0ba7e1609 --- /dev/null +++ b/app/models/admin/action_log_filter.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +class Admin::ActionLogFilter + KEYS = %i( + action_type + account_id + target_account_id + ).freeze + + ACTION_TYPE_MAP = { + assigned_to_self_report: { target_type: 'Report', action: 'assigned_to_self' }.freeze, + change_email_user: { target_type: 'User', action: 'change_email' }.freeze, + confirm_user: { target_type: 'User', action: 'confirm' }.freeze, + create_account_warning: { target_type: 'AccountWarning', action: 'create' }.freeze, + create_announcement: { target_type: 'Announcement', action: 'create' }.freeze, + create_custom_emoji: { target_type: 'CustomEmoji', action: 'create' }.freeze, + create_domain_allow: { target_type: 'DomainAllow', action: 'create' }.freeze, + create_domain_block: { target_type: 'DomainBlock', action: 'create' }.freeze, + create_email_domain_block: { target_type: 'EmailDomainBlock', action: 'create' }.freeze, + demote_user: { target_type: 'User', action: 'demote' }.freeze, + destroy_announcement: { target_type: 'Announcement', action: 'destroy' }.freeze, + destroy_custom_emoji: { target_type: 'CustomEmoji', action: 'destroy' }.freeze, + destroy_domain_allow: { target_type: 'DomainAllow', action: 'destroy' }.freeze, + destroy_domain_block: { target_type: 'DomainBlock', action: 'destroy' }.freeze, + destroy_email_domain_block: { target_type: 'EmailDomainBlock', action: 'destroy' }.freeze, + destroy_status: { target_type: 'Status', action: 'destroy' }.freeze, + disable_2fa_user: { target_type: 'User', action: 'disable' }.freeze, + disable_custom_emoji: { target_type: 'CustomEmoji', action: 'disable' }.freeze, + disable_user: { target_type: 'User', action: 'disable' }.freeze, + enable_custom_emoji: { target_type: 'CustomEmoji', action: 'enable' }.freeze, + enable_user: { target_type: 'User', action: 'enable' }.freeze, + memorialize_account: { target_type: 'Account', action: 'memorialize' }.freeze, + promote_user: { target_type: 'User', action: 'promote' }.freeze, + remove_avatar_user: { target_type: 'User', action: 'remove_avatar' }.freeze, + reopen_report: { target_type: 'Report', action: 'reopen' }.freeze, + reset_password_user: { target_type: 'User', action: 'reset_password' }.freeze, + resolve_report: { target_type: 'Report', action: 'resolve' }.freeze, + silence_account: { target_type: 'Account', action: 'silence' }.freeze, + suspend_account: { target_type: 'Account', action: 'suspend' }.freeze, + unassigned_report: { target_type: 'Report', action: 'unassigned' }.freeze, + unsilence_account: { target_type: 'Account', action: 'unsilence' }.freeze, + unsuspend_account: { target_type: 'Account', action: 'unsuspend' }.freeze, + update_announcement: { target_type: 'Announcement', action: 'update' }.freeze, + update_custom_emoji: { target_type: 'CustomEmoji', action: 'update' }.freeze, + update_status: { target_type: 'Status', action: 'update' }.freeze, + }.freeze + + attr_reader :params + + def initialize(params) + @params = params + end + + def results + scope = Admin::ActionLog.includes(:target) + + params.each do |key, value| + next if key.to_s == 'page' + + scope.merge!(scope_for(key.to_s, value.to_s.strip)) if value.present? + end + + scope + end + + private + + def scope_for(key, value) + case key + when 'action_type' + Admin::ActionLog.where(ACTION_TYPE_MAP[value.to_sym]) + when 'account_id' + Admin::ActionLog.where(account_id: value) + when 'target_account_id' + account = Account.find(value) + Admin::ActionLog.where(target: [account, account.user].compact) + else + raise "Unknown filter: #{key}" + end + end +end diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 744d17d1f..965fd6fb6 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -53,7 +53,7 @@ .dashboard__counters__num= number_with_delimiter @account.targeted_reports.count .dashboard__counters__label= t '.targeted_reports' %div - %div + = link_to admin_action_logs_path(target_account_id: @account.id) do .dashboard__counters__text - if @account.local? && @account.user.nil? %span.neutral= t('admin.accounts.deleted') diff --git a/app/views/admin/action_logs/_action_log.html.haml b/app/views/admin/action_logs/_action_log.html.haml index a545e189e..59905f341 100644 --- a/app/views/admin/action_logs/_action_log.html.haml +++ b/app/views/admin/action_logs/_action_log.html.haml @@ -7,9 +7,3 @@ = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')).html_safe .log-entry__timestamp %time.formatted{ datetime: action_log.created_at.iso8601 } - .spacer - .log-entry__icon - = fa_icon icon_for_log(action_log) - .log-entry__icon__overlay{ class: class_for_log_icon(action_log) } - .log-entry__extras - = log_extra_attributes relevant_log_changes(action_log) diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml index a4d3871a9..99f756762 100644 --- a/app/views/admin/action_logs/index.html.haml +++ b/app/views/admin/action_logs/index.html.haml @@ -1,6 +1,28 @@ - content_for :page_title do = t('admin.action_logs.title') -= render @action_logs +- content_for :header_tags do + = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous' + += form_tag admin_action_logs_url, method: 'GET', class: 'simple_form' do + = hidden_field_tag :target_account_id, params[:target_account_id] if params[:target_account_id].present? + + .filters + .filter-subset.filter-subset--with-select + %strong= t('admin.action_logs.filter_by_user') + .input.select.optional + = select_tag :account_id, options_from_collection_for_select(Account.joins(:user).merge(User.staff), :id, :username, params[:account_id]), prompt: I18n.t('admin.accounts.moderation.all') + + .filter-subset.filter-subset--with-select + %strong= t('admin.action_logs.filter_by_action') + .input.select.optional + = select_tag :action_type, options_for_select(Admin::ActionLogFilter::ACTION_TYPE_MAP.keys.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key]}, params[:action_type]), prompt: I18n.t('admin.accounts.moderation.all') + +- if @action_logs.empty? + %div.muted-hint.center-text + = t 'admin.action_logs.empty' +- else + .announcements-list + = render @action_logs = paginate @action_logs diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb index aa1517256..4fec4320c 100644 --- a/config/initializers/kaminari_config.rb +++ b/config/initializers/kaminari_config.rb @@ -2,6 +2,6 @@ Kaminari.configure do |config| config.default_per_page = 40 - config.window = 1 + config.window = 2 config.outer_window = 1 end diff --git a/config/locales/en.yml b/config/locales/en.yml index ef21fa54a..d07c4bb99 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -195,6 +195,42 @@ en: web: Web whitelisted: Whitelisted action_logs: + action_types: + assigned_to_self_report: Assign Report + change_email_user: Change E-mail for User + confirm_user: Confirm User + create_account_warning: Create Warning + create_announcement: Create Announcement + create_custom_emoji: Create Custom Emoji + create_domain_allow: Create Domain Allow + create_domain_block: Create Domain Block + create_email_domain_block: Create E-mail Domain Block + demote_user: Demote User + destroy_announcement: Delete Announcement + destroy_custom_emoji: Delete Custom Emoji + destroy_domain_allow: Delete Domain Allow + destroy_domain_block: Delete Domain Block + destroy_email_domain_block: Delete e-mail domain block + destroy_status: Delete Status + disable_2fa_user: Disable 2FA + disable_custom_emoji: Disable Custom Emoji + disable_user: Disable User + enable_custom_emoji: Enable Custom Emoji + enable_user: Enable User + memorialize_account: Memorialize Account + promote_user: Promote User + remove_avatar_user: Remove Avatar + reopen_report: Reopen Report + reset_password_user: Reset Password + resolve_report: Resolve Report + silence_account: Silence Account + suspend_account: Suspend Account + unassigned_report: Unassign Report + unsilence_account: Unsilence Account + unsuspend_account: Unsuspend Account + update_announcement: Update Announcement + update_custom_emoji: Update Custom Emoji + update_status: Update Status actions: assigned_to_self_report: "%{name} assigned report %{target} to themselves" change_email_user: "%{name} changed the e-mail address of user %{target}" @@ -232,6 +268,9 @@ en: update_custom_emoji: "%{name} updated emoji %{target}" update_status: "%{name} updated status by %{target}" deleted_status: "(deleted status)" + empty: No logs found. + filter_by_action: Filter by action + filter_by_user: Filter by user title: Audit log announcements: destroyed_msg: Announcement successfully deleted! diff --git a/spec/helpers/admin/action_log_helper_spec.rb b/spec/helpers/admin/action_log_helper_spec.rb index d7af6b939..60f5ecdcc 100644 --- a/spec/helpers/admin/action_log_helper_spec.rb +++ b/spec/helpers/admin/action_log_helper_spec.rb @@ -31,242 +31,4 @@ RSpec.describe Admin::ActionLogsHelper, type: :helper do end end end - - describe '#relevant_log_changes' do - let(:log) { double(target_type: target_type, action: log_action, recorded_changes: recorded_changes) } - let(:recorded_changes) { double } - - after do - hoge.relevant_log_changes(log) - end - - context "log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action)" do - let(:target_type) { 'CustomEmoji' } - let(:log_action) { :enable } - - it "calls log.recorded_changes.slice('domain')" do - expect(recorded_changes).to receive(:slice).with('domain') - end - end - - context "log.target_type == 'CustomEmoji' && log.action == :update" do - let(:target_type) { 'CustomEmoji' } - let(:log_action) { :update } - - it "calls log.recorded_changes.slice('domain', 'visible_in_picker')" do - expect(recorded_changes).to receive(:slice).with('domain', 'visible_in_picker') - end - end - - context "log.target_type == 'User' && [:promote, :demote].include?(log.action)" do - let(:target_type) { 'User' } - let(:log_action) { :promote } - - it "calls log.recorded_changes.slice('moderator', 'admin')" do - expect(recorded_changes).to receive(:slice).with('moderator', 'admin') - end - end - - context "log.target_type == 'User' && [:change_email].include?(log.action)" do - let(:target_type) { 'User' } - let(:log_action) { :change_email } - - it "calls log.recorded_changes.slice('email', 'unconfirmed_email')" do - expect(recorded_changes).to receive(:slice).with('email', 'unconfirmed_email') - end - end - - context "log.target_type == 'DomainBlock'" do - let(:target_type) { 'DomainBlock' } - let(:log_action) { nil } - - it "calls log.recorded_changes.slice('severity', 'reject_media')" do - expect(recorded_changes).to receive(:slice).with('severity', 'reject_media') - end - end - - context "log.target_type == 'Status' && log.action == :update" do - let(:target_type) { 'Status' } - let(:log_action) { :update } - - it "log.recorded_changes.slice('sensitive')" do - expect(recorded_changes).to receive(:slice).with('sensitive') - end - end - end - - describe '#log_extra_attributes' do - after do - hoge.log_extra_attributes(hoge: 'hoge') - end - - it "calls content_tag(:span, key, class: 'diff-key')" do - allow(hoge).to receive(:log_change).with(anything) - expect(hoge).to receive(:content_tag).with(:span, :hoge, class: 'diff-key') - end - - it 'calls safe_join twice' do - expect(hoge).to receive(:safe_join).with( - ['hoge', - '=', - 'hoge'] - ) - - expect(hoge).to receive(:safe_join).with([nil], ' ') - end - end - - describe '#log_change' do - after do - hoge.log_change(val) - end - - context '!val.is_a?(Array)' do - let(:val) { 'hoge' } - - it "calls content_tag(:span, val, class: 'diff-neutral')" do - expect(hoge).to receive(:content_tag).with(:span, val, class: 'diff-neutral') - end - end - - context 'val.is_a?(Array)' do - let(:val) { %w(foo bar) } - - it 'calls #content_tag twice and #safe_join' do - expect(hoge).to receive(:content_tag).with(:span, 'foo', class: 'diff-old') - expect(hoge).to receive(:content_tag).with(:span, 'bar', class: 'diff-new') - expect(hoge).to receive(:safe_join).with([nil, nil], '→') - end - end - end - - describe '#icon_for_log' do - subject { hoge.icon_for_log(log) } - - context "log.target_type == 'Account'" do - let(:log) { double(target_type: 'Account') } - - it 'returns "user"' do - expect(subject).to be 'user' - end - end - - context "log.target_type == 'User'" do - let(:log) { double(target_type: 'User') } - - it 'returns "user"' do - expect(subject).to be 'user' - end - end - - context "log.target_type == 'CustomEmoji'" do - let(:log) { double(target_type: 'CustomEmoji') } - - it 'returns "file"' do - expect(subject).to be 'file' - end - end - - context "log.target_type == 'Report'" do - let(:log) { double(target_type: 'Report') } - - it 'returns "flag"' do - expect(subject).to be 'flag' - end - end - - context "log.target_type == 'DomainBlock'" do - let(:log) { double(target_type: 'DomainBlock') } - - it 'returns "lock"' do - expect(subject).to be 'lock' - end - end - - context "log.target_type == 'EmailDomainBlock'" do - let(:log) { double(target_type: 'EmailDomainBlock') } - - it 'returns "envelope"' do - expect(subject).to be 'envelope' - end - end - - context "log.target_type == 'Status'" do - let(:log) { double(target_type: 'Status') } - - it 'returns "pencil"' do - expect(subject).to be 'pencil' - end - end - end - - describe '#class_for_log_icon' do - subject { hoge.class_for_log_icon(log) } - - %i(enable unsuspend unsilence confirm promote resolve).each do |action| - context "log.action == #{action}" do - let(:log) { double(action: action) } - - it 'returns "positive"' do - expect(subject).to be 'positive' - end - end - end - - context 'log.action == :create' do - context 'opposite_verbs?(log)' do - let(:log) { double(action: :create, target_type: 'DomainBlock') } - - it 'returns "negative"' do - expect(subject).to be 'negative' - end - end - - context '!opposite_verbs?(log)' do - let(:log) { double(action: :create, target_type: '') } - - it 'returns "positive"' do - expect(subject).to be 'positive' - end - end - end - - %i(update reset_password disable_2fa memorialize change_email).each do |action| - context "log.action == #{action}" do - let(:log) { double(action: action) } - - it 'returns "neutral"' do - expect(subject).to be 'neutral' - end - end - end - - %i(demote silence disable suspend remove_avatar remove_header reopen).each do |action| - context "log.action == #{action}" do - let(:log) { double(action: action) } - - it 'returns "negative"' do - expect(subject).to be 'negative' - end - end - end - - context 'log.action == :destroy' do - context 'opposite_verbs?(log)' do - let(:log) { double(action: :destroy, target_type: 'DomainBlock') } - - it 'returns "positive"' do - expect(subject).to be 'positive' - end - end - - context '!opposite_verbs?(log)' do - let(:log) { double(action: :destroy, target_type: '') } - - it 'returns "negative"' do - expect(subject).to be 'negative' - end - end - end - end end -- cgit