invisible_captcha 0.7.0 → 0.8.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57c21321c483942e15254c832843c09cbbba7830
4
- data.tar.gz: 6c18c874fdd903093e1695a362064fd2d2b274cc
3
+ metadata.gz: 03aab9758bfbaf12adb3913f5b37c8423d269c2e
4
+ data.tar.gz: 18e136fc292c192126f7c08d5d60286a4c86ba6b
5
5
  SHA512:
6
- metadata.gz: ed8400648117aac3086d26176f2f9d67eb615f737f4078ed5c817bb3604ac8d85b295266c92bcca9ceeba25953ee68601a69a79044b804b3287bfd8c28b1eaf0
7
- data.tar.gz: be584800363bf741d078f3a09f931e98544da1af91ce7757b78b2d5e4e8f896ab93583f974a7a471f8da20ba37c0fdb85f48e52b1be163cdeba3716b6acc0ca1
6
+ metadata.gz: c60cc1997f5748fef444f1eea60aa3a47b42ee6de60dffa8f320e346608e224594f4252efbe19d7df80edaf8c137729df4357162cb27f2e8b6c7fa1327aed94f
7
+ data.tar.gz: b5b62112cf6ea24aab60e66f589a0756d06e7337c7564e43cdea6a838023334c43e22cba5e486c3c8b1278fe1ef4829a5c925fea3e4917ba919677bd10710049
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012-2014 Marc Anguera Insa
1
+ Copyright 2012-2015 Marc Anguera Insa
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -109,26 +109,16 @@ end
109
109
 
110
110
  ## Options and customization
111
111
 
112
- This section contains the option list of `invisible_captcha` method (controllers side) and the plugin setup options (initializer).
113
-
114
- ### Controller method options:
115
-
116
- The `invisible_captcha` method accepts some options:
117
-
118
- * `only`: apply to given controller actions.
119
- * `except`: exclude to given controller actions.
120
- * `honeypot`: name of honeypot.
121
- * `scope`: name of scope, ie: 'topic[subtitle]' -> 'topic' is the scope.
122
- * `on_spam`: custom callback to be called on spam detection.
112
+ This section contains a description of all plugin options and customizations.
123
113
 
124
114
  ### Plugin options:
125
115
 
126
- You also can customize some plugin options:
116
+ You can customize:
127
117
 
128
118
  * `sentence_for_humans`: text for real users if input field was visible.
129
119
  * `error_message`: error message thrown by model validation (only model implementation).
130
120
  * `honeypots`: collection of default honeypots, used by the view helper, called with no args, to generate the honeypot field name
131
- * `visual_honeypots`: make honeypots visible, useful to test/debug your implementation.
121
+ * `visual_honeypots`: make honeypots visible, also useful to test/debug your implementation.
132
122
 
133
123
  To change these defaults, add the following to an initializer (recommended `config/initializers/invisible_captcha.rb`):
134
124
 
@@ -141,6 +131,28 @@ InvisibleCaptcha.setup do |config|
141
131
  end
142
132
  ```
143
133
 
134
+ ### Controller method options:
135
+
136
+ The `invisible_captcha` method accepts some options:
137
+
138
+ * `only`: apply to given controller actions.
139
+ * `except`: exclude to given controller actions.
140
+ * `honeypot`: name of honeypot.
141
+ * `scope`: name of scope, ie: 'topic[subtitle]' -> 'topic' is the scope.
142
+ * `on_spam`: custom callback to be called on spam detection.
143
+
144
+ ### View helpers options:
145
+
146
+ Using the view/form helper you can override some defaults for the given instance. Actually, it allows to change: `sentence_for_humans` and `visual_honeypots`.
147
+
148
+ ```erb
149
+ <%= form_for(@topic) do |f| %>
150
+ <%= f.invisible_captcha :subtitle, visual_honeypots: true, sentence_for_humans: "Ei, don't fill on this input!" %>
151
+ <!-- or -->
152
+ <%= invisible_captcha visual_honeypots: true, sentence_for_humans: "Ei, don't fill on this input!" %>
153
+ <% end %>
154
+ ```
155
+
144
156
  ## Contribute
145
157
 
146
158
  Any kind of idea, feedback or bug report are welcome! Open an [issue](https://github.com/markets/invisible_captcha/issues) or send a [pull request](https://github.com/markets/invisible_captcha/pulls).
@@ -163,4 +175,4 @@ $ rake web # PORT=4000 (default: 3000)
163
175
 
164
176
  ## License
165
177
 
166
- Copyright (c) 2012-2014 Marc Anguera. Invisible Captcha is released under the [MIT](LICENSE) License.
178
+ Copyright (c) 2012-2015 Marc Anguera. Invisible Captcha is released under the [MIT](LICENSE) License.
@@ -1,7 +1,7 @@
1
1
  module InvisibleCaptcha
2
2
  module FormHelpers
3
- def invisible_captcha(honeypot)
4
- @template.invisible_captcha(honeypot, self.object_name)
3
+ def invisible_captcha(honeypot, options = {})
4
+ @template.invisible_captcha(honeypot, self.object_name, options)
5
5
  end
6
6
  end
7
7
  end
@@ -1,9 +1,17 @@
1
1
  module InvisibleCaptcha
2
2
  class Railtie < Rails::Railtie
3
- ActionController::Base.send :include, InvisibleCaptcha::ControllerExt
4
- ActionController::Base.send :extend, InvisibleCaptcha::ControllerExt::ClassMethods
5
- ActionView::Base.send :include, InvisibleCaptcha::ViewHelpers
6
- ActionView::Helpers::FormBuilder.send :include, InvisibleCaptcha::FormHelpers
7
- ActiveModel::Validations::InvisibleCaptchaValidator = InvisibleCaptcha::InvisibleCaptchaValidator
3
+ initializer 'invisible_captcha.rails_integration' do
4
+ ActiveSupport.on_load(:action_controller) do
5
+ include InvisibleCaptcha::ControllerExt
6
+ extend InvisibleCaptcha::ControllerExt::ClassMethods
7
+ end
8
+
9
+ ActiveSupport.on_load(:action_view) do
10
+ include InvisibleCaptcha::ViewHelpers
11
+ ActionView::Helpers::FormBuilder.send :include, InvisibleCaptcha::FormHelpers
12
+ end
13
+
14
+ ActiveModel::Validations::InvisibleCaptchaValidator = InvisibleCaptcha::InvisibleCaptchaValidator
15
+ end
8
16
  end
9
17
  end
@@ -1,10 +1,7 @@
1
- require 'active_model/validator'
2
-
3
1
  module InvisibleCaptcha
4
2
  class InvisibleCaptchaValidator < ActiveModel::EachValidator
5
3
  def validate_each(record, attribute, value)
6
4
  if invisible_captcha?(record, attribute)
7
- record.errors.clear
8
5
  record.errors[:base] = InvisibleCaptcha.error_message
9
6
  end
10
7
  end
@@ -1,3 +1,3 @@
1
1
  module InvisibleCaptcha
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -5,31 +5,42 @@ module InvisibleCaptcha
5
5
  # @param honeypot [Symbol] name of honeypot, ie: subtitle => input name: subtitle
6
6
  # @param scope [Symbol] name of honeypot scope, ie: topic => input name: topic[subtitle]
7
7
  # @return [String] the generated html
8
- def invisible_captcha(honeypot = nil, scope = nil)
9
- build_invisible_captcha(honeypot, scope)
8
+ def invisible_captcha(honeypot = nil, scope = nil, options = {})
9
+ build_invisible_captcha(honeypot, scope, options)
10
10
  end
11
11
 
12
12
  private
13
13
 
14
- def build_invisible_captcha(honeypot = nil, scope = nil)
14
+ def build_invisible_captcha(honeypot = nil, scope = nil, options = {})
15
+ if honeypot.is_a?(Hash)
16
+ options = honeypot
17
+ honeypot = nil
18
+ end
19
+
15
20
  honeypot = honeypot ? honeypot.to_s : InvisibleCaptcha.get_honeypot
16
- label = InvisibleCaptcha.sentence_for_humans
21
+ label = options[:sentence_for_humans] || InvisibleCaptcha.sentence_for_humans
17
22
  html_id = generate_html_id(honeypot, scope)
18
23
 
19
24
  content_tag(:div, :id => html_id) do
20
- insert_inline_css(html_id) +
21
- label_tag(build_label_name(honeypot, scope), label) +
22
- text_field_tag(build_text_field_name(honeypot, scope))
23
- end.html_safe
25
+ concat visibility_css(html_id, options)
26
+ concat label_tag(build_label_name(honeypot, scope), label)
27
+ concat text_field_tag(build_text_field_name(honeypot, scope))
28
+ end
24
29
  end
25
30
 
26
31
  def generate_html_id(honeypot, scope = nil)
27
32
  "#{scope || honeypot}_#{Time.now.to_i}"
28
33
  end
29
34
 
30
- def insert_inline_css(container_id)
35
+ def visibility_css(container_id, options)
36
+ visibility = if options.key?(:visual_honeypots)
37
+ options[:visual_honeypots]
38
+ else
39
+ InvisibleCaptcha.visual_honeypots
40
+ end
41
+
31
42
  content_tag(:style, :type => 'text/css', :media => 'screen', :scoped => 'scoped') do
32
- "##{container_id} { display:none; }" unless InvisibleCaptcha.visual_honeypots
43
+ "##{container_id} { display:none; }" unless visibility
33
44
  end
34
45
  end
35
46
 
@@ -10,7 +10,7 @@ class TopicsController < ApplicationController
10
10
  @topic = Topic.new(params[:topic])
11
11
 
12
12
  if @topic.valid?
13
- redirect_to new_topic_path
13
+ redirect_to new_topic_path(context: params[:context]), notice: 'Topic valid!'
14
14
  else
15
15
  render action: 'new'
16
16
  end
@@ -4,6 +4,7 @@ class Topic
4
4
 
5
5
  attr_accessor :title, :body, :subtitle
6
6
 
7
+ validates :title, presence: true
7
8
  validates :subtitle, invisible_captcha: true
8
9
 
9
10
  def initialize(attributes = {})
@@ -8,6 +8,17 @@
8
8
  </head>
9
9
  <body>
10
10
 
11
+ <%= link_to "Default", new_topic_path %> |
12
+ <%= link_to "With visual honeypots", new_topic_path(context: "visual_honeypots") %>
13
+
14
+ <% flash.each do |key, value| %>
15
+ <ul>
16
+ <li>
17
+ <%= "[#{key.upcase}] #{value}" %>
18
+ </li>
19
+ </ul>
20
+ <% end %>
21
+
11
22
  <%= yield %>
12
23
 
13
24
  </body>
@@ -1,16 +1,35 @@
1
1
  <h1>New topic</h1>
2
2
 
3
+ <% if @topic.errors.any? %>
4
+ <div>
5
+ <h2><%= pluralize(@topic.errors.count, "error") %> prohibited this record from being saved:</h2>
6
+ <ul>
7
+ <% @topic.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
3
14
  <%= form_for(@topic) do |f| %>
4
- <%= f.invisible_captcha :subtitle %>
15
+ <%= hidden_field_tag :context, params[:context] %>
16
+
17
+ <% if params[:context].blank? || params[:context] == 'default' %>
18
+ <%= f.invisible_captcha :subtitle %>
19
+ <% else %>
20
+ <%= f.invisible_captcha :subtitle, visual_honeypots: true %>
21
+ <% end %>
5
22
 
6
23
  <div class="field">
7
24
  <%= f.label :title %><br />
8
25
  <%= f.text_field :title %>
9
26
  </div>
27
+
10
28
  <div class="field">
11
29
  <%= f.label :body %><br />
12
30
  <%= f.text_area :body %>
13
31
  </div>
32
+
14
33
  <div class="actions">
15
34
  <%= f.submit %>
16
35
  </div>
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe InvisibleCaptcha::InvisibleCaptchaValidator do
4
4
  it 'do not pass validations if honeypot is presented' do
5
- topic = Topic.new
5
+ topic = Topic.new(title: 'foo')
6
6
  expect(topic.valid?).to be true
7
7
 
8
8
  topic.subtitle = 'foo'
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe InvisibleCaptcha::ViewHelpers, type: :helper do
4
+ def helper_output(honeypot = nil, scope = nil, options = {})
5
+ honeypot ||= InvisibleCaptcha.get_honeypot
6
+ input_id = build_label_name(honeypot, scope)
7
+ input_name = build_text_field_name(honeypot, scope)
8
+ html_id = generate_html_id(honeypot, scope)
9
+ visibilty = if options.key?(:visual_honeypots)
10
+ options[:visual_honeypots]
11
+ else
12
+ InvisibleCaptcha.visual_honeypots
13
+ end
14
+
15
+ %{
16
+ <div id="#{html_id}">
17
+ <style type="text/css" media="screen" scoped="scoped">#{visibilty ? '' : "##{html_id} { display:none; }"}</style>
18
+ <label for="#{input_id}">#{InvisibleCaptcha.sentence_for_humans}</label>
19
+ <input type="text" name="#{input_name}" id="#{input_id}" />
20
+ </div>
21
+ }.gsub(/\s+/, ' ').strip.gsub('> <', '><')
22
+ end
23
+
24
+ before do
25
+ allow(Time).to receive(:now).and_return(Time.parse('Feb 19 1986'))
26
+ InvisibleCaptcha.visual_honeypots = false
27
+ end
28
+
29
+ it 'with no arguments' do
30
+ InvisibleCaptcha.honeypots = [:foo_id]
31
+ expect(invisible_captcha).to eq(helper_output)
32
+ end
33
+
34
+ it 'with specific honeypot' do
35
+ expect(invisible_captcha(:subtitle)).to eq(helper_output(:subtitle))
36
+ end
37
+
38
+ it 'with specific honeypot and scope' do
39
+ expect(invisible_captcha(:subtitle, :topic)).to eq(helper_output(:subtitle, :topic))
40
+ end
41
+
42
+ context "honeypot visibilty" do
43
+ it 'visible from defaults' do
44
+ InvisibleCaptcha.honeypots = [:foo_id]
45
+ InvisibleCaptcha.visual_honeypots = true
46
+
47
+ expect(invisible_captcha).to eq(helper_output)
48
+ end
49
+
50
+ it 'visible from given instance (default override)' do
51
+ InvisibleCaptcha.honeypots = [:foo_id]
52
+
53
+ expect(invisible_captcha(visual_honeypots: true)).to eq(helper_output(nil, nil, visual_honeypots: true))
54
+ end
55
+
56
+ it 'invisible from given instance (default override)' do
57
+ InvisibleCaptcha.honeypots = [:foo_id]
58
+ InvisibleCaptcha.visual_honeypots = true
59
+
60
+ expect(invisible_captcha(visual_honeypots: false)).to eq(helper_output(nil, nil, visual_honeypots: false))
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invisible_captcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Anguera Insa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-22 00:00:00.000000000 Z
11
+ date: 2015-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -96,10 +96,10 @@ files:
96
96
  - spec/dummy/public/500.html
97
97
  - spec/dummy/public/favicon.ico
98
98
  - spec/dummy/script/rails
99
- - spec/helpers_spec.rb
100
99
  - spec/invisible_captcha_spec.rb
101
100
  - spec/spec_helper.rb
102
101
  - spec/validator_spec.rb
102
+ - spec/view_helpers_spec.rb
103
103
  homepage: https://github.com/markets/invisible_captcha
104
104
  licenses:
105
105
  - MIT
@@ -161,7 +161,7 @@ test_files:
161
161
  - spec/dummy/public/500.html
162
162
  - spec/dummy/public/favicon.ico
163
163
  - spec/dummy/script/rails
164
- - spec/helpers_spec.rb
165
164
  - spec/invisible_captcha_spec.rb
166
165
  - spec/spec_helper.rb
167
166
  - spec/validator_spec.rb
167
+ - spec/view_helpers_spec.rb
data/spec/helpers_spec.rb DELETED
@@ -1,43 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe InvisibleCaptcha::ViewHelpers, type: :helper do
4
- def helper_output(honeypot = nil, scope = nil)
5
- honeypot ||= InvisibleCaptcha.get_honeypot
6
- input_id = build_label_name(honeypot, scope)
7
- input_name = build_text_field_name(honeypot, scope)
8
- html_id = generate_html_id(honeypot, scope)
9
-
10
- %{
11
- <div id="#{html_id}">
12
- <style media="screen" scoped="scoped" type="text/css">#{InvisibleCaptcha.visual_honeypots ? '' : "##{html_id} { display:none; }"}</style>
13
- <label for="#{input_id}">#{InvisibleCaptcha.sentence_for_humans}</label>
14
- <input id="#{input_id}" name="#{input_name}" type="text" />
15
- </div>
16
- }.gsub(/\s+/, ' ').strip.gsub('> <', '><')
17
- end
18
-
19
- before do
20
- allow(Time).to receive(:now).and_return(Time.parse('Feb 19 1986'))
21
- InvisibleCaptcha.visual_honeypots = false
22
- end
23
-
24
- it 'view helper with no arguments' do
25
- InvisibleCaptcha.honeypots = [:foo_id]
26
- expect(invisible_captcha).to eq(helper_output)
27
- end
28
-
29
- it 'view helper with specific honeypot' do
30
- expect(invisible_captcha(:subtitle)).to eq(helper_output(:subtitle))
31
- end
32
-
33
- it 'view helper with specific honeypot and scope' do
34
- expect(invisible_captcha(:subtitle, :topic)).to eq(helper_output(:subtitle, :topic))
35
- end
36
-
37
- it 'view helper with visual honeypots enabled' do
38
- InvisibleCaptcha.honeypots = [:foo_id]
39
- InvisibleCaptcha.visual_honeypots = true
40
-
41
- expect(invisible_captcha).to eq(helper_output)
42
- end
43
- end