molasses_jar 0.0.2 → 0.0.3
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.
- data/README.md +39 -6
- data/VERSION +1 -1
- data/lib/molasses_jar/extensions.rb +22 -5
- data/molasses_jar.gemspec +1 -1
- data/spec/molasses_jar_spec.rb +143 -1
- data/spec/spec_helper.rb +9 -73
- metadata +2 -2
data/README.md
CHANGED
@@ -2,23 +2,56 @@
|
|
2
2
|
|
3
3
|
A simple ActiveRecord extension for creating honeypot style captchas.
|
4
4
|
|
5
|
+
== Nuts and Bolts
|
6
|
+
|
7
|
+
MolassesJar will add simple honeypot verification to any model you wish. It creates an attribute called :molasses_jar on the desired object and then checks to see if there is a value assigned to it.
|
8
|
+
|
9
|
+
MolassesJar will look for a boolean attribute called ```spam``` on your model. If it finds it, it will update the attribute to be true if it thinks the record is being submitted by a robot, thus preventing the loss of legitimate content.
|
10
|
+
|
11
|
+
If it does not find a ```spam``` attribute on your model, it will add an error to the molasses_jar attribute, thus preventing the model from validating and saving.
|
12
|
+
|
5
13
|
== How To Use
|
6
14
|
|
7
|
-
|
15
|
+
=== Install the gem through Bundler
|
16
|
+
|
17
|
+
gem "molasses_jar"
|
18
|
+
|
19
|
+
=== If flagging is desired, add a spam attribute to your Model
|
20
|
+
|
21
|
+
Generate a migration to add the spam attribute to your model. It is recommended that you index the attribute sice it will appear in a where clause through the included scope
|
22
|
+
|
23
|
+
def change
|
24
|
+
add_column :contact_forms, :spam, :boolean, :default => false
|
25
|
+
add_index :contact_forms, :spam
|
26
|
+
ContactForm.update_all(:spam => false)
|
27
|
+
end
|
28
|
+
|
29
|
+
=== Add the Extensions to your Model
|
8
30
|
|
9
31
|
class ContactForm < ActiveRecord::Base
|
10
32
|
include MolassesJar::Extensions
|
11
33
|
end
|
12
34
|
|
13
|
-
|
35
|
+
=== Add the input to your forms
|
36
|
+
|
37
|
+
You will need to add an input to your object's form with the attribute :molasses_jar. Then use css, to either ```display: none;``` or move the form off the screen using absolute positioning. Best practices suggests you include a label with your input field and include some sort of message that says "If you're a human, please leave this field blank" to insure accessability.
|
38
|
+
|
39
|
+
HTML/HAML
|
14
40
|
|
15
|
-
|
41
|
+
= form.label :molasses_jar, "If you are a human, please leave this field blank", :class => "agglutinative"
|
42
|
+
= form.text_field :molasses_jar, :class => "agglutinative"
|
43
|
+
|
44
|
+
CSS
|
45
|
+
|
46
|
+
.agglutinative {
|
47
|
+
display: none;
|
48
|
+
}
|
49
|
+
|
50
|
+
== Coming Soon
|
16
51
|
|
17
52
|
* Form Helper to create the form input
|
18
|
-
*
|
53
|
+
* Migration generator for the spam attribute
|
19
54
|
* Stylesheet generator to create the stylesheet
|
20
|
-
* Accessibility improvements for readers
|
21
|
-
|
22
55
|
|
23
56
|
== Interesting Reads on the Honeypot Approach
|
24
57
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
@@ -3,20 +3,37 @@ module MolassesJar
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
attr_accessor :molasses_jar
|
6
|
+
attr_accessor :molasses_jar
|
7
7
|
|
8
|
-
scope :spammy, where(:spam => true)
|
8
|
+
scope :spammy, where(:spam => true)
|
9
9
|
scope :not_spammy, where(:spam => false)
|
10
10
|
|
11
11
|
validate :mark_as_spam?
|
12
12
|
|
13
13
|
def mark_as_spam?
|
14
|
-
|
14
|
+
if has_spam_attribute? and caught_something?
|
15
|
+
self.spam = true
|
16
|
+
elsif !has_spam_attribute? and caught_something?
|
17
|
+
errors.add(:molasses_jar, "")
|
18
|
+
end
|
15
19
|
end
|
16
|
-
|
20
|
+
|
17
21
|
def spam?
|
18
|
-
|
22
|
+
if has_spam_attribute?
|
23
|
+
self.spam
|
24
|
+
else
|
25
|
+
caught_something?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def caught_something?
|
30
|
+
self.molasses_jar.present?
|
19
31
|
end
|
32
|
+
|
33
|
+
def has_spam_attribute?
|
34
|
+
self.attributes.include?("spam")
|
35
|
+
end
|
36
|
+
|
20
37
|
end
|
21
38
|
end
|
22
39
|
end
|
data/molasses_jar.gemspec
CHANGED
data/spec/molasses_jar_spec.rb
CHANGED
@@ -2,6 +2,148 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe MolassesJar do
|
4
4
|
|
5
|
-
|
5
|
+
describe "a Molasses Jar without a Spam attribute" do
|
6
|
+
before(:each) do
|
7
|
+
@model = ContactForm.new
|
8
|
+
end
|
9
|
+
|
10
|
+
context "molasses_jar attributes" do
|
11
|
+
it "should have a molasses_jar attribute" do
|
12
|
+
lambda{ @model.molasses_jar }.should_not raise_error
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should initialize as nil" do
|
16
|
+
@model.molasses_jar.nil?.should be true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not have a spam attribute" do
|
20
|
+
@model.has_spam_attribute?.should be false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "scopes" do
|
25
|
+
it "should respond to spammy" do
|
26
|
+
ContactForm.respond_to?(:spammy).should be true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should respond to not_spammy" do
|
30
|
+
ContactForm.respond_to?(:not_spammy).should be true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with a molasses_jar value" do
|
35
|
+
before(:each) do
|
36
|
+
@model.update_attributes(:molasses_jar => "I am a robot")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be valid" do
|
40
|
+
@model.should_not be_valid
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return true for spam?" do
|
44
|
+
@model.spam?.should be true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have caught_something?" do
|
48
|
+
@model.caught_something?.should be true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "without a molasses_jar value" do
|
53
|
+
before(:each) do
|
54
|
+
@model.update_attributes(:molasses_jar => "")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be valid" do
|
58
|
+
@model.should be_valid
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return false for spam?" do
|
62
|
+
@model.spam?.should be false
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not have caught_something?" do
|
66
|
+
@model.caught_something?.should be false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "a Molasses Jar with a Spam attribute" do
|
72
|
+
before(:each) do
|
73
|
+
@model = Feedback.new
|
74
|
+
end
|
75
|
+
|
76
|
+
context "molasses_jar attributes" do
|
77
|
+
it "should have a molasses_jar attribute" do
|
78
|
+
lambda{ @model.molasses_jar }.should_not raise_error
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should initialize as nil" do
|
82
|
+
@model.molasses_jar.nil?.should be true
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have a spam attribute" do
|
86
|
+
@model.has_spam_attribute?.should be true
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should initialize as nil" do
|
90
|
+
@model.spam.nil?.should be true
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "scopes" do
|
95
|
+
it "should respond to spammy" do
|
96
|
+
Feedback.respond_to?(:spammy).should be true
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should respond to not_spammy" do
|
100
|
+
Feedback.respond_to?(:not_spammy).should be true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with a molasses_jar value" do
|
105
|
+
before(:each) do
|
106
|
+
@model.update_attributes(:molasses_jar => "I am a robot")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should be valid" do
|
110
|
+
@model.should be_valid
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should be marked as spam" do
|
114
|
+
@model.spam.should be true
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should return true for spam?" do
|
118
|
+
@model.spam?.should be true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should have caught_something?" do
|
122
|
+
@model.caught_something?.should be true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "without a molasses_jar value" do
|
127
|
+
before(:each) do
|
128
|
+
@model.update_attributes(:molasses_jar => "")
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should be valid" do
|
132
|
+
@model.should be_valid
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should not be marked as spam" do
|
136
|
+
@model.spam.should be (false || nil)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should return false for spam?" do
|
140
|
+
@model.spam?.should be (false || nil)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should not have caught_something?" do
|
144
|
+
@model.caught_something?.should be false
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
6
148
|
|
7
149
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -31,82 +31,18 @@ ActiveRecord::Schema.define do
|
|
31
31
|
table.column :email, :string
|
32
32
|
table.column :message, :text
|
33
33
|
end
|
34
|
+
|
35
|
+
create_table :feedbacks do |table|
|
36
|
+
table.column :email, :string
|
37
|
+
table.column :message, :text
|
38
|
+
table.column :spam, :boolean
|
39
|
+
end
|
34
40
|
end
|
35
41
|
|
36
42
|
class ContactForm < ActiveRecord::Base
|
37
43
|
include MolassesJar::Extensions
|
38
44
|
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
# Usage Example:
|
45
|
-
# In your model spec, it_should_behave_like "a molasses_jar", :singular_model_name
|
46
|
-
#
|
47
|
-
|
48
|
-
shared_examples "a molasses_jar" do |model|
|
49
|
-
|
50
|
-
describe "a Molasses Jar" do
|
51
|
-
before(:each) do
|
52
|
-
eval "@model = #{model.to_s.camelize}.new"
|
53
|
-
end
|
54
|
-
|
55
|
-
context "molasses_jar attributes" do
|
56
|
-
it "should have a molasses_jar attribute" do
|
57
|
-
lambda{ @model.molasses_jar }.should_not raise_error
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should initialize as nil" do
|
61
|
-
@model.molasses_jar.nil?.should be true
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "scopes" do
|
66
|
-
it "should respond to spammy" do
|
67
|
-
eval "#{model.to_s.camelize}.respond_to?(:spammy).should be true"
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should respond to not_spammy" do
|
71
|
-
eval "#{model.to_s.camelize}.respond_to?(:not_spammy).should be true"
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context "with a molasses_jar value" do
|
76
|
-
before(:each) do
|
77
|
-
@model.update_attributes(:molasses_jar => "I am a robot")
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should be valid" do
|
81
|
-
@model.should be_valid
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should be marked as spam" do
|
85
|
-
@model.spam.should be true
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should return true for spam?" do
|
89
|
-
@model.spam?.should be true
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context "without a molasses_jar value" do
|
94
|
-
before(:each) do
|
95
|
-
@model.update_attributes(:molasses_jar => "")
|
96
|
-
end
|
97
|
-
|
98
|
-
it "should be valid" do
|
99
|
-
@model.should be_valid
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should not be marked as spam" do
|
103
|
-
@model.spam.should be (false || nil)
|
104
|
-
end
|
105
|
-
|
106
|
-
it "should return false for spam?" do
|
107
|
-
@model.spam?.should be (false || nil)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
46
|
+
class Feedback < ActiveRecord::Base
|
47
|
+
include MolassesJar::Extensions
|
48
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: molasses_jar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -176,7 +176,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
176
|
version: '0'
|
177
177
|
segments:
|
178
178
|
- 0
|
179
|
-
hash:
|
179
|
+
hash: -4059900841103394163
|
180
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
181
|
none: false
|
182
182
|
requirements:
|