<commit_before>
require_dependency 'carto/uuidhelper'

module Carto
  module Api
    class LayersController < ::Api::ApplicationController
      include Carto::ControllerHelper

      ssl_required :show, :layers_by_map, :custom_layers_by_user

      before_filter :ensure_current_user, only: [:user_index, :user_show, :user_create, :user_update, :user_destroy]
      before_filter :load_user_layer, only: [:user_show, :user_destroy]
      before_filter :load_user_layers, only: [:user_update]

      before_filter :load_map, only: [:map_index, :map_show, :map_create, :map_update, :map_destroy]
      before_filter :ensure_writable_map, only: [:map_create, :map_update, :map_destroy]
      before_filter :load_map_layer, only: [:map_show, :map_destroy]
      before_filter :load_map_layers, only: [:map_update]

      rescue_from LoadError,
                  UnprocesableEntityError,
                  UnauthorizedError, with: :rescue_from_carto_error

      def map_index
        index(@map)
      end

      def user_index
        index(@user)
      end

      def map_show
        show(@map.user)
      end

      def user_show
        show(current_user)
      end

      def map_create
        layer = Carto::Layer.new(params.slice(:kind, :options, :infowindow, :tooltip, :order))
        validate_for_map(layer)

        if layer.save
          @map.layers << layer
          @map.process_privacy_in(layer)

          from_layer = Carto::Layer.where(id: params[:from_layer_id]).first if params[:from_layer_id]
          from_letter = params[:from_letter]
          update_layer_node_styles(layer, from_layer, from_letter)

          render_jsonp Carto::Api::LayerPresenter.new(layer, viewer_user: current_user).to_poro
        else
          CartoDB::Logger.info(
            message: 'Error creating layer',
            errors: layer.errors.full_messages
          )
          raise UnprocesableEntityError.new(layer.errors.full_messages)
        end
      end

      def user_create
        layer = Carto::Layer.new(params.slice(:kind, :options, :infowindow, :tooltip, :order))

        if layer.save
          @user.layers << layer

          render_jsonp Carto::Api::LayerPresenter.new(layer, viewer_user: current_user).to_poro
        else
          CartoDB::Logger.info(
            message: 'Error creating layer',
            errors: layer.errors.full_messages
          )
          raise UnprocesableEntityError.new(layer.errors.full_messages)
        end
      end

      def map_update
        update
      end

      def user_update
        update
      end

      def map_destroy
        destroy
      end

      def user_destroy
        destroy
      end

      private

      def validate_for_map(layer)
        unless @map.can_add_layer(current_user)
          raise UnprocesableEntityError.new('Cannot add more layers to this visualization')
        end
        unless @map.admits_layer?(layer)
          raise UnprocesableEntityError.new('Cannot add more layers of this type')
        end

        table_name = layer.options['table_name']
        user_name = layer.options['user_name']
        if user_name.present?
          table_name = user_name + '.' + table_name
        end

        if layer.data_layer?
          table_visualization = Helpers::TableLocator.new.get_by_id_or_name(
            table_name,
            current_user
          ).visualization
          unless table_visualization.has_read_permission?(current_user)
            raise UnauthorizedError.new('You do not have permission in the layer you are trying to add')
          end
        end
      end

      def index(parent)
        layers = parent.layers.map do |layer|
          Carto::Api::LayerPresenter.new(layer, viewer_user: current_user, user: owner_user(layer)).to_poro
        end

        render_jsonp layers: layers, total_entries: layers.size
      end

      def show(owner)
        render_jsonp Carto::Api::LayerPresenter.new(@layer, viewer_user: current_user, user: owner).to_json
      end

      def update
        layers = @layers.map do |layer|
          layer_params = params[:layers].present? ? params[:layers].find { |p| p['id'] == layer.id } : params

          # don't allow to override table_name and user_name
          new_layer_options = layer_params[:options]<commit_msg>Fix index for user layers<commit_after>
require_dependency 'carto/uuidhelper'

module Carto
  module Api
    class LayersController < ::Api::ApplicationController
      include Carto::ControllerHelper

      ssl_required :show, :layers_by_map, :custom_layers_by_user

      before_filter :ensure_current_user, only: [:user_index, :user_show, :user_create, :user_update, :user_destroy]
      before_filter :load_user_layer, only: [:user_show, :user_destroy]
      before_filter :load_user_layers, only: [:user_update]

      before_filter :load_map, only: [:map_index, :map_show, :map_create, :map_update, :map_destroy]
      before_filter :ensure_writable_map, only: [:map_create, :map_update, :map_destroy]
      before_filter :load_map_layer, only: [:map_show, :map_destroy]
      before_filter :load_map_layers, only: [:map_update]

      rescue_from LoadError,
                  UnprocesableEntityError,
                  UnauthorizedError, with: :rescue_from_carto_error

      def map_index
        index(@map)
      end

      def user_index
        index(@user, owner: @user)
      end

      def map_show
        show(@map.user)
      end

      def user_show
        show(current_user)
      end

      def map_create
        layer = Carto::Layer.new(params.slice(:kind, :options, :infowindow, :tooltip, :order))
        validate_for_map(layer)

        if layer.save
          @map.layers << layer
          @map.process_privacy_in(layer)

          from_layer = Carto::Layer.where(id: params[:from_layer_id]).first if params[:from_layer_id]
          from_letter = params[:from_letter]
          update_layer_node_styles(layer, from_layer, from_letter)

          render_jsonp Carto::Api::LayerPresenter.new(layer, viewer_user: current_user).to_poro
        else
          CartoDB::Logger.info(
            message: 'Error creating layer',
            errors: layer.errors.full_messages
          )
          raise UnprocesableEntityError.new(layer.errors.full_messages)
        end
      end

      def user_create
        layer = Carto::Layer.new(params.slice(:kind, :options, :infowindow, :tooltip, :order))

        if layer.save
          @user.layers << layer

          render_jsonp Carto::Api::LayerPresenter.new(layer, viewer_user: current_user).to_poro
        else
          CartoDB::Logger.info(
            message: 'Error creating layer',
            errors: layer.errors.full_messages
          )
          raise UnprocesableEntityError.new(layer.errors.full_messages)
        end
      end

      def map_update
        update
      end

      def user_update
        update
      end

      def map_destroy
        destroy
      end

      def user_destroy
        destroy
      end

      private

      def validate_for_map(layer)
        unless @map.can_add_layer(current_user)
          raise UnprocesableEntityError.new('Cannot add more layers to this visualization')
        end
        unless @map.admits_layer?(layer)
          raise UnprocesableEntityError.new('Cannot add more layers of this type')
        end

        table_name = layer.options['table_name']
        user_name = layer.options['user_name']
        if user_name.present?
          table_name = user_name + '.' + table_name
        end

        if layer.data_layer?
          table_visualization = Helpers::TableLocator.new.get_by_id_or_name(
            table_name,
            current_user
          ).visualization
          unless table_visualization.has_read_permission?(current_user)
            raise UnauthorizedError.new('You do not have permission in the layer you are trying to add')
          end
        end
      end

      def index(parent, owner: nil)
        layers = parent.layers.map do |layer|
          Carto::Api::LayerPresenter.new(layer, viewer_user: current_user, user: owner || owner_user(layer)).to_poro
        end

        render_jsonp layers: layers, total_entries: layers.size
      end

      def show(owner)
        render_jsonp Carto::Api::LayerPresenter.new(@layer, viewer_user: current_user, user: owner).to_json
      end

      def update
        layers = @layers.map do |layer|
          layer_params = params[:layers].present? ? params[:layers].find { |p| p['id'] == layer.id } : params

          # don't allow to override table_name and user_name
          new_layer_options = layer_params[:options]
{'fraction_non_alphanumeric': 0.08502024291497975, 'fraction_numerical': 0.0, 'mean_word_length': 2.4708952228020875, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4034045', 'n_tokens_mistral': 2579, 'n_tokens_neox': 2502, 'n_words': 552}