kamcaptcha 0.1.0 → 0.2.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.
- data/kamcaptcha.gemspec +1 -1
- data/lib/kamcaptcha.rb +25 -16
- data/lib/kamcaptcha/helper.rb +15 -7
- data/lib/kamcaptcha/token.rb +19 -0
- data/lib/kamcaptcha/validation.rb +3 -1
- data/test/test_helper.rb +1 -1
- data/test/unit/test_generator.rb +0 -1
- data/test/unit/test_helper.rb +65 -0
- data/test/unit/test_kamcaptcha.rb +0 -2
- data/test/unit/test_token.rb +28 -0
- metadata +100 -106
data/kamcaptcha.gemspec
CHANGED
data/lib/kamcaptcha.rb
CHANGED
@@ -1,28 +1,37 @@
|
|
1
1
|
require "digest"
|
2
2
|
|
3
|
+
require 'kamcaptcha/token'
|
4
|
+
|
3
5
|
# You must configure Kamcaptcha with a path to the generated words, and a salt.
|
4
6
|
# The salt must be the same you used when generating words.
|
5
7
|
module Kamcaptcha
|
6
|
-
|
7
8
|
class << self
|
8
|
-
attr_accessor :salt, :path
|
9
|
-
|
9
|
+
attr_accessor :salt, :path, :template
|
10
|
+
attr_writer :prefix
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def prefix
|
13
|
+
@prefix || ""
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
def random
|
17
|
+
images[rand(images.size)]
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
20
|
+
def images
|
21
|
+
@images ||= Dir.glob("#{path}/*.*").map { |f| File.basename(f) }
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def encrypt(string)
|
25
|
+
raise "You must configure a salt" if Kamcaptcha.salt.nil?
|
26
|
+
Digest::SHA2.hexdigest("#{salt}::#{string}")
|
27
|
+
end
|
27
28
|
end
|
28
29
|
end
|
30
|
+
|
31
|
+
Kamcaptcha.template = <<-END
|
32
|
+
<div class="kamcaptcha">
|
33
|
+
<label for="kamcaptcha_input"><%= label %></label><input type="text" id="kamcaptcha_input" name="kamcaptcha[input]" />
|
34
|
+
<input type="hidden" name="kamcaptcha[validation]" value="<%= token %>" />
|
35
|
+
<img src="<%= image %>" />
|
36
|
+
</div>
|
37
|
+
END
|
data/lib/kamcaptcha/helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
1
3
|
module Kamcaptcha
|
2
4
|
module Helper
|
3
5
|
DEFAULT_LABEL = "Please type the characters in the image below"
|
@@ -5,16 +7,22 @@ module Kamcaptcha
|
|
5
7
|
# Usage: <%= kamcaptcha :label => "Please prove that you're a human" %>
|
6
8
|
def kamcaptcha(options = {})
|
7
9
|
label = options.fetch(:label, DEFAULT_LABEL)
|
10
|
+
template = options.fetch(:template, Kamcaptcha.template)
|
11
|
+
|
8
12
|
image = Kamcaptcha.random
|
13
|
+
|
9
14
|
token = image.split(".").first
|
15
|
+
token = instance_exec(token, &Kamcaptcha::Token.generator) if Kamcaptcha::Token.generator
|
16
|
+
|
17
|
+
image = File.join('/', Kamcaptcha.prefix, image)
|
18
|
+
|
19
|
+
instance_exec(token, &Kamcaptcha::Token.store) if Kamcaptcha::Token.store
|
20
|
+
|
21
|
+
# Makes sure the ERB template only gets these variables: label, token, image
|
22
|
+
form = ERB.new(template).result(OpenStruct.new(:label => label, :token => token, :image => image).send(:binding))
|
10
23
|
|
11
|
-
|
12
|
-
|
13
|
-
<label for="kamcaptcha[input]">#{label}</label><input type="text" id="kamcaptcha[input]" name="kamcaptcha[input]" />
|
14
|
-
<input type="hidden" name="kamcaptcha[validation]" value="#{token}" />
|
15
|
-
<img src="#{image}" />
|
16
|
-
</div
|
17
|
-
FORM
|
24
|
+
form = form.html_safe if form.respond_to?(:html_safe)
|
25
|
+
form
|
18
26
|
end
|
19
27
|
|
20
28
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Kamcaptcha
|
2
|
+
module Token
|
3
|
+
class << self
|
4
|
+
attr_accessor :generator, :lookup, :store
|
5
|
+
|
6
|
+
def valid?(validation, input)
|
7
|
+
input = Kamcaptcha.encrypt(input.to_s.delete(" ").downcase)
|
8
|
+
input = instance_exec(input, &generator) if generator
|
9
|
+
|
10
|
+
input == validation
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Default form lookup
|
17
|
+
Kamcaptcha::Token.lookup = lambda do
|
18
|
+
params[:kamcaptcha][:validation]
|
19
|
+
end
|
@@ -5,7 +5,9 @@ module Kamcaptcha
|
|
5
5
|
return false unless params.respond_to?(:key?)
|
6
6
|
return false unless params.key?(:kamcaptcha)
|
7
7
|
|
8
|
-
Kamcaptcha.
|
8
|
+
token = instance_exec(&Kamcaptcha::Token.lookup)
|
9
|
+
|
10
|
+
Kamcaptcha::Token.valid?(token, params[:kamcaptcha][:input])
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
data/test/test_helper.rb
CHANGED
data/test/unit/test_generator.rb
CHANGED
data/test/unit/test_helper.rb
CHANGED
@@ -17,5 +17,70 @@ describe Kamcaptcha::Helper do
|
|
17
17
|
it "uses a default label" do
|
18
18
|
assert_match /#{Kamcaptcha::Helper::DEFAULT_LABEL}/, subject
|
19
19
|
end
|
20
|
+
|
21
|
+
it "uses the token" do
|
22
|
+
assert_match /value="hello"/, subject
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "should use the token storage if it exists" do
|
26
|
+
before(:all) { @store, Kamcaptcha::Token.store = Kamcaptcha::Token.store, lambda {|token| @token = token}}
|
27
|
+
after(:all) { Kamcaptcha::Token.store = @store }
|
28
|
+
|
29
|
+
it "should set the storage" do
|
30
|
+
subject # will store the token
|
31
|
+
|
32
|
+
assert_equal "hello", @token
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "html safety" do
|
37
|
+
before(:all) do
|
38
|
+
class String
|
39
|
+
def html_safe
|
40
|
+
"safe"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
after(:all) do
|
46
|
+
class String
|
47
|
+
remove_method :html_safe
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should call #html_safe" do
|
52
|
+
assert_equal "safe", subject
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "image path" do
|
57
|
+
before(:all) { @prefix, Kamcaptcha.prefix = Kamcaptcha.prefix, "omg/123" }
|
58
|
+
after(:all) { Kamcaptcha.prefix = @prefix }
|
59
|
+
|
60
|
+
subject { Kamcaptcha.stub(:random, "hello.png") { kamcaptcha(:template => "<%= image %>") } }
|
61
|
+
|
62
|
+
it "should prefix image path" do
|
63
|
+
assert_equal "/omg/123/hello.png", subject
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "should use custom generator if it exists" do
|
68
|
+
before(:all) { @generator, Kamcaptcha::Token.generator = Kamcaptcha::Token.generator, lambda {|_| "token"}}
|
69
|
+
after(:all) { Kamcaptcha::Token.generator = @generator }
|
70
|
+
|
71
|
+
subject { Kamcaptcha.stub(:random, "hello.png") { kamcaptcha(:template => "<%= token %>") } }
|
72
|
+
|
73
|
+
it "should use the custom generator" do
|
74
|
+
assert_equal "token", subject
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "when given a template" do
|
79
|
+
subject { Kamcaptcha.stub(:random, "hello.png") { kamcaptcha(:template => "this-isnt-real") } }
|
80
|
+
|
81
|
+
it "should use custom template" do
|
82
|
+
assert_equal "this-isnt-real", subject
|
83
|
+
end
|
84
|
+
end
|
20
85
|
end
|
21
86
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path("test/test_helper")
|
2
|
+
|
3
|
+
describe Kamcaptcha::Token do
|
4
|
+
describe "#valid?" do
|
5
|
+
let(:validation) { Kamcaptcha.encrypt("hello") }
|
6
|
+
|
7
|
+
it "should handle other types" do
|
8
|
+
refute Kamcaptcha::Token.valid?(validation, 123)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should handle spaces" do
|
12
|
+
assert Kamcaptcha::Token.valid?(validation, "h e l l o")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should handle mixed case" do
|
16
|
+
assert Kamcaptcha::Token.valid?(validation, "HeLLo")
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "with a custom generator" do
|
20
|
+
before(:all) { @generator, Kamcaptcha::Token.generator = Kamcaptcha::Token.generator, lambda {|_| "hello"}}
|
21
|
+
after(:all) { Kamcaptcha::Token.generator = @generator }
|
22
|
+
|
23
|
+
it "should call the generator" do
|
24
|
+
assert Kamcaptcha::Token.valid?("hello", "anything")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,118 +1,119 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: kamcaptcha
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Morten Primdahl
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-11-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: trollop
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 2
|
31
|
-
- 0
|
32
|
-
version: "2.0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
33
22
|
type: :runtime
|
34
|
-
version_requirements: *id001
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: rake
|
37
23
|
prerelease: false
|
38
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
25
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
47
38
|
type: :development
|
48
|
-
version_requirements: *id002
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: bundler
|
51
39
|
prerelease: false
|
52
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
41
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
61
54
|
type: :development
|
62
|
-
version_requirements: *id003
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: rmagick
|
65
55
|
prerelease: false
|
66
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rmagick
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
67
65
|
none: false
|
68
|
-
requirements:
|
69
|
-
- -
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
|
72
|
-
segments:
|
73
|
-
- 0
|
74
|
-
version: "0"
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
75
70
|
type: :development
|
76
|
-
version_requirements: *id004
|
77
|
-
- !ruby/object:Gem::Dependency
|
78
|
-
name: minitest
|
79
71
|
prerelease: false
|
80
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: minitest
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
|
86
|
-
segments:
|
87
|
-
- 0
|
88
|
-
version: "0"
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
89
86
|
type: :development
|
90
|
-
version_requirements: *id005
|
91
|
-
- !ruby/object:Gem::Dependency
|
92
|
-
name: uuidtools
|
93
87
|
prerelease: false
|
94
|
-
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
89
|
none: false
|
96
|
-
requirements:
|
97
|
-
- -
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: uuidtools
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
104
101
|
version: 2.1.3
|
105
102
|
type: :development
|
106
|
-
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.1.3
|
107
110
|
description: Helps humankind with simpler captchas
|
108
111
|
email: primdahl@me.com
|
109
|
-
executables:
|
112
|
+
executables:
|
110
113
|
- kamcaptcha
|
111
114
|
extensions: []
|
112
|
-
|
113
115
|
extra_rdoc_files: []
|
114
|
-
|
115
|
-
files:
|
116
|
+
files:
|
116
117
|
- .gitignore
|
117
118
|
- .travis.yml
|
118
119
|
- Gemfile
|
@@ -124,44 +125,37 @@ files:
|
|
124
125
|
- lib/kamcaptcha.rb
|
125
126
|
- lib/kamcaptcha/generator.rb
|
126
127
|
- lib/kamcaptcha/helper.rb
|
128
|
+
- lib/kamcaptcha/token.rb
|
127
129
|
- lib/kamcaptcha/validation.rb
|
128
130
|
- test/test_helper.rb
|
129
131
|
- test/unit/test_generator.rb
|
130
132
|
- test/unit/test_helper.rb
|
131
133
|
- test/unit/test_kamcaptcha.rb
|
134
|
+
- test/unit/test_token.rb
|
132
135
|
- test/unit/test_validation.rb
|
133
136
|
homepage: http://github.com/morten/kamcaptcha
|
134
|
-
licenses:
|
137
|
+
licenses:
|
135
138
|
- MIT
|
136
139
|
post_install_message:
|
137
140
|
rdoc_options: []
|
138
|
-
|
139
|
-
require_paths:
|
141
|
+
require_paths:
|
140
142
|
- lib
|
141
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
144
|
none: false
|
143
|
-
requirements:
|
144
|
-
- -
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
|
147
|
-
|
148
|
-
- 0
|
149
|
-
version: "0"
|
150
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ! '>='
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
150
|
none: false
|
152
|
-
requirements:
|
153
|
-
- -
|
154
|
-
- !ruby/object:Gem::Version
|
155
|
-
|
156
|
-
segments:
|
157
|
-
- 0
|
158
|
-
version: "0"
|
151
|
+
requirements:
|
152
|
+
- - ! '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
159
155
|
requirements: []
|
160
|
-
|
161
156
|
rubyforge_project:
|
162
|
-
rubygems_version: 1.8.
|
157
|
+
rubygems_version: 1.8.23
|
163
158
|
signing_key:
|
164
159
|
specification_version: 3
|
165
160
|
summary: A captcha image generator that's a little less retarded
|
166
161
|
test_files: []
|
167
|
-
|