227 lines
7.8 KiB
Ruby
227 lines
7.8 KiB
Ruby
require_relative '../../../lib/carto/http/client'
|
|
require_dependency 'carto/uuidhelper'
|
|
require_dependency 'carto/overquota_users_service'
|
|
require_dependency 'carto/api/paged_searcher'
|
|
|
|
class Superadmin::UsersController < Superadmin::SuperadminController
|
|
include Carto::UUIDHelper
|
|
include Carto::Api::PagedSearcher
|
|
include Carto::ControllerHelper
|
|
|
|
respond_to :json
|
|
|
|
ssl_required :show, :create, :update, :destroy, :index
|
|
before_filter :get_user, only: [:update, :destroy, :show, :dump, :data_imports, :data_import]
|
|
before_filter :get_carto_user, only: [:synchronizations, :synchronization, :geocodings, :geocoding]
|
|
|
|
rescue_from Carto::ParamInvalidError, with: :rescue_from_carto_error
|
|
|
|
layout 'application'
|
|
|
|
VALID_ORDER_PARAMS = [:updated_at].freeze
|
|
|
|
def show
|
|
respond_with(@user.data({:extended => true}))
|
|
end
|
|
|
|
def index
|
|
if params[:overquota].present?
|
|
users = Carto::OverquotaUsersService.new.get_stored_overquota_users
|
|
respond_with(:superadmin, users)
|
|
elsif params[:db_size_in_bytes_change].present?
|
|
# This use case is specific: we only return cached db_size_in_bytes, which is
|
|
# much faster and doesn't add load to the database.
|
|
username_dbsize = Carto::UserDbSizeCache.new.db_size_in_bytes_change_users
|
|
respond_with(:superadmin, username_dbsize.map do |username, db_size_in_bytes|
|
|
{ 'username' => username, 'db_size_in_bytes' => db_size_in_bytes }
|
|
end) and return
|
|
elsif params[:account_type].present? && params[:state].present?
|
|
users = ::User.where(account_type: params[:account_type], state: params[:state])
|
|
respond_with(:superadmin, users.map(&:activity))
|
|
else
|
|
users = ::User.all
|
|
respond_with(:superadmin, users.map(&:data))
|
|
end
|
|
end
|
|
|
|
def create
|
|
@user = ::User.new
|
|
|
|
user_param = params[:user]
|
|
@user.set_fields_from_central(user_param, :create)
|
|
@user.enabled = true
|
|
|
|
@user.rate_limit_id = create_rate_limits(user_param[:rate_limit]).id if user_param[:rate_limit].present?
|
|
if @user.save
|
|
@user.reload
|
|
CartoDB::Visualization::CommonDataService.load_common_data(@user, self) if @user.should_load_common_data?
|
|
@user.set_relationships_from_central(user_param)
|
|
end
|
|
CartoGearsApi::Events::EventManager.instance.notify(
|
|
CartoGearsApi::Events::UserCreationEvent.new(
|
|
CartoGearsApi::Events::UserCreationEvent::CREATED_VIA_SUPERADMIN, @user
|
|
)
|
|
)
|
|
respond_with(:superadmin, @user)
|
|
end
|
|
|
|
def update
|
|
user_param = params[:user]
|
|
@user.set_fields_from_central(user_param, :update)
|
|
@user.set_relationships_from_central(user_param)
|
|
@user.regenerate_api_key(user_param[:api_key]) if user_param[:api_key].present?
|
|
|
|
@user.update_rate_limits(user_param[:rate_limit])
|
|
@user.save
|
|
respond_with(:superadmin, @user)
|
|
end
|
|
|
|
def destroy
|
|
@user.set_force_destroy if params[:force] == 'true'
|
|
@user.destroy
|
|
respond_with(:superadmin, @user)
|
|
rescue CartoDB::SharedEntitiesError => e
|
|
render json: { "error": "Error destroying user: #{e.message}", "errorCode": "userHasSharedEntities" }, status: 422
|
|
rescue => e
|
|
CartoDB::Logger.error(exception: e, message: 'Error destroying user', user: @user)
|
|
render json: { "error": "Error destroying user: #{e.message}", "errorCode": "" }, status: 422
|
|
end
|
|
|
|
def dump
|
|
if Cartodb.config[:users_dumps].nil? || Cartodb.config[:users_dumps]["service"].nil? || Cartodb.config[:users_dumps]["service"]["port"].nil?
|
|
raise "There is not a dump method configured"
|
|
end
|
|
json_data = {database: @user.database_name, username: @user.username}
|
|
http_client = Carto::Http::Client.get(self.class.name, log_requests: true)
|
|
response = http_client.request(
|
|
"#{@user.database_host}:#{Cartodb.config[:users_dumps]["service"]["port"]}/scripts/db_dump",
|
|
method: :post,
|
|
headers: { "Content-Type" => "application/json" },
|
|
body: json_data.to_json
|
|
).run
|
|
parsed_response = JSON.parse(response.body)
|
|
if response.code == 200 &&
|
|
parsed_response['retcode'] == 0 &&
|
|
!parsed_response['return_values']['local_file'].nil? &&
|
|
!parsed_response['return_values']['local_file'].empty? &&
|
|
!parsed_response['return_values']['remote_file'].nil? &&
|
|
!parsed_response['return_values']['remote_file'].empty?
|
|
sa_response = {
|
|
:dumper_response => parsed_response,
|
|
:remote_file => parsed_response['remote_file'],
|
|
:local_file => parsed_response['local_file'],
|
|
:database_host => @user.database_host
|
|
}
|
|
render json: sa_response, status: 200
|
|
else
|
|
sa_response = {
|
|
:dumper_response => parsed_response
|
|
}
|
|
render json: sa_response, status: 400
|
|
end
|
|
end
|
|
|
|
def data_imports
|
|
page, per_page, order, _order_direction = page_per_page_order_params(VALID_ORDER_PARAMS)
|
|
dataset = @user.data_imports_dataset.order(Sequel.desc(order)).paginate(page, per_page)
|
|
|
|
dataset = dataset.where(state: params[:status]) if params[:status].present?
|
|
total_entries = dataset.pagination_record_count
|
|
|
|
data_imports_info = dataset.map do |entry|
|
|
{
|
|
id: entry.id,
|
|
data_type: entry.data_type,
|
|
date: entry.updated_at,
|
|
status: entry.success.nil? ? false : entry.success,
|
|
state: entry.state
|
|
}
|
|
end
|
|
|
|
respond_with({ total_entries: total_entries }.merge(data_imports: data_imports_info))
|
|
end
|
|
|
|
def data_import
|
|
data_import = DataImport[params[:data_import_id]]
|
|
respond_with({
|
|
data: data_import.to_hash,
|
|
log: data_import.nil? ? nil : data_import.log.to_s
|
|
})
|
|
end
|
|
|
|
def geocodings
|
|
page, per_page, order, _order_direction = page_per_page_order_params(VALID_ORDER_PARAMS)
|
|
dataset = @user.geocodings.order("#{order} desc")
|
|
|
|
dataset = dataset.where(state: params[:status]) if params[:status].present?
|
|
total_entries = dataset.count
|
|
|
|
geocodings_info = dataset.limit(per_page).offset((page - 1) * per_page).map do |entry|
|
|
{
|
|
id: entry.id,
|
|
date: entry.updated_at,
|
|
status: entry.state
|
|
}
|
|
end
|
|
respond_with({ total_entries: total_entries }.merge(geocodings: geocodings_info))
|
|
end
|
|
|
|
def geocoding
|
|
geocoding = @user.geocodings.find(params[:geocoding_id])
|
|
respond_with(data: geocoding.attributes, log: geocoding && geocoding.log.to_s)
|
|
end
|
|
|
|
def synchronizations
|
|
page, per_page, order, _order_direction = page_per_page_order_params(VALID_ORDER_PARAMS)
|
|
dataset = @user.synchronizations.order("#{order} desc")
|
|
|
|
dataset = dataset.where(state: params[:status]) if params[:status].present?
|
|
total_entries = dataset.count
|
|
|
|
synchronizations_info = dataset.limit(per_page).offset((page - 1) * per_page).map do |entry|
|
|
{
|
|
id: entry.id,
|
|
data_type: entry.service_name,
|
|
date: entry.updated_at,
|
|
status: entry.success?,
|
|
state: entry.state
|
|
}
|
|
end
|
|
respond_with({ total_entries: total_entries }.merge(synchronizations: synchronizations_info))
|
|
end
|
|
|
|
def synchronization
|
|
synchronization = Carto::Synchronization.where(id: params[:synchronization_id]).first
|
|
respond_with({
|
|
data: synchronization.to_hash,
|
|
log: synchronization.nil? ? nil : synchronization.log.try(:entries)
|
|
})
|
|
end
|
|
|
|
private
|
|
|
|
def get_user
|
|
id = params[:id]
|
|
|
|
@user = if is_uuid?(id)
|
|
::User[params[:id]]
|
|
else
|
|
::User.where(username: id).first
|
|
end
|
|
|
|
render json: { error: 'User not found' }, status: 404 unless @user
|
|
end
|
|
|
|
def get_carto_user
|
|
@user = Carto::User.where(id: params[:id]).first
|
|
render json: { error: 'User not found' }, status: 404 unless @user
|
|
end
|
|
|
|
def create_rate_limits(rate_limit_attributes)
|
|
rate_limit = Carto::RateLimit.from_api_attributes(rate_limit_attributes)
|
|
rate_limit.save!
|
|
rate_limit
|
|
end
|
|
|
|
end # Superadmin::UsersController
|