Support for visualization user basemaps loading and meaningful information on protected error

pull/13141/head
Juan Ignacio Sánchez Lara 7 years ago
parent 64239749cf
commit 3ee487ab1b

@ -7,11 +7,12 @@ module Carto
BUILDER_ACTIVATION_DATE = Date.new(2016, 11, 11).freeze
def initialize(user, fetch_groups: false, current_viewer: nil, fetch_db_size: true)
def initialize(user, fetch_groups: false, current_viewer: nil, fetch_db_size: true, fetch_basemaps: false)
@user = user
@fetch_groups = fetch_groups
@current_viewer = current_viewer
@fetch_db_size = fetch_db_size
@fetch_basemaps = fetch_basemaps
end
def to_poro
@ -46,6 +47,8 @@ module Carto
poro[:groups] = @user.groups ? @user.groups.map { |g| Carto::Api::GroupPresenter.new(g).to_poro } : []
end
poro[:basemaps] = @user.basemaps if fetch_basemaps
poro[:db_size_in_bytes] = @user.db_size_in_bytes if fetch_db_size
poro
@ -241,7 +244,7 @@ module Carto
private
attr_reader :current_viewer, :current_user, :fetch_groups, :fetch_db_size
attr_reader :current_viewer, :current_user, :fetch_groups, :fetch_db_size, :fetch_basemaps
def failed_import_count
Carto::DataImport.where(user_id: @user.id, state: 'failure').count

@ -10,7 +10,7 @@ module Carto
related: true, related_canonical_visualizations: false, show_user: false,
show_stats: true, show_likes: true, show_liked: true, show_table: true,
show_permission: true, show_synchronization: true, show_uses_builder_features: true,
show_table_size_and_row_count: true, show_auth_tokens: true, show_basemaps: false,
show_table_size_and_row_count: true, show_auth_tokens: true, show_user_basemaps: false,
password: nil)
@visualization = visualization
@current_viewer = current_viewer
@ -28,7 +28,7 @@ module Carto
@show_uses_builder_features = show_uses_builder_features
@show_table_size_and_row_count = show_table_size_and_row_count
@show_auth_tokens = show_auth_tokens
@show_basemaps = show_basemaps
@show_user_basemaps = show_user_basemaps
@password = password
@presenter_cache = Carto::Api::PresenterCache.new
@ -56,14 +56,6 @@ module Carto
poro[:permission] = permission if show_permission
poro[:stats] = show_stats ? @visualization.stats : {}
if @visualization.user.has_feature_flag?('google_maps')
poro[:google_maps_query_string] = @visualization.user.google_maps_query_string
end
if show_basemaps
poro[:basemaps] = Cartodb.config[:basemaps].present? ? Cartodb.config[:basemaps] : {}
end
if show_auth_tokens
poro[:auth_tokens] = auth_tokens
elsif return_private_poro || @visualization.is_accessible_with_password?(@current_viewer, @password)
@ -169,7 +161,7 @@ module Carto
:show_stats, :show_likes, :show_liked, :show_table,
:show_permission, :show_synchronization, :show_uses_builder_features,
:show_table_size_and_row_count, :show_auth_tokens,
:show_basemaps
:show_user_basemaps
def user_table_presentation
Carto::Api::UserTablePresenter.new(@visualization.user_table, @current_viewer,
@ -239,7 +231,9 @@ module Carto
def user
Carto::Api::UserPresenter.new(@visualization.user,
current_viewer: @current_viewer, fetch_db_size: false).to_poro
current_viewer: @current_viewer,
fetch_db_size: false,
fetch_basemaps: show_user_basemaps).to_poro
end
end
end

@ -53,18 +53,19 @@ module Carto
rescue_from Carto::LoadError, with: :rescue_from_carto_error
rescue_from Carto::UnauthorizedError, with: :rescue_from_carto_error
rescue_from Carto::UUIDParameterFormatError, with: :rescue_from_carto_error
rescue_from Carto::ProtectedVisualizationLoadError, with: :rescue_from_protected_visualization_load_error
def show
presenter = VisualizationPresenter.new(
@visualization, current_viewer, self,
related_canonical_visualizations: params[:fetch_related_canonical_visualizations] == 'true',
show_user: params[:fetch_user] == 'true',
show_user_basemaps: params[:show_user_basemaps] == 'true',
show_liked: params[:show_liked] == 'true',
show_likes: params[:show_likes] == 'true',
show_permission: params[:show_permission] == 'true',
show_stats: params[:show_stats] == 'true',
show_auth_tokens: params[:show_auth_tokens] == 'true',
show_basemaps: params[:show_basemaps] == 'true',
password: params[:password]
)
@ -382,8 +383,11 @@ module Carto
end
if !@visualization.is_accessible_with_password?(current_viewer, params[:password])
raise Carto::LoadError.new('Visualization not viewable', 403,
errors_cause: @visualization.password_protected? ? 'privacy_password' : nil)
if @visualization.password_protected?
raise Carto::ProtectedVisualizationLoadError.new(@visualization)
else
raise Carto::LoadError.new('Visualization not viewable', 403)
end
end
end

@ -34,6 +34,15 @@ module Carto
end
end
class ProtectedVisualizationLoadError < LoadError
def initialize(visualization)
@visualization = visualization
super('Visualization not viewable', 403, errors_cause: 'privacy_password')
end
attr_reader :visualization
end
class UnprocesableEntityError < CartoError
def initialize(message, status = 422)
super(message, status)
@ -63,6 +72,28 @@ module Carto
end
end
def rescue_from_protected_visualization_load_error(error)
message = error.message
status = error.status
respond_to do |format|
format.html { render text: message, status: status }
format.json {
errors_cause = error.errors_cause
visualization = error.visualization
visualization_info = {
privacy: visualization.privacy,
user: {
google_maps_query_string: visualization.user.google_maps_query_string
}
}
render json: { errors: message, errors_cause: errors_cause, visualization: visualization_info },
status: status
}
end
end
def rescue_from_standard_error(error)
CartoDB::Logger.error(exception: error)
message = error.message

@ -1372,15 +1372,24 @@ describe Carto::Api::VisualizationsController do
response['likes'].should eq nil
end
it 'returns a specific error for password-protected visualizations' do
it 'returns a specific error for password-protected visualizations and required, public information' do
@visualization.privacy = Carto::Visualization::PRIVACY_PROTECTED
@visualization.password = 'wadus'
@visualization.save!
@visualization.user.update_attribute(:google_maps_key, 'waaaaadus')
expected_visualization_info = {
privacy: @visualization.privacy,
user: {
google_maps_query_string: @visualization.user.google_maps_query_string
}
}
get_json api_v1_visualizations_show_url(id: @visualization.id) do |response|
response.status.should eq 403
response.body[:errors].should eq "Visualization not viewable"
response.body[:errors_cause].should eq "privacy_password"
response.body[:visualization].should eq expected_visualization_info
end
end
@ -1551,6 +1560,7 @@ describe Carto::Api::VisualizationsController do
response.body[:description].should_not be_nil
# Optional information requiring parameters
response.body[:user].should eq nil
response.body[:liked].should eq nil
response.body[:likes].should eq 0
response.body[:stats].should be_empty
@ -1566,15 +1576,21 @@ describe Carto::Api::VisualizationsController do
show_likes: true,
show_permission: true,
show_auth_tokens: true,
show_stats: true
show_stats: true,
fetch_user: true,
show_user_basemaps: true
)
get_json url do |response|
response.status.should eq 200
response.body[:user].should_not be_nil
response.body[:liked].should eq false
response.body[:likes].should eq 0
response.body[:stats].should_not be_empty
response_user = response.body[:user]
response_user[:basemaps].should be_nil # Even if requested, because it's not public
permission = response.body[:permission]
permission.should_not eq nil
permission[:owner].should_not eq nil
@ -1590,6 +1606,23 @@ describe Carto::Api::VisualizationsController do
end
end
it 'not only returns public information for authenticated requests' do
url = api_v1_visualizations_show_url(
id: @visualization.id,
fetch_user: true,
show_user_basemaps: true,
api_key: @visualization.user.api_key
)
get_json url do |response|
response.status.should eq 200
response.body[:user].should_not be_nil
response_user = response.body[:user]
response_user[:basemaps].should_not be_empty
end
end
it 'returns auth_tokens for password protected visualizations if correct password is provided' do
password = 'wadus'
@visualization.privacy = Carto::Visualization::PRIVACY_PROTECTED

Loading…
Cancel
Save