From f9feef153a383c7e4619b3abc64e5d1159bf5bb7 Mon Sep 17 00:00:00 2001 From: Ynda Jas Date: Tue, 13 Aug 2024 12:03:02 +0100 Subject: [PATCH] Add Rake task for querying non-GDS permissions This will be used to find out if any non-GDS publishing managers have given non-GDS users permissions that we wouldn't expect them to be giving (as a result of the broken delegatable permissions feature) Testing this in integration, the number of rows is pretty low, but this tracks with the output from the preceding Rake task. I'd expect the numbers to be a little larger in production --- lib/tasks/event_log.rake | 70 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/lib/tasks/event_log.rake b/lib/tasks/event_log.rake index a47055d33..e59d24bde 100644 --- a/lib/tasks/event_log.rake +++ b/lib/tasks/event_log.rake @@ -1,3 +1,5 @@ +require "csv" + namespace :event_log do desc "Delete all events in the event log older than 2 years" task delete_logs_older_than_two_years: :environment do @@ -47,4 +49,72 @@ namespace :event_log do puts event_logs_csv end + + desc "Get permissions for non-GDS users added by non-GDS publishing managers" + task get_permissions_for_non_gds_users_added_by_non_gds_publishing_managers: :environment do + gds_organisation_id = Organisation.find_by(content_id: Organisation::GDS_ORG_CONTENT_ID).id + non_gds_publishing_manager_ids = User + .where.not(organisation_id: gds_organisation_id) + .where(role: [Roles::OrganisationAdmin.name, Roles::SuperOrganisationAdmin.name]) + .pluck(:id) + + CSV.open("tmp/permissions_by_non_gds_user.csv", "w") do |csv| + csv << [ + "Grantee ID", + "Grantee email", + "Grantee organisation (now)", + "Grantee role (now)", + "Grantee status (now)", + "Application", + "Permission", + "Added at", + "Granter ID", + "Granter email", + "Granter organisation (now)", + "Granter role (now)", + "EventLog ID", + "All permissions added during event", + ] + + User.where.not(organisation_id: gds_organisation_id).find_each do |user| + event_logs = EventLog + .where(event_id: EventLog::PERMISSIONS_ADDED.id, uid: user.uid) + .where(initiator_id: non_gds_publishing_manager_ids) + .includes(:initiator) + .order(created_at: :desc) + .map do |model_instance| + { + model_instance:, + application_id: model_instance.application&.id, + permission_names: model_instance.trailing_message[1..-2].split(","), + } + end + + user.supported_permissions.pluck(:application_id, :name).each do |application_id, permission_name| + event_log = event_logs.find { |log| log[:application_id] == application_id && log[:permission_names].include?(permission_name) } + + next unless event_log + + model_instance = event_log[:model_instance] + + csv << [ + user.id, + user.email, + "\"#{user.organisation_name}\"", + user.role_name, + user.status, + model_instance.application&.name || "#{Doorkeeper::Application.unscoped.retired.find(model_instance.application_id).name} (retired)", + permission_name, + model_instance.created_at, + model_instance.initiator_id, + model_instance.initiator.email, + "\"#{model_instance.initiator.organisation_name}\"", + model_instance.initiator.role_name, + model_instance.id, + model_instance.trailing_message[1..-2].gsub(",", ";"), + ] + end + end + end + end end