acts_as_textcaptcha 4.2.0 → 4.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.rubocop.yml +1165 -0
- data/.simplecov +11 -0
- data/.travis.yml +30 -8
- data/Appraisals +9 -6
- data/CHANGELOG.md +94 -34
- data/CODE_OF_CONDUCT.md +54 -31
- data/CONTRIBUTING.md +14 -9
- data/Gemfile +2 -2
- data/LICENSE +165 -0
- data/PULL_REQUEST_TEMPLATE.md +16 -0
- data/README.md +206 -228
- data/Rakefile +26 -19
- data/acts_as_textcaptcha.gemspec +57 -41
- data/bin/console +2 -5
- data/bin/setup +7 -0
- data/gemfiles/rails_3.gemfile +1 -0
- data/gemfiles/rails_4.gemfile +2 -1
- data/gemfiles/rails_5.gemfile +2 -1
- data/gemfiles/rails_6.gemfile +8 -0
- data/lib/acts_as_textcaptcha.rb +9 -4
- data/lib/acts_as_textcaptcha/errors.rb +21 -0
- data/lib/acts_as_textcaptcha/framework/rails.rb +3 -1
- data/lib/acts_as_textcaptcha/railtie.rb +9 -0
- data/lib/acts_as_textcaptcha/tasks/textcaptcha.rake +17 -0
- data/lib/acts_as_textcaptcha/textcaptcha.rb +75 -72
- data/lib/acts_as_textcaptcha/textcaptcha_api.rb +39 -45
- data/lib/acts_as_textcaptcha/textcaptcha_cache.rb +12 -16
- data/lib/acts_as_textcaptcha/textcaptcha_config.rb +47 -0
- data/lib/acts_as_textcaptcha/textcaptcha_helper.rb +13 -14
- data/lib/acts_as_textcaptcha/version.rb +3 -1
- metadata +68 -46
- data/.coveralls.yml +0 -1
- data/LICENSE.txt +0 -21
- data/config/textcaptcha.yml +0 -34
- data/lib/tasks/textcaptcha.rake +0 -21
- data/test/schema.rb +0 -34
- data/test/test_helper.rb +0 -44
- data/test/test_models.rb +0 -69
- data/test/textcaptcha_api_test.rb +0 -46
- data/test/textcaptcha_cache_test.rb +0 -25
- data/test/textcaptcha_helper_test.rb +0 -68
- data/test/textcaptcha_test.rb +0 -198
| @@ -1,61 +1,55 @@ | |
| 1 | 
            -
            #  | 
| 2 | 
            -
            # loads and parses captcha question and answers
         | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 3 2 |  | 
| 4 | 
            -
            require  | 
| 3 | 
            +
            require "json"
         | 
| 5 4 |  | 
| 6 5 | 
             
            module ActsAsTextcaptcha
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              # raised if an empty response is returned
         | 
| 9 | 
            -
              class EmptyResponseError < StandardError; end;
         | 
| 10 | 
            -
             | 
| 11 6 | 
             
              class TextcaptchaApi
         | 
| 7 | 
            +
                BASE_URL = "http://textcaptcha.com"
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(api_key: nil, api_endpoint: nil, raise_errors: false)
         | 
| 10 | 
            +
                  self.uri = if api_endpoint
         | 
| 11 | 
            +
                               URI(api_endpoint)
         | 
| 12 | 
            +
                             else
         | 
| 13 | 
            +
                               URI("#{BASE_URL}/#{api_key}.json")
         | 
| 14 | 
            +
                             end
         | 
| 15 | 
            +
                  self.raise_errors = raise_errors || false
         | 
| 16 | 
            +
                rescue URI::InvalidURIError => e
         | 
| 17 | 
            +
                  raise ApiKeyError.new(api_key, e)
         | 
| 18 | 
            +
                end
         | 
| 12 19 |  | 
| 13 | 
            -
                 | 
| 14 | 
            -
             | 
| 15 | 
            -
                def self.fetch(api_key, options = {})
         | 
| 16 | 
            -
                  begin
         | 
| 17 | 
            -
                    url = uri_parser.parse("#{ENDPOINT}#{api_key}")
         | 
| 18 | 
            -
                    http = Net::HTTP.new(url.host, url.port)
         | 
| 19 | 
            -
                    if options[:http_open_timeout]
         | 
| 20 | 
            -
                      http.open_timeout = options[:http_open_timeout]
         | 
| 21 | 
            -
                    end
         | 
| 22 | 
            -
                    if options[:http_read_timeout]
         | 
| 23 | 
            -
                      http.read_timeout = options[:http_read_timeout]
         | 
| 24 | 
            -
                    end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                    response = http.get(url.path)
         | 
| 27 | 
            -
                    if response.body.to_s.empty?
         | 
| 28 | 
            -
                      raise ActsAsTextcaptcha::EmptyResponseError
         | 
| 29 | 
            -
                    else
         | 
| 30 | 
            -
                      return parse(response.body)
         | 
| 31 | 
            -
                    end
         | 
| 32 | 
            -
                  rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
         | 
| 33 | 
            -
                    Errno::EHOSTUNREACH, EOFError, Errno::ECONNREFUSED, Errno::ETIMEDOUT,
         | 
| 34 | 
            -
                    Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
         | 
| 35 | 
            -
                    URI::InvalidURIError, ActsAsTextcaptcha::EmptyResponseError,
         | 
| 36 | 
            -
                    REXML::ParseException
         | 
| 37 | 
            -
                    # rescue from these errors and continue
         | 
| 38 | 
            -
                  end
         | 
| 20 | 
            +
                def fetch
         | 
| 21 | 
            +
                  parse(get.to_s)
         | 
| 39 22 | 
             
                end
         | 
| 40 23 |  | 
| 41 | 
            -
                 | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 24 | 
            +
                private
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                attr_accessor :uri, :raise_errors
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def get
         | 
| 29 | 
            +
                  response = Net::HTTP.new(uri.host, uri.port).get(uri.path)
         | 
| 30 | 
            +
                  if response.code == "200"
         | 
| 31 | 
            +
                    response.body
         | 
| 46 32 | 
             
                  else
         | 
| 47 | 
            -
                     | 
| 33 | 
            +
                    handle_error ResponseError.new(uri, "status: #{response.code}")
         | 
| 48 34 | 
             
                  end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 35 | 
            +
                rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
         | 
| 36 | 
            +
                       Errno::EHOSTUNREACH, EOFError, Errno::ECONNREFUSED, Errno::ETIMEDOUT,
         | 
| 37 | 
            +
                       Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
         | 
| 38 | 
            +
                       Net::ProtocolError => e
         | 
| 39 | 
            +
                  handle_error ResponseError.new(uri, e)
         | 
| 51 40 | 
             
                end
         | 
| 52 41 |  | 
| 42 | 
            +
                def parse(response)
         | 
| 43 | 
            +
                  JSON.parse(response) unless response.empty?
         | 
| 44 | 
            +
                rescue JSON::ParserError
         | 
| 45 | 
            +
                  handle_error ParseError.new(uri)
         | 
| 46 | 
            +
                end
         | 
| 53 47 |  | 
| 54 | 
            -
                 | 
| 48 | 
            +
                def handle_error(error)
         | 
| 49 | 
            +
                  raise error if raise_errors
         | 
| 55 50 |  | 
| 56 | 
            -
             | 
| 57 | 
            -
                   | 
| 58 | 
            -
                  URI.const_defined?(:Parser) ? URI::Parser.new : URI
         | 
| 51 | 
            +
                  Rails.logger.error("#{error.class} #{error.message}")
         | 
| 52 | 
            +
                  nil
         | 
| 59 53 | 
             
                end
         | 
| 60 54 | 
             
              end
         | 
| 61 55 | 
             
            end
         | 
| @@ -1,34 +1,30 @@ | |
| 1 | 
            -
            #  | 
| 2 | 
            -
             | 
| 3 | 
            -
            #  | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # A simple cache for storing Textcaptcha answers, Rails.cache is used as the
         | 
| 4 | 
            +
            # backend (ActiveSupport::Cache). This must not be set as a `:null_store`.
         | 
| 4 5 |  | 
| 5 6 | 
             
            module ActsAsTextcaptcha
         | 
| 6 7 | 
             
              class TextcaptchaCache
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                 | 
| 9 | 
            -
                DEFAULT_CACHE_EXPIRY_MINUTES = 10
         | 
| 8 | 
            +
                KEY_PREFIX = "acts_as_textcaptcha-"
         | 
| 9 | 
            +
                DEFAULT_EXPIRY_MINUTES = 10
         | 
| 10 10 |  | 
| 11 11 | 
             
                def write(key, value, options = {})
         | 
| 12 | 
            -
                  unless options.has_key?(:expires_in)
         | 
| 13 | 
            -
                    options[:expires_in] = DEFAULT_CACHE_EXPIRY_MINUTES.minutes
         | 
| 14 | 
            -
                  end
         | 
| 12 | 
            +
                  options[:expires_in] = DEFAULT_EXPIRY_MINUTES.minutes unless options.has_key?(:expires_in)
         | 
| 15 13 | 
             
                  Rails.cache.write(cache_key(key), value, options)
         | 
| 16 14 | 
             
                end
         | 
| 17 15 |  | 
| 18 | 
            -
                def read(key | 
| 19 | 
            -
                  Rails.cache.read(cache_key(key) | 
| 16 | 
            +
                def read(key)
         | 
| 17 | 
            +
                  Rails.cache.read(cache_key(key))
         | 
| 20 18 | 
             
                end
         | 
| 21 19 |  | 
| 22 | 
            -
                def delete(key | 
| 23 | 
            -
                  Rails.cache.delete(cache_key(key) | 
| 20 | 
            +
                def delete(key)
         | 
| 21 | 
            +
                  Rails.cache.delete(cache_key(key))
         | 
| 24 22 | 
             
                end
         | 
| 25 23 |  | 
| 26 24 | 
             
                private
         | 
| 27 25 |  | 
| 28 | 
            -
                # since this cache may be shared with other objects
         | 
| 29 | 
            -
                # a prefix is used in all cache keys
         | 
| 30 26 | 
             
                def cache_key(key)
         | 
| 31 | 
            -
                  "#{ | 
| 27 | 
            +
                  "#{KEY_PREFIX}#{key}"
         | 
| 32 28 | 
             
                end
         | 
| 33 29 | 
             
              end
         | 
| 34 30 | 
             
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ActsAsTextcaptcha
         | 
| 4 | 
            +
              class TextcaptchaConfig
         | 
| 5 | 
            +
                YAML = <<~CONFIG
         | 
| 6 | 
            +
                  development: &common_settings
         | 
| 7 | 
            +
                    api_key: 'TEXTCAPTCHA_API_IDENT' # see https://textcaptcha.com for details
         | 
| 8 | 
            +
                    # api_endpoint: nil        # Optional API URL to fetch questions and answers from
         | 
| 9 | 
            +
                    # raise_errors: false      # Optional flag, if true errors will be raised if the API endpoint fails
         | 
| 10 | 
            +
                    # cache_expiry_minutes: 10 # Optional minutes for captcha answers to persist in the cache (default 10 minutes)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    questions:
         | 
| 13 | 
            +
                        - question: 'Is ice hot or cold?'
         | 
| 14 | 
            +
                          answers: 'cold'
         | 
| 15 | 
            +
                        - question: 'what color is an orange?'
         | 
| 16 | 
            +
                          answers: 'orange'
         | 
| 17 | 
            +
                        - question: 'what is two plus 3?'
         | 
| 18 | 
            +
                          answers: '5,five'
         | 
| 19 | 
            +
                        - question: 'what is 5 times two?'
         | 
| 20 | 
            +
                          answers: '10,ten'
         | 
| 21 | 
            +
                        - question: 'How many colors in the list, green, brown, foot and blue?'
         | 
| 22 | 
            +
                          answers: '3,three'
         | 
| 23 | 
            +
                        - question: 'what is Georges name?'
         | 
| 24 | 
            +
                          answers: 'george'
         | 
| 25 | 
            +
                        - question: '11 minus 1?'
         | 
| 26 | 
            +
                          answers: '10,ten'
         | 
| 27 | 
            +
                        - question: 'is boiling water hot or cold?'
         | 
| 28 | 
            +
                          answers: 'hot'
         | 
| 29 | 
            +
                        - question: 'what color is my blue shirt today?'
         | 
| 30 | 
            +
                          answers: 'blue'
         | 
| 31 | 
            +
                        - question: 'what is 16 plus 4?'
         | 
| 32 | 
            +
                          answers: '20,twenty'
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  test:
         | 
| 35 | 
            +
                    <<: *common_settings
         | 
| 36 | 
            +
                    api_key: 'TEST_TEXTCAPTCHA_API_IDENT'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  production:
         | 
| 39 | 
            +
                    <<: *common_settings
         | 
| 40 | 
            +
                CONFIG
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def self.create(path: "./config/textcaptcha.yml")
         | 
| 43 | 
            +
                  FileUtils.mkdir_p(File.dirname(path))
         | 
| 44 | 
            +
                  File.open(path, "w") { |f| f.write(YAML) }
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -1,21 +1,20 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module ActsAsTextcaptcha
         | 
| 2 4 | 
             
              module TextcaptchaHelper
         | 
| 5 | 
            +
                def textcaptcha_fields(form, &block)
         | 
| 6 | 
            +
                  build_textcaptcha_form_elements(form, &block) if form.object.perform_textcaptcha? && form.object.textcaptcha_key
         | 
| 7 | 
            +
                end
         | 
| 3 8 |  | 
| 4 | 
            -
                 | 
| 5 | 
            -
                def textcaptcha_fields(f, &block)
         | 
| 6 | 
            -
                  model        = f.object
         | 
| 7 | 
            -
                  captcha_html = ''
         | 
| 8 | 
            -
                  if model.perform_textcaptcha?
         | 
| 9 | 
            -
                    if model.textcaptcha_key
         | 
| 10 | 
            -
                      captcha_html += f.hidden_field(:textcaptcha_key)
         | 
| 11 | 
            -
                      if model.textcaptcha_question
         | 
| 12 | 
            -
                        captcha_html += capture(&block)
         | 
| 13 | 
            -
                      elsif model.textcaptcha_answer
         | 
| 14 | 
            -
                        captcha_html += f.hidden_field(:textcaptcha_answer)
         | 
| 15 | 
            -
                      end
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
                  end
         | 
| 9 | 
            +
                private
         | 
| 18 10 |  | 
| 11 | 
            +
                def build_textcaptcha_form_elements(form, &block)
         | 
| 12 | 
            +
                  captcha_html = form.hidden_field(:textcaptcha_key)
         | 
| 13 | 
            +
                  if form.object.textcaptcha_question
         | 
| 14 | 
            +
                    captcha_html += capture(&block)
         | 
| 15 | 
            +
                  elsif form.object.textcaptcha_answer
         | 
| 16 | 
            +
                    captcha_html += form.hidden_field(:textcaptcha_answer)
         | 
| 17 | 
            +
                  end
         | 
| 19 18 | 
             
                  captcha_html.html_safe
         | 
| 20 19 | 
             
                end
         | 
| 21 20 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,31 +1,31 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: acts_as_textcaptcha
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 4.2 | 
| 4 | 
            +
              version: 4.5.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Matthew Hutchinson
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-01-28 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            -
              name:  | 
| 14 | 
            +
              name: bundler
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - - " | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version:  | 
| 19 | 
            +
                    version: '0'
         | 
| 20 20 | 
             
              type: :development
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - - " | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version:  | 
| 26 | 
            +
                    version: '0'
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            -
              name:  | 
| 28 | 
            +
              name: pry-byebug
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - ">="
         | 
| @@ -39,7 +39,7 @@ dependencies: | |
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '0'
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            -
              name:  | 
| 42 | 
            +
              name: rake
         | 
| 43 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                requirements:
         | 
| 45 45 | 
             
                - - ">="
         | 
| @@ -53,7 +53,7 @@ dependencies: | |
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '0'
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            -
              name:  | 
| 56 | 
            +
              name: rubocop
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 59 | 
             
                - - ">="
         | 
| @@ -67,7 +67,7 @@ dependencies: | |
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: '0'
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            -
              name:  | 
| 70 | 
            +
              name: rdoc
         | 
| 71 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 73 | 
             
                - - ">="
         | 
| @@ -81,7 +81,7 @@ dependencies: | |
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '0'
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            -
              name:  | 
| 84 | 
            +
              name: appraisal
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 87 | 
             
                - - ">="
         | 
| @@ -95,7 +95,7 @@ dependencies: | |
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 96 | 
             
                    version: '0'
         | 
| 97 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 | 
            -
              name:  | 
| 98 | 
            +
              name: minitest
         | 
| 99 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 100 | 
             
                requirements:
         | 
| 101 101 | 
             
                - - ">="
         | 
| @@ -109,21 +109,35 @@ dependencies: | |
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 110 | 
             
                    version: '0'
         | 
| 111 111 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            -
              name:  | 
| 112 | 
            +
              name: rails
         | 
| 113 113 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 114 | 
             
                requirements:
         | 
| 115 | 
            -
                - - " | 
| 115 | 
            +
                - - "~>"
         | 
| 116 116 | 
             
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            -
                    version:  | 
| 117 | 
            +
                    version: 6.0.3.4
         | 
| 118 118 | 
             
              type: :development
         | 
| 119 119 | 
             
              prerelease: false
         | 
| 120 120 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 121 | 
             
                requirements:
         | 
| 122 | 
            -
                - - " | 
| 122 | 
            +
                - - "~>"
         | 
| 123 123 | 
             
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            -
                    version:  | 
| 124 | 
            +
                    version: 6.0.3.4
         | 
| 125 125 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 126 | 
            -
              name:  | 
| 126 | 
            +
              name: simplecov
         | 
| 127 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 | 
            +
                requirements:
         | 
| 129 | 
            +
                - - "~>"
         | 
| 130 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            +
                    version: 0.19.1
         | 
| 132 | 
            +
              type: :development
         | 
| 133 | 
            +
              prerelease: false
         | 
| 134 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 | 
            +
                requirements:
         | 
| 136 | 
            +
                - - "~>"
         | 
| 137 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            +
                    version: 0.19.1
         | 
| 139 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 140 | 
            +
              name: sqlite3
         | 
| 127 141 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 142 | 
             
                requirements:
         | 
| 129 143 | 
             
                - - ">="
         | 
| @@ -137,7 +151,7 @@ dependencies: | |
| 137 151 | 
             
                  - !ruby/object:Gem::Version
         | 
| 138 152 | 
             
                    version: '0'
         | 
| 139 153 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 140 | 
            -
              name:  | 
| 154 | 
            +
              name: webmock
         | 
| 141 155 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 142 156 | 
             
                requirements:
         | 
| 143 157 | 
             
                - - ">="
         | 
| @@ -150,73 +164,81 @@ dependencies: | |
| 150 164 | 
             
                - - ">="
         | 
| 151 165 | 
             
                  - !ruby/object:Gem::Version
         | 
| 152 166 | 
             
                    version: '0'
         | 
| 153 | 
            -
            description:  | 
| 154 | 
            -
             | 
| 155 | 
            -
                 | 
| 156 | 
            -
                 | 
| 157 | 
            -
                 | 
| 167 | 
            +
            description: |2
         | 
| 168 | 
            +
                ActsAsTextcaptcha provides spam protection for Rails models with text-based
         | 
| 169 | 
            +
                logic question captchas. Questions are fetched from Rob Tuley's
         | 
| 170 | 
            +
                textcaptcha.com They can be solved easily by humans but are tough for robots
         | 
| 171 | 
            +
                to crack.
         | 
| 158 172 | 
             
            email:
         | 
| 159 173 | 
             
            - matt@hiddenloop.com
         | 
| 160 174 | 
             
            executables: []
         | 
| 161 175 | 
             
            extensions: []
         | 
| 162 | 
            -
            extra_rdoc_files: | 
| 176 | 
            +
            extra_rdoc_files:
         | 
| 177 | 
            +
            - README.md
         | 
| 178 | 
            +
            - LICENSE
         | 
| 163 179 | 
             
            files:
         | 
| 164 | 
            -
            - ".coveralls.yml"
         | 
| 165 180 | 
             
            - ".gitignore"
         | 
| 181 | 
            +
            - ".rubocop.yml"
         | 
| 182 | 
            +
            - ".simplecov"
         | 
| 166 183 | 
             
            - ".travis.yml"
         | 
| 167 184 | 
             
            - Appraisals
         | 
| 168 185 | 
             
            - CHANGELOG.md
         | 
| 169 186 | 
             
            - CODE_OF_CONDUCT.md
         | 
| 170 187 | 
             
            - CONTRIBUTING.md
         | 
| 171 188 | 
             
            - Gemfile
         | 
| 172 | 
            -
            - LICENSE | 
| 189 | 
            +
            - LICENSE
         | 
| 190 | 
            +
            - PULL_REQUEST_TEMPLATE.md
         | 
| 173 191 | 
             
            - README.md
         | 
| 174 192 | 
             
            - Rakefile
         | 
| 175 193 | 
             
            - acts_as_textcaptcha.gemspec
         | 
| 176 194 | 
             
            - bin/console
         | 
| 177 | 
            -
            -  | 
| 195 | 
            +
            - bin/setup
         | 
| 178 196 | 
             
            - gemfiles/rails_3.gemfile
         | 
| 179 197 | 
             
            - gemfiles/rails_4.gemfile
         | 
| 180 198 | 
             
            - gemfiles/rails_5.gemfile
         | 
| 199 | 
            +
            - gemfiles/rails_6.gemfile
         | 
| 181 200 | 
             
            - lib/acts_as_textcaptcha.rb
         | 
| 201 | 
            +
            - lib/acts_as_textcaptcha/errors.rb
         | 
| 182 202 | 
             
            - lib/acts_as_textcaptcha/framework/rails.rb
         | 
| 203 | 
            +
            - lib/acts_as_textcaptcha/railtie.rb
         | 
| 204 | 
            +
            - lib/acts_as_textcaptcha/tasks/textcaptcha.rake
         | 
| 183 205 | 
             
            - lib/acts_as_textcaptcha/textcaptcha.rb
         | 
| 184 206 | 
             
            - lib/acts_as_textcaptcha/textcaptcha_api.rb
         | 
| 185 207 | 
             
            - lib/acts_as_textcaptcha/textcaptcha_cache.rb
         | 
| 208 | 
            +
            - lib/acts_as_textcaptcha/textcaptcha_config.rb
         | 
| 186 209 | 
             
            - lib/acts_as_textcaptcha/textcaptcha_helper.rb
         | 
| 187 210 | 
             
            - lib/acts_as_textcaptcha/version.rb
         | 
| 188 | 
            -
            - lib/tasks/textcaptcha.rake
         | 
| 189 | 
            -
            - test/schema.rb
         | 
| 190 | 
            -
            - test/test_helper.rb
         | 
| 191 | 
            -
            - test/test_models.rb
         | 
| 192 | 
            -
            - test/textcaptcha_api_test.rb
         | 
| 193 | 
            -
            - test/textcaptcha_cache_test.rb
         | 
| 194 | 
            -
            - test/textcaptcha_helper_test.rb
         | 
| 195 | 
            -
            - test/textcaptcha_test.rb
         | 
| 196 211 | 
             
            homepage: http://github.com/matthutchinson/acts_as_textcaptcha
         | 
| 197 212 | 
             
            licenses:
         | 
| 198 213 | 
             
            - MIT
         | 
| 199 214 | 
             
            metadata:
         | 
| 215 | 
            +
              homepage_uri: https://github.com/matthutchinson/acts_as_textcaptcha
         | 
| 216 | 
            +
              changelog_uri: https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/CHANGELOG.md
         | 
| 217 | 
            +
              source_code_uri: https://github.com/matthutchinson/acts_as_textcaptcha
         | 
| 218 | 
            +
              bug_tracker_uri: https://github.com/matthutchinson/acts_as_textcaptcha/issues
         | 
| 200 219 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 201 | 
            -
            post_install_message: | 
| 202 | 
            -
            rdoc_options: | 
| 220 | 
            +
            post_install_message:
         | 
| 221 | 
            +
            rdoc_options:
         | 
| 222 | 
            +
            - "--title"
         | 
| 223 | 
            +
            - ActAsTextcaptcha
         | 
| 224 | 
            +
            - "--main"
         | 
| 225 | 
            +
            - README.md
         | 
| 226 | 
            +
            - "-ri"
         | 
| 203 227 | 
             
            require_paths:
         | 
| 204 228 | 
             
            - lib
         | 
| 205 229 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 206 230 | 
             
              requirements:
         | 
| 207 231 | 
             
              - - ">="
         | 
| 208 232 | 
             
                - !ruby/object:Gem::Version
         | 
| 209 | 
            -
                  version: ' | 
| 233 | 
            +
                  version: '2.5'
         | 
| 210 234 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 211 235 | 
             
              requirements:
         | 
| 212 236 | 
             
              - - ">="
         | 
| 213 237 | 
             
                - !ruby/object:Gem::Version
         | 
| 214 238 | 
             
                  version: '0'
         | 
| 215 239 | 
             
            requirements: []
         | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
            signing_key: 
         | 
| 240 | 
            +
            rubygems_version: 3.2.3
         | 
| 241 | 
            +
            signing_key:
         | 
| 219 242 | 
             
            specification_version: 4
         | 
| 220 | 
            -
            summary:  | 
| 221 | 
            -
              API
         | 
| 243 | 
            +
            summary: A text-based logic question captcha for Rails
         | 
| 222 244 | 
             
            test_files: []
         |