yl_simple_captcha 1.1.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 +7 -0
- data/README.md +335 -0
- data/Rakefile +63 -0
- data/lib/generators/USAGE +7 -0
- data/lib/generators/simple_captcha_generator.rb +22 -0
- data/lib/generators/templates/migration.rb +15 -0
- data/lib/generators/templates/partial.erb +41 -0
- data/lib/generators/templates/partial.haml +28 -0
- data/lib/simple_captcha/controller.rb +32 -0
- data/lib/simple_captcha/engine.rb +26 -0
- data/lib/simple_captcha/form_builder.rb +43 -0
- data/lib/simple_captcha/formtastic.rb +15 -0
- data/lib/simple_captcha/image.rb +86 -0
- data/lib/simple_captcha/middleware.rb +92 -0
- data/lib/simple_captcha/model_helpers.rb +74 -0
- data/lib/simple_captcha/simple_captcha_data.rb +32 -0
- data/lib/simple_captcha/simple_captcha_data_mongoid.rb +25 -0
- data/lib/simple_captcha/utils.rb +36 -0
- data/lib/simple_captcha/version.rb +3 -0
- data/lib/simple_captcha/view.rb +158 -0
- data/lib/simple_captcha.rb +83 -0
- data/lib/yl_simple_captcha.rb +1 -0
- metadata +135 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
module SimpleCaptcha #:nodoc
|
3
|
+
module ImageHelpers #:nodoc
|
4
|
+
|
5
|
+
mattr_accessor :image_styles
|
6
|
+
@@image_styles = {
|
7
|
+
'embosed_silver' => ['-fill darkblue', '-shade 20x60', '-background white'],
|
8
|
+
'simply_red' => ['-fill darkred', '-background white'],
|
9
|
+
'simply_green' => ['-fill darkgreen', '-background white'],
|
10
|
+
'simply_blue' => ['-fill darkblue', '-background white'],
|
11
|
+
'distorted_black' => ['-fill darkblue', '-edge 10', '-background white'],
|
12
|
+
'all_black' => ['-fill darkblue', '-edge 2', '-background white'],
|
13
|
+
'charcoal_grey' => ['-fill darkblue', '-charcoal 5', '-background white'],
|
14
|
+
'almost_invisible' => ['-fill red', '-solarize 50', '-background white']
|
15
|
+
}
|
16
|
+
|
17
|
+
DISTORTIONS = ['low', 'medium', 'high']
|
18
|
+
|
19
|
+
IMPLODES = { 'none' => 0, 'low' => 0.1, 'medium' => 0.2, 'high' => 0.3 }
|
20
|
+
DEFAULT_IMPLODE = 'medium'
|
21
|
+
|
22
|
+
class << self
|
23
|
+
|
24
|
+
def image_params(key = 'simply_blue')
|
25
|
+
image_keys = @@image_styles.keys
|
26
|
+
|
27
|
+
style = begin
|
28
|
+
if key == 'random'
|
29
|
+
image_keys[rand(image_keys.length)]
|
30
|
+
else
|
31
|
+
image_keys.include?(key) ? key : 'simply_blue'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
@@image_styles[style]
|
36
|
+
end
|
37
|
+
|
38
|
+
def distortion(key='low')
|
39
|
+
key =
|
40
|
+
key == 'random' ?
|
41
|
+
DISTORTIONS[rand(DISTORTIONS.length)] :
|
42
|
+
DISTORTIONS.include?(key) ? key : 'low'
|
43
|
+
case key.to_s
|
44
|
+
when 'low' then return [0 + rand(2), 80 + rand(20)]
|
45
|
+
when 'medium' then return [2 + rand(2), 50 + rand(20)]
|
46
|
+
when 'high' then return [4 + rand(2), 30 + rand(20)]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def implode
|
51
|
+
IMPLODES[SimpleCaptcha.implode] || IMPLODES[DEFAULT_IMPLODE]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if RUBY_VERSION < '1.9'
|
56
|
+
class Tempfile < ::Tempfile
|
57
|
+
# Replaces Tempfile's +make_tmpname+ with one that honors file extensions.
|
58
|
+
def make_tmpname(basename, n = 0)
|
59
|
+
extension = File.extname(basename)
|
60
|
+
sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n, extension)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def generate_simple_captcha_image(simple_captcha_key) #:nodoc
|
68
|
+
amplitude, frequency = ImageHelpers.distortion(SimpleCaptcha.distortion)
|
69
|
+
text = Utils::simple_captcha_value(simple_captcha_key)
|
70
|
+
|
71
|
+
params = ImageHelpers.image_params(SimpleCaptcha.image_style).dup
|
72
|
+
params << "-size #{SimpleCaptcha.image_size}"
|
73
|
+
params << "-wave #{amplitude}x#{frequency}"
|
74
|
+
params << "-gravity Center"
|
75
|
+
params << "-pointsize 22"
|
76
|
+
params << "-implode #{ImageHelpers.implode}"
|
77
|
+
params << "label:#{text}"
|
78
|
+
if SimpleCaptcha.noise and SimpleCaptcha.noise > 0
|
79
|
+
params << "-evaluate Uniform-noise #{SimpleCaptcha.noise}"
|
80
|
+
end
|
81
|
+
params << "jpeg:-"
|
82
|
+
|
83
|
+
SimpleCaptcha::Utils::run("convert", params.join(' '))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module SimpleCaptcha
|
3
|
+
class Middleware
|
4
|
+
include SimpleCaptcha::ImageHelpers
|
5
|
+
include SimpleCaptcha::ViewHelper
|
6
|
+
|
7
|
+
DEFAULT_SEND_FILE_OPTIONS = {
|
8
|
+
:type => 'application/octet-stream'.freeze,
|
9
|
+
:disposition => 'attachment'.freeze,
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
def initialize(app, options={})
|
13
|
+
@app = app
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env) # :nodoc:
|
18
|
+
if env["REQUEST_METHOD"] == "GET" && captcha_path?(env['PATH_INFO'])
|
19
|
+
request = Rack::Request.new(env)
|
20
|
+
if request.params.present? && request.params['code'].present?
|
21
|
+
make_image(env)
|
22
|
+
else
|
23
|
+
refresh_code(env)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
@app.call(env)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
def make_image(env, headers = {}, status = 404)
|
32
|
+
request = Rack::Request.new(env)
|
33
|
+
code = request.params["code"]
|
34
|
+
body = []
|
35
|
+
|
36
|
+
if Utils::simple_captcha_value(code)
|
37
|
+
#status, headers, body = @app.call(env)
|
38
|
+
#status = 200
|
39
|
+
#body = generate_simple_captcha_image(code)
|
40
|
+
#headers['Content-Type'] = 'image/jpeg'
|
41
|
+
|
42
|
+
send_data(generate_simple_captcha_image(code), :type => 'image/jpeg', :disposition => 'inline', :filename => 'simple_captcha.jpg')
|
43
|
+
else
|
44
|
+
[status, headers, body]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def captcha_path?(request_path)
|
49
|
+
request_path.include?('/simple_captcha')
|
50
|
+
end
|
51
|
+
|
52
|
+
def send_file(path, options = {})
|
53
|
+
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
|
54
|
+
|
55
|
+
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
|
56
|
+
|
57
|
+
status = options[:status] || 200
|
58
|
+
headers = {"Content-Disposition" => "#{options[:disposition]}; filename='#{options[:filename]}'", "Content-Type" => options[:type], 'Content-Transfer-Encoding' => 'binary', 'Cache-Control' => 'private'}
|
59
|
+
response_body = File.open(path, "rb")
|
60
|
+
|
61
|
+
[status, headers, response_body]
|
62
|
+
end
|
63
|
+
|
64
|
+
def send_data(response_body, options = {})
|
65
|
+
status = options[:status] || 200
|
66
|
+
headers = {"Content-Disposition" => "#{options[:disposition]}; filename='#{options[:filename]}'", "Content-Type" => options[:type], 'Content-Transfer-Encoding' => 'binary', 'Cache-Control' => 'private'}
|
67
|
+
|
68
|
+
[status, headers, [response_body]]
|
69
|
+
end
|
70
|
+
|
71
|
+
def refresh_code(env)
|
72
|
+
request = Rack::Request.new(env)
|
73
|
+
|
74
|
+
request.session.delete :captcha
|
75
|
+
key = simple_captcha_key(nil, request)
|
76
|
+
options = {}
|
77
|
+
options[:field_value] = set_simple_captcha_data(key, options)
|
78
|
+
url = simple_captcha_image_url(key, options)
|
79
|
+
|
80
|
+
status = 200
|
81
|
+
id = request.params['id']
|
82
|
+
captcha_hidden_field_id = simple_captch_hidden_field_id(id)
|
83
|
+
|
84
|
+
body = %Q{
|
85
|
+
$("##{id}").attr('src', '#{url}');
|
86
|
+
$("##{ captcha_hidden_field_id }").attr('value', '#{key}');
|
87
|
+
}
|
88
|
+
headers = {'Content-Type' => 'text/javascript; charset=utf-8', "Content-Disposition" => "inline; filename='captcha.js'", "Content-Length" => body.length.to_s}.merge(SimpleCaptcha.extra_response_headers)
|
89
|
+
[status, headers, [body]]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module SimpleCaptcha #:nodoc
|
2
|
+
module ModelHelpers #:nodoc
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(SingletonMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
# To implement model based simple captcha use this method in the model as...
|
8
|
+
#
|
9
|
+
# class User < ActiveRecord::Base
|
10
|
+
#
|
11
|
+
# apply_simple_captcha :message => "my customized message"
|
12
|
+
#
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Customize the error message by using :message, the default message is "Captcha did not match".
|
16
|
+
# As in the applications captcha is needed with a very few cases like signing up the new user, but
|
17
|
+
# not every time you need to authenticate the captcha with @user.save. So as to maintain simplicity
|
18
|
+
# here we have the explicit method to save the instace with captcha validation as...
|
19
|
+
#
|
20
|
+
# * to validate the instance
|
21
|
+
#
|
22
|
+
# @user.valid_with_captcha? # whene captcha validation is required.
|
23
|
+
#
|
24
|
+
# @user.valid? # when captcha validation is not required.
|
25
|
+
#
|
26
|
+
# * to save the instance
|
27
|
+
#
|
28
|
+
# @user.save_with_captcha # whene captcha validation is required.
|
29
|
+
#
|
30
|
+
# @user.save # when captcha validation is not required.
|
31
|
+
module SingletonMethods
|
32
|
+
def apply_simple_captcha(options = {})
|
33
|
+
options = { :add_to_base => false }.merge(options)
|
34
|
+
|
35
|
+
class_attribute :simple_captcha_options
|
36
|
+
self.simple_captcha_options = options
|
37
|
+
|
38
|
+
unless self.is_a?(ClassMethods)
|
39
|
+
include InstanceMethods
|
40
|
+
extend ClassMethods
|
41
|
+
|
42
|
+
attr_accessor :captcha, :captcha_key
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module ClassMethods
|
48
|
+
end
|
49
|
+
|
50
|
+
module InstanceMethods
|
51
|
+
|
52
|
+
def valid_with_captcha?
|
53
|
+
[valid?, is_captcha_valid?].all?
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_captcha_valid?
|
57
|
+
return true if SimpleCaptcha.always_pass
|
58
|
+
|
59
|
+
if captcha && captcha.upcase.delete(" ") == SimpleCaptcha::Utils::simple_captcha_value(captcha_key)
|
60
|
+
SimpleCaptcha::Utils::simple_captcha_passed!(captcha_key)
|
61
|
+
return true
|
62
|
+
else
|
63
|
+
message = simple_captcha_options[:message] || I18n.t(self.class.model_name.to_s.downcase, :scope => [:simple_captcha, :message], :default => :default)
|
64
|
+
simple_captcha_options[:add_to_base] ? errors.add(:base, message) : errors.add(:captcha, message)
|
65
|
+
return false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def save_with_captcha
|
70
|
+
valid_with_captcha? && save(:validate => false)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SimpleCaptcha
|
2
|
+
class SimpleCaptchaData < ::ActiveRecord::Base
|
3
|
+
|
4
|
+
if ::ActiveRecord::VERSION::MAJOR >= 3
|
5
|
+
# Fixes deprecation warning in Rails 3.2:
|
6
|
+
# DEPRECATION WARNING: Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.
|
7
|
+
self.table_name = SimpleCaptcha.table_name #"simple_captcha_data"
|
8
|
+
else
|
9
|
+
set_table_name SimpleCaptcha.table_name #"simple_captcha_data"
|
10
|
+
end
|
11
|
+
if ::ActiveRecord::VERSION::MAJOR == 3 and defined? attr_protected
|
12
|
+
attr_protected
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def get_data(key)
|
18
|
+
where(key: key).first_or_initialize
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove_data(key)
|
22
|
+
delete_all(["#{connection.quote_column_name(:key)} = ?", key])
|
23
|
+
clear_old_data(1.hour.ago)
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear_old_data(time = 1.hour.ago)
|
27
|
+
return unless Time === time
|
28
|
+
delete_all(["#{connection.quote_column_name(:updated_at)} < ?", time])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SimpleCaptcha
|
2
|
+
class SimpleCaptchaData
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
|
6
|
+
field :key, type: String
|
7
|
+
field :value, type: String
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def get_data(key)
|
11
|
+
data = where(:key => key).first || new(:key => key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove_data(key)
|
15
|
+
where(:key => key).delete_all
|
16
|
+
clear_old_data(1.hour.ago)
|
17
|
+
end
|
18
|
+
|
19
|
+
def clear_old_data(time = 1.hour.ago)
|
20
|
+
return unless Time === time
|
21
|
+
where(:updated_at.lte => time).delete_all
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module SimpleCaptcha #:nodoc
|
4
|
+
module Utils #:nodoc
|
5
|
+
# Execute command with params and return output if exit status equal expected_outcodes
|
6
|
+
def self.run(cmd, params = "", expected_outcodes = 0)
|
7
|
+
command = %Q[#{cmd} #{params}].gsub(/\s+/, " ")
|
8
|
+
command = "#{command} 2>&1"
|
9
|
+
|
10
|
+
unless (image_magick_path = SimpleCaptcha.image_magick_path).blank?
|
11
|
+
command = File.join(image_magick_path, command)
|
12
|
+
end
|
13
|
+
|
14
|
+
output = `#{command}`
|
15
|
+
|
16
|
+
unless [expected_outcodes].flatten.include?($?.exitstatus)
|
17
|
+
raise ::StandardError, "Error while running #{cmd}: #{output}"
|
18
|
+
end
|
19
|
+
|
20
|
+
output
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.simple_captcha_value(key) #:nodoc
|
24
|
+
SimpleCaptchaData.get_data(key).value rescue nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.simple_captcha_passed!(key) #:nodoc
|
28
|
+
SimpleCaptchaData.remove_data(key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.generate_key(*args)
|
32
|
+
args << (Time.now.to_f * 1_000_000_000).to_s
|
33
|
+
Digest::SHA1.hexdigest(args.join)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module SimpleCaptcha #:nodoc
|
2
|
+
module ViewHelper #:nodoc
|
3
|
+
|
4
|
+
# Simple Captcha is a very simplified captcha.
|
5
|
+
#
|
6
|
+
# It can be used as a *Model* or a *Controller* based Captcha depending on what options
|
7
|
+
# we are passing to the method show_simple_captcha.
|
8
|
+
#
|
9
|
+
# *show_simple_captcha* method will return the image, the label and the text box.
|
10
|
+
# This method should be called from the view within your form as...
|
11
|
+
#
|
12
|
+
# <%= show_simple_captcha %>
|
13
|
+
#
|
14
|
+
# The available options to pass to this method are
|
15
|
+
# * label
|
16
|
+
# * object
|
17
|
+
#
|
18
|
+
# <b>Label:</b>
|
19
|
+
#
|
20
|
+
# default label is "type the text from the image", it can be modified by passing :label as
|
21
|
+
#
|
22
|
+
# <%= show_simple_captcha(:label => "new captcha label") %>.
|
23
|
+
#
|
24
|
+
# *Object*
|
25
|
+
#
|
26
|
+
# This option is needed to create a model based captcha.
|
27
|
+
# If this option is not provided, the captcha will be controller based and
|
28
|
+
# should be checked in controller's action just by calling the method simple_captcha_valid?
|
29
|
+
#
|
30
|
+
# To make a model based captcha give this option as...
|
31
|
+
#
|
32
|
+
# <%= show_simple_captcha(:object => "user") %>
|
33
|
+
# and also call the method apply_simple_captcha in the model
|
34
|
+
# this will consider "user" as the object of the model class.
|
35
|
+
#
|
36
|
+
# *Examples*
|
37
|
+
# * controller based
|
38
|
+
# <%= show_simple_captcha(:label => "Human Authentication: type the text from image above") %>
|
39
|
+
# * model based
|
40
|
+
# <%= show_simple_captcha(:object => "person", :label => "Human Authentication: type the text from image above") %>
|
41
|
+
#
|
42
|
+
# Find more detailed examples with sample images here on my blog http://EXPRESSICA.com
|
43
|
+
#
|
44
|
+
# All Feedbacks/CommentS/Issues/Queries are welcome.
|
45
|
+
def show_simple_captcha(options = {})
|
46
|
+
render :partial => SimpleCaptcha.partial_path, :locals => { :simple_captcha_options => simple_captcha_options(options) }
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def simple_captcha_options(options = {})
|
51
|
+
key = simple_captcha_key(options[:object])
|
52
|
+
if options[:multiple] === false
|
53
|
+
# It's not the first captcha, we only need to return the key
|
54
|
+
options[:field_value] = key
|
55
|
+
else
|
56
|
+
# It's the first captcha in the page, we generate a new key
|
57
|
+
options[:field_value] = set_simple_captcha_data(key, options)
|
58
|
+
end
|
59
|
+
|
60
|
+
defaults = {
|
61
|
+
:image => simple_captcha_image(key, options),
|
62
|
+
:label => I18n.t('simple_captcha.label'),
|
63
|
+
:field => simple_captcha_field(options),
|
64
|
+
:refresh_button => simple_captcha_refresh_button(options),
|
65
|
+
}.merge(options)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def simple_captcha_image(simple_captcha_key, options = {})
|
71
|
+
url = simple_captcha_image_url simple_captcha_key, options: options
|
72
|
+
id = simple_captcha_image_id(options)
|
73
|
+
tag('img', :src => url, :alt => 'captcha', :id => id)
|
74
|
+
end
|
75
|
+
|
76
|
+
def simple_captcha_image_url(simple_captcha_key, options = {})
|
77
|
+
defaults = {}
|
78
|
+
defaults[:time] = options[:time] || Time.now.to_i
|
79
|
+
|
80
|
+
query = defaults.to_query
|
81
|
+
path = "/simple_captcha?code=#{simple_captcha_key}&#{query}"
|
82
|
+
build_url(options, path)
|
83
|
+
end
|
84
|
+
|
85
|
+
def build_url(options, path)
|
86
|
+
if defined?(request) && request
|
87
|
+
"#{request.protocol}#{request.host_with_port}#{ENV['RAILS_RELATIVE_URL_ROOT']}#{path}"
|
88
|
+
else
|
89
|
+
"#{ENV['RAILS_RELATIVE_URL_ROOT']}#{path}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def simple_captcha_field(options={})
|
94
|
+
html = {:autocomplete => 'off', :autocorrect => 'off', :autocapitalize => 'off', :required => 'required'}
|
95
|
+
html.merge!(options[:input_html] || {})
|
96
|
+
html[:placeholder] = options[:placeholder] || I18n.t('simple_captcha.placeholder')
|
97
|
+
|
98
|
+
if options[:object]
|
99
|
+
text_field(options[:object], :captcha, html.merge(:value => '')) +
|
100
|
+
hidden_field(options[:object], :captcha_key, {:value => options[:field_value], :id => simple_captch_hidden_field_id(options)})
|
101
|
+
else
|
102
|
+
text_field_tag(:captcha, nil, html) +
|
103
|
+
hidden_field_tag(:captcha_key, options[:field_value], :id => simple_captch_hidden_field_id(options))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def simple_captcha_refresh_button(options={})
|
108
|
+
html = {remote: true}
|
109
|
+
html.merge!(options[:refresh_button_html] || {})
|
110
|
+
|
111
|
+
text = options[:refresh_button_text] || I18n.t('simple_captcha.refresh_button_text', default: 'Refresh')
|
112
|
+
|
113
|
+
url = build_url(options, "/simple_captcha?id=#{simple_captcha_image_id(options)}")
|
114
|
+
link_to(text, url, html)
|
115
|
+
end
|
116
|
+
|
117
|
+
def simple_captcha_image_id(options={})
|
118
|
+
"simple_captcha-#{options[:field_value][0..10]}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def simple_captch_hidden_field_id(image_id)
|
122
|
+
image_id = simple_captcha_image_id(image_id) if image_id.is_a?(Hash)
|
123
|
+
"simple-captcha-hidden-field-#{ image_id }"
|
124
|
+
end
|
125
|
+
|
126
|
+
def set_simple_captcha_data(key, options={})
|
127
|
+
code_type = options[:code_type]
|
128
|
+
|
129
|
+
value = generate_simple_captcha_data(code_type)
|
130
|
+
data = SimpleCaptcha::SimpleCaptchaData.get_data(key)
|
131
|
+
data.value = value
|
132
|
+
data.save
|
133
|
+
key
|
134
|
+
end
|
135
|
+
|
136
|
+
def generate_simple_captcha_data(code)
|
137
|
+
value = ''
|
138
|
+
|
139
|
+
case code
|
140
|
+
when 'numeric' then
|
141
|
+
SimpleCaptcha.length.times{value << (48 + rand(10)).chr}
|
142
|
+
else
|
143
|
+
SimpleCaptcha.length.times{value << (65 + rand(26)).chr}
|
144
|
+
end
|
145
|
+
|
146
|
+
return value
|
147
|
+
end
|
148
|
+
|
149
|
+
def simple_captcha_key(key_name = nil, prequest = request)
|
150
|
+
local_session = prequest.try(:session) || session
|
151
|
+
if key_name.nil?
|
152
|
+
local_session[:captcha] ||= SimpleCaptcha::Utils.generate_key(local_session[:id].to_s, 'captcha')
|
153
|
+
else
|
154
|
+
SimpleCaptcha::Utils.generate_key(local_session[:id].to_s, key_name)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SimpleCaptcha
|
4
|
+
class << self
|
5
|
+
attr_accessor :always_pass
|
6
|
+
end
|
7
|
+
self.always_pass = Rails.env.test?
|
8
|
+
autoload :Utils, 'simple_captcha/utils'
|
9
|
+
|
10
|
+
autoload :ImageHelpers, 'simple_captcha/image'
|
11
|
+
autoload :ViewHelper, 'simple_captcha/view'
|
12
|
+
autoload :ControllerHelpers, 'simple_captcha/controller'
|
13
|
+
|
14
|
+
autoload :FormBuilder, 'simple_captcha/form_builder'
|
15
|
+
autoload :CustomFormBuilder, 'simple_captcha/formtastic'
|
16
|
+
|
17
|
+
autoload :ModelHelpers, 'simple_captcha/model_helpers'
|
18
|
+
|
19
|
+
if defined?(ActiveRecord)
|
20
|
+
autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data'
|
21
|
+
else
|
22
|
+
autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data_mongoid.rb'
|
23
|
+
end
|
24
|
+
|
25
|
+
autoload :Middleware, 'simple_captcha/middleware'
|
26
|
+
|
27
|
+
mattr_accessor :image_size
|
28
|
+
@@image_size = "100x28"
|
29
|
+
|
30
|
+
mattr_accessor :length
|
31
|
+
@@length = 5
|
32
|
+
|
33
|
+
mattr_accessor :table_name
|
34
|
+
@@table_name = "simple_captcha_data"
|
35
|
+
|
36
|
+
# 'embosed_silver',
|
37
|
+
# 'simply_red',
|
38
|
+
# 'simply_green',
|
39
|
+
# 'simply_blue',
|
40
|
+
# 'distorted_black',
|
41
|
+
# 'all_black',
|
42
|
+
# 'charcoal_grey',
|
43
|
+
# 'almost_invisible'
|
44
|
+
# 'random'
|
45
|
+
mattr_accessor :image_style
|
46
|
+
@@image_style = 'simply_blue'
|
47
|
+
|
48
|
+
# 'low', 'medium', 'high', 'random'
|
49
|
+
mattr_accessor :distortion
|
50
|
+
@@distortion = 'low'
|
51
|
+
|
52
|
+
# 'none', 'low', 'medium', 'high'
|
53
|
+
mattr_accessor :implode
|
54
|
+
@@implode = SimpleCaptcha::ImageHelpers::DEFAULT_IMPLODE
|
55
|
+
|
56
|
+
# command path
|
57
|
+
mattr_accessor :image_magick_path
|
58
|
+
@@image_magick_path = ''
|
59
|
+
|
60
|
+
# tmp directory
|
61
|
+
mattr_accessor :tmp_path
|
62
|
+
@@tmp_path = nil
|
63
|
+
|
64
|
+
# additive noise
|
65
|
+
mattr_accessor :noise
|
66
|
+
@@noise = 0
|
67
|
+
|
68
|
+
mattr_accessor :extra_response_headers
|
69
|
+
@@extra_response_headers = {}
|
70
|
+
|
71
|
+
mattr_accessor :partial_path
|
72
|
+
@@partial_path = 'simple_captcha/simple_captcha'
|
73
|
+
|
74
|
+
def self.add_image_style(name, params = [])
|
75
|
+
SimpleCaptcha::ImageHelpers.image_styles.update(name.to_s => params)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.setup
|
79
|
+
yield self
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
require 'simple_captcha/engine' if defined?(Rails)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'simple_captcha'
|