diff --git a/lib/action_account.rb b/lib/action_account.rb index 231f0c4fbf7..e756ae731ca 100644 --- a/lib/action_account.rb +++ b/lib/action_account.rb @@ -44,6 +44,8 @@ def banner * #{basename} reinstate-user uuid1 uuid2 * #{basename} confirm-suspend-user uuid1 uuid2 + + * #{basename} clear-device-profiling-failure uuid1 uuid2 Options: EOS end @@ -59,6 +61,7 @@ def subtask(name) 'suspend-user' => SuspendUser, 'reinstate-user' => ReinstateUser, 'confirm-suspend-user' => ConfirmSuspendUser, + 'clear-device-profiling-failure' => ClearDeviceProfilingFailure, }[name] end @@ -83,6 +86,9 @@ def log_text user_already_suspended: 'User has already been suspended', user_is_not_suspended: 'User is not suspended', user_already_reinstated: 'User has already been reinstated', + device_profiling_approved: 'Device profiling result has been updated to pass', + device_profiling_already_passed: 'Device profiling result already passed', + device_profiling_no_results_found: 'No device profiling results found for this user', } end end @@ -124,6 +130,19 @@ def perform_user_action(args:, config:, action:) else log_texts << log_text[:user_is_not_suspended] end + when :clear_device_profiling_failure + result = DeviceProfilingResult.where( + user_id: user.id, + profiling_type: DeviceProfilingResult::PROFILING_TYPES[:account_creation], + ).first + if result.nil? + log_texts << log_text[:device_profiling_no_results_found] + elsif result.review_status == 'pass' + log_texts << log_text[:device_profiling_already_passed] + else + result.update!(review_status: 'pass', notes: 'Manually overridden') + log_texts << log_text[:device_profiling_approved] + end else raise "unknown subtask=#{action}" end @@ -407,5 +426,16 @@ def run(args:, config:) ) end end + + class ClearDeviceProfilingFailure + include UserActions + def run(args:, config:) + perform_user_action( + args:, + config:, + action: :clear_device_profiling_failure, + ) + end + end end # rubocop:enable Metrics/BlockLength diff --git a/lib/tasks/device_profiling.rake b/lib/tasks/device_profiling.rake deleted file mode 100644 index e25f2ea8048..00000000000 --- a/lib/tasks/device_profiling.rake +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -namespace :device_profiling do - desc 'Approve rejected device profiling results to pass for list of UUIDs' - task :approve_rejected_users, [:user_uuids] => :environment do |_task, _args| - user_uuids = ARGV[1] - - if user_uuids.blank? - puts 'Error: user_uuids is required' - exit 1 - end - - # Parse UUIDs - uuid_list = user_uuids.split(',').map(&:strip).reject(&:blank?) - - puts "Processing #{uuid_list.count} user UUID(s)" - puts "Action: Change 'reject' to 'pass' (skip if already 'pass')" - puts '' - - total_users_processed = 0 - total_results_updated = 0 - skipped_already_passed = 0 - users_with_no_results = 0 - - uuid_list.each do |user_uuid| - total_users_processed += 1 - - begin - # Find user by UUID - user = User.find_by(uuid: user_uuid) - if user.blank? - puts "User not found: #{user_uuid}" - next - end - - # Find device profiling results for this user (reject or pass) - result = DeviceProfilingResult.where( - user_id: user.id, - profiling_type: DeviceProfilingResult::PROFILING_TYPES[:account_creation], - ).first - - if result.nil? - users_with_no_results += 1 - puts "No device profiling results found for: #{user_uuid} (#{user.email})" - next - end - - # Check if already passed - - if result.review_status == 'pass' - skipped_already_passed += 1 - puts "Already passed: #{user_uuid}" - next - end - - # Update rejected results to pass - puts "Updating rejected result for: #{user_uuid}" - result.update!(review_status: 'pass', notes: 'Manually overridden') - total_results_updated += 1 - - puts "Successfully updated result for: #{user_uuid}" - - # Log for audit - rescue => e - puts "Error processing #{user_uuid}: #{e.message}" - end - end - - puts '' - puts '=' * 80 - puts 'SUMMARY:' - puts "Total users processed: #{total_users_processed}" - puts "Results updated (reject → pass): #{total_results_updated}" - puts "Users already passed: #{skipped_already_passed}" - puts "Users with no results: #{users_with_no_results}" - - puts 'Task completed successfully!' - end -end diff --git a/spec/lib/action_account_spec.rb b/spec/lib/action_account_spec.rb index 5949dfed676..c11e8b52c33 100644 --- a/spec/lib/action_account_spec.rb +++ b/spec/lib/action_account_spec.rb @@ -457,4 +457,38 @@ end end end + + describe ActionAccount::ClearDeviceProfilingFailure do + subject(:subtask) { ActionAccount::ClearDeviceProfilingFailure.new } + + describe '#run' do + let(:user) { create(:user) } + let(:user2) { create(:user) } + let!(:device_profiling_result) do + create( + :device_profiling_result, + user:, + review_status: 'reject', + profiling_type: DeviceProfilingResult::PROFILING_TYPES[:account_creation], + ) + end + let(:args) { [user.uuid, user2.uuid] } + let(:include_missing) { true } + let(:config) { ScriptBase::Config.new(include_missing:) } + subject(:result) { subtask.run(args:, config:) } + + it 'clears device profiling failure for the user', aggregate_failures: true do + expect(result.table).to match_array( + [ + ['uuid', 'status', 'reason'], + [user.uuid, 'Device profiling result has been updated to pass', nil], + [user2.uuid, 'No device profiling results found for this user', nil], + ], + ) + + expect(result.subtask).to eq('clear-device-profiling-failure-user') + expect(result.uuids).to match_array([user.uuid, user2.uuid]) + end + end + end end