cartodb/lib/tasks/user.rake
2020-06-15 10:58:47 +08:00

155 lines
6.4 KiB
Ruby

namespace :user do
namespace :deletion do
desc 'Delete a user given a username'
task :by_username, [:username] => [:environment] do |task, args|
raise 'Please specify the username of the user to be deleted' if args[:username].blank?
user = ::User.find(username: args[:username])
raise "The username '#{args[:username]}' does not correspond to any user" if user.nil?
raise 'Deletion aborted due to bad confirmation' if !deletion_confirmed?(user)
user.destroy
end
desc 'Delete a user given an email'
task :by_email, [:email] => [:environment] do |task, args|
raise 'Please specify the email of the user to be deleted' if args[:email].blank?
user = ::User.find(email: args[:email])
raise "The email '#{args[:email]}' does not correspond to any user" if user.nil?
raise 'Deletion aborted due to bad confirmation' if !deletion_confirmed?(user)
user.destroy
end
def deletion_confirmed?(user)
puts ""
puts "You are about to delete the following user:"
puts "\t> username: #{user.username}"
puts "\t> email: #{user.email}"
puts ""
puts "Alongside '#{user.username}', the following will be deleted:"
puts "\t> #{user.maps.length} maps"
puts "\t> #{user.tables.count} datasets"
puts ""
puts "Type in the user's username (#{user.username}) to confirm:"
confirm = STDIN.gets.strip
confirm == user.username
end
end
namespace :change do
desc 'Change the number of maximum layers allowed on a map'
task :max_layers, [:username, :max_layers] => [:environment] do |task, args|
max_layers = args[:max_layers].to_i
raise 'Please specify the username of the user to be modified' if args[:username].blank?
raise 'Please specify a number of layers that is a positive integer' if max_layers < 1
user = ::User.find(username: args[:username])
raise "The username '#{args[:username]}' does not correspond to any user" if user.nil?
old_max_layers = user.max_layers
user.max_layers = max_layers
user.save
puts "Changed the number of max layers for '#{user.username}' from #{old_max_layers} to #{max_layers}."
end
end
namespace :likes do
desc 'Clean likes for all the users of the organization'
task :clean_org_likes, [:organization] => [:environment] do |_, args|
raise 'Please specify the organization to be cleaned' if args[:organization].blank?
org = Carto::Organization.find_by_name(args[:organization])
raise "The organization '#{args[:organization]}' does not correspond to any organization" if org.nil?
org.users.find_each do |u|
Carto::Like.where(actor: u.id).delete_all
end
end
desc 'Clean likes for a user'
task :clean_user_likes, [:username] => [:environment] do |_, args|
raise 'Please specify the username to be cleaned' if args[:username].blank?
u = Carto::User.find_by_username(args[:username])
raise "The username '#{args[:username]}' does not correspond to any user" if u.nil?
Carto::Like.where(actor: u.id).delete_all
end
end
namespace :ghost_tables do
desc 'Install ghost tables trigger to all the organizations owners and regular users'
task :install_ghost_tables_trigger => :environment do
Carto::User.where(organization_id: nil).find_each do |user|
install_ghost_tables_trigger(user.id)
end
Organization.each { |org| install_ghost_tables_trigger(org.owner_id) }
end
def install_ghost_tables_trigger(user_id)
user = ::User.find(id: user_id)
if user.nil?
puts "ERROR: User #{user_id} does not exist"
elsif user.organization_user? && !user.organization_owner?
puts "ERROR: User #{user_id} must be an org owner or not to be an organization user"
elsif user.has_feature_flag?('ghost_tables_trigger_disabled')
puts "WARN: Skipping user #{user_id} (it has 'ghost_tables_trigger_disabled' feature flag)"
else
begin
user.db_service.create_ghost_tables_event_trigger
rescue StandardError => error
puts "ERROR creating ghost tables trigger for user #{user_id}: #{error.message}"
end
end
end
desc 'Drop ghost_tables_trigger to all the organizations owners and regular users'
task :drop_ghost_tables_trigger => :environment do
Carto::User.where(organization_id: nil).find_each do |user|
drop_ghost_tables_trigger(user.id)
end
Organization.each { |org| drop_ghost_tables_trigger(org.owner_id) }
end
def drop_ghost_tables_trigger(user_id)
user = ::User.find(id: user_id)
if user.nil?
puts "ERROR: User #{username} does not exist"
elsif user.organization_user? && !user.organization_owner?
puts "ERROR: User #{username} must be an org owner or not to be an organization user"
else
user.db_service.drop_ghost_tables_event_trigger
end
end
end
namespace :notifications do
desc 'Add a text in the notification field for users filtered by field'
task :add_by_field, [:filter_field, :filter_value, :notification] => [:environment] do |task, args|
allowed_fields = ['database_host']
raise "Filter field and value are needed" if args[:filter_field].nil? || args[:filter_value].nil?
raise "Unknown field #{args[:filter_field]} for filtering. Allowed fields are #{allowed_fields.join(',')}" unless allowed_fields.include?(args[:filter_field])
raise "Notification not provided. Please include it" if args[:notification].nil?
sql = "UPDATE users SET notification = '%s' WHERE %s = '%s'"
query = ActiveRecord::Base.send(:sanitize_sql_array, [sql, args[:notification], args[:filter_field], args[:filter_value]])
ActiveRecord::Base.connection.execute(query)
end
desc 'Clean notification for users filtered by field'
task :clean_by_field, [:filter_field, :filter_value] => [:environment] do |task, args|
allowed_fields = ['database_host']
raise "Filter field and value are needed" if args[:filter_field].nil? || args[:filter_value].nil?
raise "Unknown field #{args[:filter_field]} for filtering. Allowed fields are #{allowed_fields.join(',')}" unless allowed_fields.include?(args[:filter_field])
sql = "UPDATE users SET notification = NULL WHERE %s = '%s'"
query = ActiveRecord::Base.send(:sanitize_sql_array, [sql, args[:filter_field], args[:filter_value]])
ActiveRecord::Base.connection.execute(query)
end
end
end