From ebf4dd465e05beb5f75a2defa4a4d202335793d0 Mon Sep 17 00:00:00 2001 From: Laura Jaime Date: Wed, 8 Feb 2023 13:22:28 +0100 Subject: [PATCH] Add geopositioning user ips rake task --- Gemfile | 1 + Gemfile.lock | 2 ++ lib/tasks/geopositioning_users.rake | 40 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 lib/tasks/geopositioning_users.rake diff --git a/Gemfile b/Gemfile index a2e740a1..6e87be4c 100644 --- a/Gemfile +++ b/Gemfile @@ -38,6 +38,7 @@ gem "delayed_job_active_record" gem "whenever", require: false +gem "ipaddr" gem "recaptcha" group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 0652ee5b..4fc37f40 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -524,6 +524,7 @@ GEM ruby-vips (>= 2.0.17, < 3) invisible_captcha (0.13.0) rails (>= 3.2.0) + ipaddr (1.2.3) json (2.6.2) jwt (2.5.0) kaminari (1.2.2) @@ -904,6 +905,7 @@ DEPENDENCIES delayed_job_active_record faker figaro (>= 1.1.1) + ipaddr letter_opener_web listen (~> 3.1.0) puma (< 6) diff --git a/lib/tasks/geopositioning_users.rake b/lib/tasks/geopositioning_users.rake new file mode 100644 index 00000000..44cec27c --- /dev/null +++ b/lib/tasks/geopositioning_users.rake @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "csv" +require "ipaddr" + +namespace :geopositioning_users do + # This task extracts a csv file with the IPs of the users and their location. + desc "Generate a CSV with the users IP information" + task generate_csv: :environment do + headers = %w(email IP IP_location last_sign_in) + # VPN IP, blank or nils + invalid_ips = ["10.2.1.52", "", nil] + users_with_valid_ip = Decidim::User.where.not(last_sign_in_ip: invalid_ips) + + CSV.open("users_ip_locations.csv", "w") do |csv| + csv << headers + + users_with_valid_ip.each_with_index do |user, index| + user_ip = user.last_sign_in_ip + puts "User #{index}/#{users_with_valid_ip.count}" + + if IPAddr.new(user_ip).private? + csv << [user.email, user_ip, "Private IP", user.last_sign_in_at] + else + # Delay to wait between requests to Geocoder API + sleep 0.5 + csv << [user.email, user_ip, ip_location(user_ip), user.last_sign_in_at] + end + end + end + end + + private + + def ip_location(ip) + results = Geocoder.search(ip).first + + results.present? ? results.address : nil + end +end