Fix admin deletion of banned users being skipped

What does this MR do and why?

DeleteUserWorker#skip_own_account_deletion? unconditionally skipped deletion for any banned user, even when the deletion was admin- initiated rather than the result of the user deleting their own account. This meant admins deleting a banned user via the Admin UI saw the deletion appear to succeed while the user record was never actually removed.

The banned branch now also checks deleted_own_account?, mirroring the non-banned branch, so the self-deletion grace period still applies to users who initiated their own deletion, but admin- initiated deletions of banned users proceed normally.

References

Screenshots or screen recordings

Before After

How to set up and validate locally

  1. Start on the master branch.

  2. Enable Admin Area > Settings > General > Account and limit > "User account deletion will be delayed for 7 days"

  3. Ban a user via the Admin UI.

  4. As an admin, navigate to Admin > Users, find the banned user, and click Delete user (or Delete user and contributions).

  5. Observe that the deletion appears to succeed in the UI, but the user record is not actually deleted.

    • The log/sidekiq_json.log file will show that the job succeeded:

      {"severity":"INFO","time":"2026-07-21T02:28:54.417Z","retry":3,"queue":"default","backtrace":true,"version":0,"store":null,"args":["1","46","{}"],"class":"DeleteUserWorker","jid":"16e7827f5528476ce6c63361","created_at":"2026-07-21T02:28:54.414Z","trace_propagation_headers":{"sentry-trace":"5870f5e0c0cd483bb5aa998cca1832f1-4a2e64ed80804121","baggage":"sentry-trace_id=5870f5e0c0cd483bb5aa998cca1832f1,sentry-environment=,sentry-release=29f8b3e2de1"},"correlation_id":"01KY182DWYMNNBX36Y805KJZK8","meta.caller_id":"Admin::UsersController#destroy","meta.feature_category":"user_management","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.user":"root","meta.gl_user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"Admin::UsersController#destroy","worker_data_consistency":"always","worker_data_consistency_per_db":{"main":"always","ci":"always","sec":"always"},"idempotency_key":"resque:gitlab:duplicate:default:15937b2aae9e9d5fecdc555ba4c1d815b6529f06bb607cc4e0d4952d3cdceb26","size_limiter":"validated","enqueued_at":"2026-07-21T02:28:54.416Z","job_size_bytes":9,"pid":21931,"sidekiq_tid":"h5af","sidekiq_thread_name":"sidekiq.default/processor","message":"DeleteUserWorker JID-16e7827f5528476ce6c63361: start","job_status":"start","queue_duration_s":0.000482,"scheduling_latency_s":0.000495}
      {"severity":"INFO","time":"2026-07-21T02:28:54.447Z","retry":3,"queue":"default","backtrace":true,"version":0,"store":null,"args":["1","46","{}"],"class":"DeleteUserWorker","jid":"16e7827f5528476ce6c63361","created_at":"2026-07-21T02:28:54.414Z","trace_propagation_headers":{"sentry-trace":"5870f5e0c0cd483bb5aa998cca1832f1-4a2e64ed80804121","baggage":"sentry-trace_id=5870f5e0c0cd483bb5aa998cca1832f1,sentry-environment=,sentry-release=29f8b3e2de1"},"correlation_id":"01KY182DWYMNNBX36Y805KJZK8","meta.caller_id":"Admin::UsersController#destroy","meta.feature_category":"user_management","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.user":"root","meta.gl_user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"Admin::UsersController#destroy","worker_data_consistency":"always","worker_data_consistency_per_db":{"main":"always","ci":"always","sec":"always"},"idempotency_key":"resque:gitlab:duplicate:default:15937b2aae9e9d5fecdc555ba4c1d815b6529f06bb607cc4e0d4952d3cdceb26","size_limiter":"validated","enqueued_at":"2026-07-21T02:28:54.416Z","job_size_bytes":9,"pid":21931,"sidekiq_tid":"h5af","sidekiq_thread_name":"sidekiq.default/processor","message":"DeleteUserWorker JID-16e7827f5528476ce6c63361: done: 0.03078 sec","job_status":"done","queue_duration_s":0.000482,"scheduling_latency_s":0.000495,"db_count":12,"db_write_count":3,"db_cached_count":0,"db_txn_count":0,"db_replica_txn_count":0,"db_primary_txn_count":0,"db_replica_count":0,"db_primary_count":12,"db_replica_write_count":0,"db_primary_write_count":3,"db_replica_cached_count":0,"db_primary_cached_count":0,"db_replica_wal_count":0,"db_primary_wal_count":0,"db_replica_wal_cached_count":0,"db_primary_wal_cached_count":0,"db_replica_txn_max_duration_s":0.0,"db_primary_txn_max_duration_s":0.0,"db_replica_txn_duration_s":0.0,"db_primary_txn_duration_s":0.0,"db_replica_duration_s":0.0,"db_primary_duration_s":0.027,"db_main_txn_count":0,"db_ci_txn_count":0,"db_sec_txn_count":0,"db_main_replica_txn_count":0,"db_ci_replica_txn_count":0,"db_sec_replica_txn_count":0,"db_main_count":12,"db_ci_count":0,"db_sec_count":0,"db_main_replica_count":0,"db_ci_replica_count":0,"db_sec_replica_count":0,"db_main_write_count":3,"db_ci_write_count":0,"db_sec_write_count":0,"db_main_replica_write_count":0,"db_ci_replica_write_count":0,"db_sec_replica_write_count":0,"db_main_cached_count":0,"db_ci_cached_count":0,"db_sec_cached_count":0,"db_main_replica_cached_count":0,"db_ci_replica_cached_count":0,"db_sec_replica_cached_count":0,"db_main_wal_count":0,"db_ci_wal_count":0,"db_sec_wal_count":0,"db_main_replica_wal_count":0,"db_ci_replica_wal_count":0,"db_sec_replica_wal_count":0,"db_main_wal_cached_count":0,"db_ci_wal_cached_count":0,"db_sec_wal_cached_count":0,"db_main_replica_wal_cached_count":0,"db_ci_replica_wal_cached_count":0,"db_sec_replica_wal_cached_count":0,"db_main_txn_max_duration_s":0.0,"db_ci_txn_max_duration_s":0.0,"db_sec_txn_max_duration_s":0.0,"db_main_replica_txn_max_duration_s":0.0,"db_ci_replica_txn_max_duration_s":0.0,"db_sec_replica_txn_max_duration_s":0.0,"db_main_txn_duration_s":0.0,"db_ci_txn_duration_s":0.0,"db_sec_txn_duration_s":0.0,"db_main_replica_txn_duration_s":0.0,"db_ci_replica_txn_duration_s":0.0,"db_sec_replica_txn_duration_s":0.0,"db_main_duration_s":0.027,"db_ci_duration_s":0.0,"db_sec_duration_s":0.0,"db_main_replica_duration_s":0.0,"db_ci_replica_duration_s":0.0,"db_sec_replica_duration_s":0.0,"cpu_s":0.01487,"mem_objects":12532,"mem_bytes":799864,"mem_mallocs":1887,"mem_total_bytes":1301144,"worker_id":"sidekiq_0","rate_limiting_gates":[],"exclusive_lock_requested_count":1,"exclusive_lock_wait_duration_s":0,"exclusive_lock_hold_duration_s":0,"duration_s":0.03078,"completed_at":"2026-07-21T02:28:54.447Z","load_balancing_strategy":"primary","db_duration_s":0.008928,"urgency":"low","target_duration_s":300,"target_scheduling_latency_s":60}
    • The log/application_json.log file will contain Skipped own account deletion / User has been banned:

      {"severity":"INFO","time":"2026-07-21T02:28:54.444Z","correlation_id":"01KY182DWYMNNBX36Y805KJZK8","meta.caller_id":"DeleteUserWorker","meta.feature_category":"user_management","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.user":"root","meta.gl_user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"Admin::UsersController#destroy","message":"Skipped own account deletion.","reason":"User has been banned.","user_id":46,"username":"reported_user_steven_connelly"}
    • The log/audit_json.log file does not have any entries about the deletion being scheduled.

  6. Switch to the fix/banned-users-skipped-during-deletion branch, and restart Sidekiq gdk restart rails-background-jobs

  7. As an admin, navigate to Admin > Users, find the banned user from before, and click Delete user (or Delete user and contributions).

    • The log/sidekiq_json.log file will show that the job succeeded:

      {"severity":"INFO","time":"2026-07-21T02:51:48.815Z","retry":3,"queue":"default","backtrace":true,"version":0,"store":null,"args":["1","48","{}"],"class":"DeleteUserWorker","jid":"1e36d0b654151ebbf80c7da9","created_at":"2026-07-21T02:51:48.813Z","trace_propagation_headers":{"sentry-trace":"7f684ca565594c5eb8b928a0f84caf84-90cc3c7b9f7b461a","baggage":"sentry-trace_id=7f684ca565594c5eb8b928a0f84caf84,sentry-environment=,sentry-release=29f8b3e2de1"},"correlation_id":"01KY19CC2S4GM7YBPKAQ6P6Z1F","meta.caller_id":"Admin::UsersController#destroy","meta.feature_category":"user_management","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.user":"root","meta.gl_user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"Admin::UsersController#destroy","worker_data_consistency":"always","worker_data_consistency_per_db":{"main":"always","ci":"always","sec":"always"},"idempotency_key":"resque:gitlab:duplicate:default:f9e5ca4c68985b4630021648ae5cb52339738f714bdf47b0c609420aa4c46b91","size_limiter":"validated","enqueued_at":"2026-07-21T02:51:48.814Z","job_size_bytes":9,"pid":24449,"sidekiq_tid":"3yyt","sidekiq_thread_name":"sidekiq.default/processor","message":"DeleteUserWorker JID-1e36d0b654151ebbf80c7da9: start","job_status":"start","queue_duration_s":0.001063,"scheduling_latency_s":0.00108}
      {"severity":"INFO","time":"2026-07-21T02:51:49.150Z","retry":3,"queue":"default","backtrace":true,"version":0,"store":null,"args":["1","48","{}"],"class":"DeleteUserWorker","jid":"1e36d0b654151ebbf80c7da9","created_at":"2026-07-21T02:51:48.813Z","trace_propagation_headers":{"sentry-trace":"7f684ca565594c5eb8b928a0f84caf84-90cc3c7b9f7b461a","baggage":"sentry-trace_id=7f684ca565594c5eb8b928a0f84caf84,sentry-environment=,sentry-release=29f8b3e2de1"},"correlation_id":"01KY19CC2S4GM7YBPKAQ6P6Z1F","meta.caller_id":"Admin::UsersController#destroy","meta.feature_category":"user_management","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.user":"root","meta.gl_user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"Admin::UsersController#destroy","worker_data_consistency":"always","worker_data_consistency_per_db":{"main":"always","ci":"always","sec":"always"},"idempotency_key":"resque:gitlab:duplicate:default:f9e5ca4c68985b4630021648ae5cb52339738f714bdf47b0c609420aa4c46b91","size_limiter":"validated","enqueued_at":"2026-07-21T02:51:48.814Z","job_size_bytes":9,"pid":24449,"sidekiq_tid":"3yyt","sidekiq_thread_name":"sidekiq.default/processor","message":"DeleteUserWorker JID-1e36d0b654151ebbf80c7da9: done: 0.334311 sec","job_status":"done","queue_duration_s":0.001063,"scheduling_latency_s":0.00108,"db_count":23,"db_write_count":3,"db_cached_count":1,"db_txn_count":2,"db_replica_txn_count":0,"db_primary_txn_count":0,"db_replica_count":0,"db_primary_count":23,"db_replica_write_count":0,"db_primary_write_count":3,"db_replica_cached_count":0,"db_primary_cached_count":1,"db_replica_wal_count":0,"db_primary_wal_count":0,"db_replica_wal_cached_count":0,"db_primary_wal_cached_count":0,"db_replica_txn_max_duration_s":0.0,"db_primary_txn_max_duration_s":0.0,"db_replica_txn_duration_s":0.0,"db_primary_txn_duration_s":0.0,"db_replica_duration_s":0.0,"db_primary_duration_s":0.048,"db_main_txn_count":2,"db_ci_txn_count":0,"db_sec_txn_count":0,"db_main_replica_txn_count":0,"db_ci_replica_txn_count":0,"db_sec_replica_txn_count":0,"db_main_count":23,"db_ci_count":0,"db_sec_count":0,"db_main_replica_count":0,"db_ci_replica_count":0,"db_sec_replica_count":0,"db_main_write_count":3,"db_ci_write_count":0,"db_sec_write_count":0,"db_main_replica_write_count":0,"db_ci_replica_write_count":0,"db_sec_replica_write_count":0,"db_main_cached_count":1,"db_ci_cached_count":0,"db_sec_cached_count":0,"db_main_replica_cached_count":0,"db_ci_replica_cached_count":0,"db_sec_replica_cached_count":0,"db_main_wal_count":0,"db_ci_wal_count":0,"db_sec_wal_count":0,"db_main_replica_wal_count":0,"db_ci_replica_wal_count":0,"db_sec_replica_wal_count":0,"db_main_wal_cached_count":0,"db_ci_wal_cached_count":0,"db_sec_wal_cached_count":0,"db_main_replica_wal_cached_count":0,"db_ci_replica_wal_cached_count":0,"db_sec_replica_wal_cached_count":0,"db_main_txn_max_duration_s":0.012,"db_ci_txn_max_duration_s":0.0,"db_sec_txn_max_duration_s":0.0,"db_main_replica_txn_max_duration_s":0.0,"db_ci_replica_txn_max_duration_s":0.0,"db_sec_replica_txn_max_duration_s":0.0,"db_main_txn_duration_s":0.017,"db_ci_txn_duration_s":0.0,"db_sec_txn_duration_s":0.0,"db_main_replica_txn_duration_s":0.0,"db_ci_replica_txn_duration_s":0.0,"db_sec_replica_txn_duration_s":0.0,"db_main_duration_s":0.048,"db_ci_duration_s":0.0,"db_sec_duration_s":0.0,"db_main_replica_duration_s":0.0,"db_ci_replica_duration_s":0.0,"db_sec_replica_duration_s":0.0,"cpu_s":0.173138,"mem_objects":101465,"mem_bytes":20987255,"mem_mallocs":58284,"mem_total_bytes":25045855,"worker_id":"sidekiq_0","rate_limiting_gates":[],"exclusive_lock_requested_count":1,"exclusive_lock_wait_duration_s":0,"exclusive_lock_hold_duration_s":0,"duration_s":0.334311,"completed_at":"2026-07-21T02:51:49.150Z","load_balancing_strategy":"primary","db_duration_s":0.062305,"urgency":"low","target_duration_s":300,"target_scheduling_latency_s":60}
    • The log/application_json.log file does not contain any errors

    • The log/audit_json.log file shows that the deletion is scheduled for deletion:

      {"severity":"INFO","time":"2026-07-21T02:51:49.084Z","correlation_id":"01KY19CC2S4GM7YBPKAQ6P6Z1F","meta.caller_id":"DeleteUserWorker","meta.feature_category":"user_management","meta.organization_id":1,"meta.remote_ip":"172.16.123.1","meta.user":"root","meta.gl_user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"Admin::UsersController#destroy","id":319,"created_at":"2026-07-21T02:51:49.047Z","user_id":48,"author_id":1,"target_id":48,"event_name":"user_destroyed","details":{"event_name":"user_destroyed","author_name":"Administrator","author_class":"User","target_id":48,"target_type":"User","target_details":"reported_user_veronica.mccullough","custom_message":"User reported_user_veronica.mccullough scheduled for deletion","ip_address":"172.16.123.1","entity_path":"reported_user_veronica.mccullough"},"ip_address":"172.16.123.1","author_name":"Administrator","entity_path":"reported_user_veronica.mccullough","target_details":"reported_user_veronica.mccullough","target_type":"User","entity_id":48,"entity_type":"User","author_class":"User","custom_message":"User reported_user_veronica.mccullough scheduled for deletion"}
    • After a few minutes, the user will be deleted and no longer visible in the Admin UI.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Merge request reports

Loading
Loading