Initial commit
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
|
||||
module CartoDB
|
||||
# To avoid collisions with User class
|
||||
module UserModule
|
||||
class DBQueries
|
||||
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def run_in_transaction(queries, superuser = false)
|
||||
conn_params = superuser ? { as: :superuser } : {}
|
||||
@user.in_database(conn_params) do |user_database|
|
||||
user_database.transaction do
|
||||
queries.each do |query|
|
||||
begin
|
||||
user_database.run(query)
|
||||
rescue => e
|
||||
CartoDB.notify_debug('Error running user query in transaction',
|
||||
query: query, user: @user, error: e.inspect)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
yield(user_database) if block_given?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def grant_connect_on_database_queries(db_user = nil)
|
||||
granted_user = db_user.nil? ? @user.database_username : db_user
|
||||
[
|
||||
"GRANT CONNECT ON DATABASE \"#{@user.database_name}\" TO \"#{granted_user}\""
|
||||
]
|
||||
end
|
||||
|
||||
def grant_read_on_schema_queries(schema, db_user = nil)
|
||||
granted_user = db_user.nil? ? @user.database_username : db_user
|
||||
|
||||
queries = [
|
||||
"GRANT USAGE ON SCHEMA \"#{schema}\" TO \"#{granted_user}\"",
|
||||
"GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA \"#{schema}\" TO \"#{granted_user}\"",
|
||||
"GRANT SELECT ON ALL TABLES IN SCHEMA \"#{schema}\" TO \"#{granted_user}\""
|
||||
]
|
||||
if schema == CartoDB::UserModule::DBService::SCHEMA_CARTODB
|
||||
queries.concat(revoke_permissions_on_cartodb_conf_queries(granted_user))
|
||||
end
|
||||
|
||||
queries
|
||||
end
|
||||
|
||||
def grant_write_on_cdb_tablemetadata_queries(db_user = nil)
|
||||
granted_user = db_user.nil? ? @user.database_username : db_user
|
||||
[
|
||||
"GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE cartodb.cdb_tablemetadata TO \"#{granted_user}\""
|
||||
]
|
||||
end
|
||||
|
||||
def grant_write_on_cdb_analysis_catalog_queries(db_user = nil)
|
||||
granted_user = db_user.nil? ? @user.database_username : db_user
|
||||
[
|
||||
"GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE cartodb.cdb_analysis_catalog TO \"#{granted_user}\""
|
||||
]
|
||||
end
|
||||
|
||||
def revoke_permissions_on_cartodb_conf_queries(db_user)
|
||||
[
|
||||
"REVOKE ALL ON TABLE cartodb.CDB_CONF FROM \"#{db_user}\""
|
||||
]
|
||||
end
|
||||
|
||||
def grant_all_on_database_queries
|
||||
[
|
||||
"GRANT ALL ON DATABASE \"#{@user.database_name}\" TO \"#{@user.database_username}\""
|
||||
]
|
||||
end
|
||||
|
||||
def grant_all_on_user_schema_queries
|
||||
[
|
||||
"GRANT ALL ON SCHEMA \"#{@user.database_schema}\" TO \"#{@user.database_username}\"",
|
||||
"GRANT ALL ON ALL SEQUENCES IN SCHEMA \"#{@user.database_schema}\" TO \"#{@user.database_username}\"",
|
||||
"GRANT ALL ON ALL FUNCTIONS IN SCHEMA \"#{@user.database_schema}\" TO \"#{@user.database_username}\"",
|
||||
"GRANT ALL ON ALL TABLES IN SCHEMA \"#{@user.database_schema}\" TO \"#{@user.database_username}\""
|
||||
]
|
||||
end
|
||||
|
||||
def grant_usage_on_user_schema_to_other(granted_user)
|
||||
[
|
||||
"GRANT USAGE ON SCHEMA \"#{@user.database_schema}\" TO \"#{granted_user}\""
|
||||
]
|
||||
end
|
||||
|
||||
def grant_all_on_schema_queries(schema, db_user = nil)
|
||||
granted_user = db_user.nil? ? @user.database_username : db_user
|
||||
[
|
||||
"GRANT ALL ON SCHEMA \"#{schema}\" TO \"#{granted_user}\""
|
||||
]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
|
||||
module CartoDB
|
||||
# This class encapsulates access to synchronization_oauths from the outside
|
||||
class OAuths
|
||||
|
||||
# Class constructor
|
||||
# @param owner_user ::User
|
||||
def initialize(owner_user)
|
||||
@owner = owner_user
|
||||
end #initialize
|
||||
|
||||
def all
|
||||
@owner.synchronization_oauths
|
||||
end #all
|
||||
|
||||
# @param service string
|
||||
# @return SynchronizationOauth
|
||||
def select(service)
|
||||
SynchronizationOauth.where(service: service, user_id: @owner.id).first
|
||||
end #select
|
||||
|
||||
def add(service, token)
|
||||
new_oauth = SynchronizationOauth.create(
|
||||
user_id: @owner.id,
|
||||
service: service,
|
||||
token: token
|
||||
)
|
||||
@owner.add_synchronization_oauth(new_oauth)
|
||||
self
|
||||
end
|
||||
|
||||
def remove(service)
|
||||
oauth = SynchronizationOauth.where(service: service, user_id: @owner.id).first
|
||||
oauth.delete unless oauth.nil?
|
||||
@owner.reload
|
||||
self
|
||||
end
|
||||
|
||||
end #OAuths
|
||||
end #CartoDB
|
||||
@@ -0,0 +1,186 @@
|
||||
module CartoDB
|
||||
module UserDecorator
|
||||
include AccountTypeHelper
|
||||
|
||||
def activity(options = {})
|
||||
calls = options.fetch(:show_api_calls, true) ? get_api_calls(from: last_billing_cycle, to: Date.today) : []
|
||||
map_views = calls.reduce(0, :+)
|
||||
|
||||
{
|
||||
id: id,
|
||||
email: email,
|
||||
username: username,
|
||||
state: state,
|
||||
account_type: account_type,
|
||||
table_count: table_count,
|
||||
public_map_count: public_privacy_visualization_count + link_privacy_visualization_count + password_privacy_visualization_count,
|
||||
map_count: all_visualization_count,
|
||||
map_views: map_views,
|
||||
geocoding_credits_count: organization_user? ? organization.get_geocoding_calls : get_geocoding_calls,
|
||||
routing_credits_count: organization_user? ? organization.get_mapzen_routing_calls : get_mapzen_routing_calls,
|
||||
isolines_credits_count: organization_user? ? organization.get_here_isolines_calls : get_here_isolines_calls,
|
||||
billing_period: last_billing_cycle ? last_billing_cycle.strftime('%Q') : nil,
|
||||
regular_api_key_count: api_keys.by_type('regular').count
|
||||
}
|
||||
end
|
||||
|
||||
# Options:
|
||||
# - show_api_calls: load api calls. Default: true.
|
||||
# - extended: load real_table_count and last_active_time. Default: false.
|
||||
def data(options = {})
|
||||
calls = options.fetch(:show_api_calls, true) ? get_api_calls(from: last_billing_cycle, to: Date.today) : []
|
||||
calls.fill(0, calls.size..29)
|
||||
|
||||
db_size_in_bytes = self.db_size_in_bytes
|
||||
|
||||
data = {
|
||||
id: id,
|
||||
email: email,
|
||||
name: name,
|
||||
last_name: last_name,
|
||||
created_at: created_at,
|
||||
username: username,
|
||||
state: state,
|
||||
account_type: account_type,
|
||||
account_type_display_name: plan_name(account_type),
|
||||
table_quota: table_quota,
|
||||
public_map_quota: public_map_quota,
|
||||
regular_api_key_quota: regular_api_key_quota,
|
||||
table_count: table_count,
|
||||
public_visualization_count: public_visualization_count,
|
||||
public_privacy_map_count: public_privacy_visualization_count,
|
||||
link_privacy_map_count: link_privacy_visualization_count,
|
||||
password_privacy_map_count: password_privacy_visualization_count,
|
||||
all_visualization_count: all_visualization_count,
|
||||
visualization_count: visualization_count,
|
||||
owned_visualization_count: owned_visualizations_count,
|
||||
failed_import_count: failed_import_count,
|
||||
success_import_count: success_import_count,
|
||||
import_count: import_count,
|
||||
last_visualization_created_at: last_visualization_created_at,
|
||||
quota_in_bytes: quota_in_bytes,
|
||||
db_size_in_bytes: db_size_in_bytes,
|
||||
db_size_in_megabytes: db_size_in_bytes.present? ? (db_size_in_bytes / (1024.0 * 1024.0)).round(2) : nil,
|
||||
remaining_table_quota: remaining_table_quota,
|
||||
remaining_byte_quota: remaining_quota(false, db_size_in_bytes).to_f,
|
||||
api_calls: calls,
|
||||
api_calls_quota: organization_user? ? organization.map_view_quota : map_view_quota,
|
||||
api_calls_block_price: organization_user? ? organization.map_view_block_price : map_view_block_price,
|
||||
geocoding: {
|
||||
quota: organization_user? ? organization.geocoding_quota : geocoding_quota,
|
||||
block_price: organization_user? ? organization.geocoding_block_price : geocoding_block_price,
|
||||
monthly_use: organization_user? ? organization.get_geocoding_calls : get_geocoding_calls,
|
||||
hard_limit: hard_geocoding_limit?
|
||||
},
|
||||
here_isolines: {
|
||||
quota: organization_user? ? organization.here_isolines_quota : here_isolines_quota,
|
||||
block_price: organization_user? ? organization.here_isolines_block_price : here_isolines_block_price,
|
||||
monthly_use: organization_user? ? organization.get_here_isolines_calls : get_here_isolines_calls,
|
||||
hard_limit: hard_here_isolines_limit?
|
||||
},
|
||||
geocoder_provider: geocoder_provider,
|
||||
isolines_provider: isolines_provider,
|
||||
routing_provider: routing_provider,
|
||||
obs_snapshot: {
|
||||
quota: organization_user? ? organization.obs_snapshot_quota : obs_snapshot_quota,
|
||||
block_price: organization_user? ? organization.obs_snapshot_block_price : obs_snapshot_block_price,
|
||||
monthly_use: organization_user? ? organization.get_obs_snapshot_calls : get_obs_snapshot_calls,
|
||||
hard_limit: hard_obs_snapshot_limit?
|
||||
},
|
||||
obs_general: {
|
||||
quota: organization_user? ? organization.obs_general_quota : obs_general_quota,
|
||||
block_price: organization_user? ? organization.obs_general_block_price : obs_general_block_price,
|
||||
monthly_use: organization_user? ? organization.get_obs_general_calls : get_obs_general_calls,
|
||||
hard_limit: hard_obs_general_limit?
|
||||
},
|
||||
twitter: {
|
||||
enabled: organization_user? ? organization.twitter_datasource_enabled : twitter_datasource_enabled,
|
||||
quota: organization_user? ? organization.twitter_datasource_quota : twitter_datasource_quota,
|
||||
block_price: organization_user? ? organization.twitter_datasource_block_price : twitter_datasource_block_price,
|
||||
block_size: organization_user? ? organization.twitter_datasource_block_size : twitter_datasource_block_size,
|
||||
monthly_use: organization_user? ? organization.get_twitter_imports_count : get_twitter_imports_count,
|
||||
hard_limit: hard_twitter_datasource_limit,
|
||||
customized_config: CartoDB::Datasources::DatasourcesFactory.customized_config?(CartoDB::Datasources::Search::Twitter::DATASOURCE_NAME, self)
|
||||
},
|
||||
mailchimp: {
|
||||
enabled: Carto::AccountType.new.mailchimp?(self)
|
||||
},
|
||||
mapzen_routing: {
|
||||
quota: organization_user? ? organization.mapzen_routing_quota : mapzen_routing_quota,
|
||||
block_price: organization_user? ? organization.mapzen_routing_block_price : mapzen_routing_block_price,
|
||||
monthly_use: organization_user? ? organization.get_mapzen_routing_calls : get_mapzen_routing_calls,
|
||||
hard_limit: hard_mapzen_routing_limit?
|
||||
},
|
||||
salesforce: {
|
||||
enabled: organization_user? ? organization.salesforce_datasource_enabled : salesforce_datasource_enabled
|
||||
},
|
||||
billing_period: last_billing_cycle,
|
||||
api_key: api_key,
|
||||
layers: layers.map(&:public_values),
|
||||
trial_ends_at: trial_ends_at,
|
||||
upgraded_at: upgraded_at,
|
||||
show_trial_reminder: trial_ends_at.present?,
|
||||
show_upgraded_message: (account_type.downcase != 'free' && upgraded_at && upgraded_at + 15.days > Date.today ? true : false),
|
||||
actions: {
|
||||
private_tables: private_tables_enabled,
|
||||
private_maps: private_maps_enabled?,
|
||||
remove_logo: remove_logo?,
|
||||
sync_tables: sync_tables_enabled,
|
||||
google_maps_geocoder_enabled: google_maps_geocoder_enabled?,
|
||||
google_maps_enabled: google_maps_enabled?,
|
||||
engine_enabled: engine_enabled?,
|
||||
builder_enabled: builder_enabled?,
|
||||
mobile_sdk_enabled: mobile_sdk_enabled?
|
||||
},
|
||||
limits: {
|
||||
concurrent_syncs: CartoDB::PlatformLimits::Importer::UserConcurrentSyncsAmount::MAX_SYNCS_PER_USER,
|
||||
concurrent_imports: max_concurrent_import_count,
|
||||
import_file_size: max_import_file_size,
|
||||
import_table_rows: max_import_table_row_count,
|
||||
max_layers: max_layers
|
||||
},
|
||||
notification: notification,
|
||||
avatar_url: avatar,
|
||||
feature_flags: feature_flags,
|
||||
base_url: public_url,
|
||||
needs_password_confirmation: needs_password_confirmation?,
|
||||
viewer: viewer,
|
||||
org_admin: organization_admin?,
|
||||
description: description,
|
||||
website: website,
|
||||
twitter_username: twitter_username,
|
||||
disqus_shortname: disqus_shortname,
|
||||
available_for_hire: available_for_hire,
|
||||
location: location,
|
||||
industry: industry,
|
||||
company_employees: company_employees,
|
||||
use_case: use_case,
|
||||
company: company,
|
||||
phone: phone,
|
||||
job_role: job_role
|
||||
}
|
||||
|
||||
if google_maps_geocoder_enabled? && (!organization.present? || organization_owner?)
|
||||
data[:google_maps_private_key] = google_maps_private_key
|
||||
end
|
||||
|
||||
if organization.present?
|
||||
data[:organization] = organization.to_poro
|
||||
data[:organization][:available_quota_for_user] = organization.unassigned_quota + quota_in_bytes
|
||||
end
|
||||
|
||||
if !groups.nil?
|
||||
data[:groups] = groups.map { |g| Carto::Api::GroupPresenter.new(g).to_poro }
|
||||
end
|
||||
|
||||
if options[:extended]
|
||||
data.merge(
|
||||
real_table_count: real_tables.size,
|
||||
last_active_time: get_last_active_time
|
||||
)
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,81 @@
|
||||
module CartoDB
|
||||
class UserOrganization
|
||||
|
||||
def initialize(org_id, owner_id)
|
||||
@owner = ::User.where(:id => owner_id).first
|
||||
raise "The organization needs a owner" if @owner.nil?
|
||||
if !@owner.organization_id.nil? && @owner.organization_id != org_id
|
||||
raise "The user already has a organization and it's not #{org_id}"
|
||||
end
|
||||
@organization = Organization.where(:id => org_id).first
|
||||
raise "The user needs a organization" if @organization.nil?
|
||||
if !@organization.owner_id.nil? && @organization.owner_id != owner_id
|
||||
raise "The organization already has a owner and it's not #{owner_id}"
|
||||
end
|
||||
@users = ::User.where(:organization_id => org_id)
|
||||
@active = false
|
||||
if !@organization.owner_id.nil?
|
||||
@active = true
|
||||
end
|
||||
end
|
||||
|
||||
def promote_user_to_admin
|
||||
raise "Organization is already active. You can't assign an admin" if @active
|
||||
@owner.organization_id = @organization.id
|
||||
@owner.db_service.move_to_own_schema
|
||||
@organization.owner_id = @owner.id
|
||||
@organization.admin_email = @owner.email
|
||||
@organization.save
|
||||
@owner.organization = @organization
|
||||
|
||||
# WIP: CartoDB/cartodb-management#4467
|
||||
# Added after commenting it in setup_organization_user_schema to avoid configure_database to reset permissions
|
||||
@owner.db_service.reset_user_schema_permissions
|
||||
|
||||
@owner.db_service.setup_organization_user_schema
|
||||
@owner.save
|
||||
@owner.db_service.monitor_user_notification
|
||||
@active = true
|
||||
end
|
||||
|
||||
def owner
|
||||
@owner
|
||||
end
|
||||
|
||||
def organization
|
||||
@organization
|
||||
end
|
||||
|
||||
def users
|
||||
@users
|
||||
end
|
||||
|
||||
def self.from_org_id(organization_id)
|
||||
organization = Organization.where(:id => organization_id).first
|
||||
raise "Organization with id #{org_id} does not exist" if organization.nil?
|
||||
return CartoDB::UserOrganization.new(organization.id, organization.owner_id)
|
||||
end
|
||||
|
||||
def self.is_a_user?(name)
|
||||
return ::User.where(:username => name).count > 0 ? true : false
|
||||
end
|
||||
|
||||
def self.is_a_organization?(name)
|
||||
return Organization.where(:username => name).count > 0 ? true : false
|
||||
end
|
||||
|
||||
def self.user_belongs_to_organization?(name)
|
||||
if CartoDB::UserOrganization.is_a_user?(name)
|
||||
begin
|
||||
organization_id = ::User.select(:organization_id).where(:username => name).first[:organization_id]
|
||||
return Organization.select(:name).where(:id => organization_id).first[:name]
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user