Welcome to mirror list, hosted at ThFree Co, Russian Federation.

params.rb « search « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e6a1305a82a9dad4626a30e054d414acd1034274 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# frozen_string_literal: true

module Gitlab
  module Search
    class Params
      include ActiveModel::Validations

      SEARCH_CHAR_LIMIT = 4096
      SEARCH_TERM_LIMIT = 64

      # Generic validation
      validates :query_string, length: { maximum: SEARCH_CHAR_LIMIT }
      validate :not_too_many_terms

      attr_reader :raw_params, :query_string, :abuse_detection
      alias_method :search, :query_string
      alias_method :term, :query_string

      def initialize(params, detect_abuse: true)
        @raw_params      = params.is_a?(Hash) ? params.with_indifferent_access : params.dup
        @query_string    = strip_surrounding_whitespace(@raw_params[:search] || @raw_params[:term])
        @detect_abuse    = detect_abuse
        @abuse_detection = AbuseDetection.new(self) if @detect_abuse

        validate
      end

      def [](key)
        if respond_to? key
          # We have this logic here to support reading custom attributes
          # like @query_string
          #
          # This takes precedence over values in @raw_params
          public_send(key) # rubocop:disable GitlabSecurity/PublicSend
        else
          raw_params[key]
        end
      end

      def abusive?
        detect_abuse? && abuse_detection.errors.any?
      end

      def valid_query_length?
        return true unless errors.has_key? :query_string

        errors[:query_string].none? { |msg| msg.include? SEARCH_CHAR_LIMIT.to_s }
      end

      def valid_terms_count?
        return true unless errors.has_key? :query_string

        errors[:query_string].none? { |msg| msg.include? SEARCH_TERM_LIMIT.to_s }
      end

      def validate
        if detect_abuse?
          abuse_detection.validate
        end

        super
      end

      def valid?
        if detect_abuse?
          abuse_detection.valid? && super
        else
          super
        end
      end

      private

      def detect_abuse?
        @detect_abuse
      end

      def not_too_many_terms
        if query_string.split.count { |word| word.length >= 3 } > SEARCH_TERM_LIMIT
          errors.add :query_string, "has too many search terms (maximum is #{SEARCH_TERM_LIMIT})"
        end
      end

      def strip_surrounding_whitespace(obj)
        obj.to_s.strip
      end
    end
  end
end