quick_captcha 3.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.
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2008 [Sur http://expressica.com]
2
+ Copyright (c) 2010 [kares <http://log.kares.org>]
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,280 @@
1
+
2
+ This code is a fork <http://github.com/kares/simple_captcha>
3
+
4
+ Main Updates
5
+ ------------
6
+
7
+ - Renamed (mostly) to QuickMagick
8
+ - Upgraded to engine running under Rails 3.2
9
+ - Removed support for RMagick
10
+ - Removed support for Rails 2
11
+ - Attempted to maintain backwards compatibility
12
+
13
+
14
+ Other Updates
15
+ -------------
16
+
17
+ The original version does all kinds of method aliasing and requires you
18
+ to write code specifically for handling the captcha validation. This version
19
+ accepts the usual :if, :unless and :on options.
20
+
21
+ This version does not bypass the validation if in test mode. It behaves the
22
+ same in all environments, allowing you to actually test it.
23
+
24
+ To disable the validations in test mode, You should now state it explicitly:
25
+
26
+ class User < ActiveRecord::Base
27
+ validates_captcha :unless => lambda { Rails.env.test? }
28
+ end
29
+
30
+ NOTE: This will validate captcha every-time You do a `user.save` !
31
+
32
+ There's an API that allows You to (temporary) disable captcha validation for
33
+ classes, individual instances or even blocks :
34
+
35
+ User.captcha_validation = false # disables validation globally
36
+ user = User.new
37
+ ...
38
+ # force captcha validation for the given instance and block
39
+ user.captcha_validation(true) do
40
+ user.save!
41
+ end
42
+ ...
43
+ # enable captcha validation for the given instance
44
+ user.captcha_validation(true)
45
+ user.save
46
+ ...
47
+ # reset captcha validation - fallback to the class setting
48
+ user.captcha_validation(nil)
49
+ user.save # validates captcha if User.captcha_validation?
50
+
51
+
52
+ Old Validation
53
+ --------------
54
+
55
+ A backward compatible validation for Your model classes is as well available.
56
+ The original captcha validation code was different from standard validation in
57
+ a way that it did not validate the captcha on "regular" `save` calls, one has
58
+ to explicitly state captcha validation is desired by calling `save_with_captcha`.
59
+
60
+ class User < ActiveRecord::Base
61
+ apply_simple_captcha :message => 'WTF?!'
62
+ end
63
+
64
+ NOTE: The "old" behavior is emulated using the captcha_validation flags.
65
+
66
+ QuickCaptcha
67
+ =============
68
+
69
+ QuickCaptcha is the simplest and a robust captcha plugin. Its implementation
70
+ requires adding up a single line in views and in controllers/models.
71
+
72
+ ### Features
73
+
74
+ - Zero FileSystem usage(secret code moved to db-store and image storage removed).
75
+ - Provides various image styles.
76
+ - Provides three level of complexity of images.
77
+ - Works absolutely fine in distributed environment(session and db based implementation
78
+ works fine in distributed environment).
79
+ - Implementation is as easy as just writing a single line in your view.
80
+ `<%= show_quick_captcha %>` within the 'form' tags.
81
+ - Flexible DOM and CSS handling(There is a separate view partial for rendering
82
+ QuickCaptcha DOM elements).
83
+ - Automated removal of 1 hour old unmatched simple_captcha data.
84
+
85
+ ### Pre-Requisite
86
+
87
+ [quick_magick](https://rubyforge.org/projects/quickmagick) should be installed on your machine to use this plugin.
88
+
89
+
90
+ ### Installation
91
+
92
+ gem install quick_captcha
93
+ add gem 'quick_captcha' to Gemfile
94
+
95
+ ### Setup
96
+
97
+ After installation, follow these simple steps to setup the plugin.
98
+ The setup will depend on the version of rails your application is using.
99
+
100
+ #### STEP 1
101
+
102
+ for Rails 3.x :
103
+
104
+ rails generate quick_captcha
105
+
106
+ #### STEP 2
107
+
108
+ rake db:migrate
109
+
110
+ #### STEP 4 (Optional)
111
+
112
+ configure quick_captcha e.g. in `app/config/initializers/quick_captcha.rb`
113
+
114
+ QuickCaptcha.backend = :quick_magick
115
+
116
+ QuickCaptcha.image_options = {
117
+ :image_color => 'white',
118
+ :image_size => '110x30',
119
+ :text_color => 'black',
120
+ :text_font => 'arial',
121
+ :text_size => 22
122
+ } # these are the defaults
123
+
124
+ Please note that some image options such as color might change when using
125
+ some of the pre-built captcha image styles available.
126
+
127
+
128
+ ### Usage
129
+
130
+ #### Controller Based
131
+
132
+ Include `QuickCaptcha::ControllerValidation` into Your captcha validating
133
+ controller or put the include into `app/controllers/application.rb`
134
+
135
+ ApplicationController < ActionController::Base
136
+ include QuickCaptcha::ControllerValidation
137
+ end
138
+
139
+ in the view file within the form tags add this code
140
+
141
+ <%= show_quick_captcha %> or <%= show_simple_captcha %>
142
+
143
+ and in the controller's action authenticate it as
144
+
145
+ if quick_captcha_valid?
146
+ do this
147
+ else
148
+ do that
149
+ end
150
+
151
+
152
+ #### Model Based
153
+
154
+ In the view file within the form tags write this code
155
+
156
+ <%= show_quick_captcha(:object=>"user") %>
157
+
158
+ and in the model class include `QuickCaptcha::ModelValidation` and setup
159
+ the validation
160
+
161
+ class User < ActiveRecord::Base
162
+ include QuickCaptcha::ModelValidation
163
+
164
+ validates_captcha :on => :create, :message => 'invalid captcha'
165
+ end
166
+
167
+ or if You prefer the old version which doesn't trigger the captcha
168
+ validation on `save` (one have to call `save_with_captcha`)
169
+
170
+ class User < ActiveRecord::Base
171
+ include QuickCaptcha::ModelValidation
172
+
173
+ apply_quick_captcha :message => :'invalid_captcha'
174
+ end
175
+
176
+
177
+ Options & Examples
178
+ ------------------
179
+
180
+ View Options
181
+ ==========================================================================
182
+
183
+ :label
184
+ --------------------------------------------------------------------------
185
+ provides the custom text b/w the image and the text field,
186
+ the default is "type the code from the image"
187
+
188
+ :image_style
189
+ --------------------------------------------------------------------------
190
+ Provides the specific image style for the captcha image.
191
+ There are eight different styles available with the plugin as...
192
+ 1) simply_blue
193
+ 2) simply_red
194
+ 3) simply_green
195
+ 4) charcoal_grey
196
+ 5) embosed_silver
197
+ 6) all_black
198
+ 7) distorted_black
199
+ 8) almost_invisible
200
+
201
+ See the included samples <http://github.com/kares/simple_captcha/samples>.
202
+ You can also specify 'random' to select the random image style.
203
+
204
+
205
+ :distortion
206
+ --------------------------------------------------------------------------
207
+ Handles the complexity of the image. The :distortion can be set to 'low',
208
+ 'medium' or 'high'. Default is 'low'.
209
+
210
+ :object
211
+ --------------------------------------------------------------------------
212
+ the name of the object of the model class, to implement the model based
213
+ captcha.
214
+
215
+
216
+ How to change the CSS for QuickCaptcha DOM elements ?
217
+ -----------------------------------------------------
218
+ You can change the CSS of the QuickCaptcha DOM elements as per your need
219
+ in this file.
220
+ "/app/views/quick_captcha/_quick_captcha.erb"
221
+
222
+
223
+ View's Examples
224
+ ==========================================================================
225
+
226
+ Controller Based Example
227
+ --------------------------------------------------------------------------
228
+ example
229
+ -------
230
+ <%= show_quick_captcha(:label => "human authentication") %>
231
+
232
+ example
233
+ -------
234
+ <%= show_quick_captcha(:label => "human authentication",
235
+ :image_style => 'embosed_silver') %>
236
+
237
+ example
238
+ -------
239
+ <%= show_quick_captcha(:label => "human authentication",
240
+ :image_style => 'simply_red',
241
+ :distortion => 'medium') %>
242
+
243
+ Model Based Example
244
+ --------------------------------------------------------------------------
245
+
246
+ example
247
+ -------
248
+ <%= show_quick_captcha(:object => 'user',
249
+ :label => "human authentication") %>
250
+
251
+
252
+
253
+ Model Options
254
+ ==========================================================================
255
+
256
+ :message
257
+ --------------------------------------------------------------------------
258
+ provides the custom message on failure of captcha authentication
259
+ the default is "Secret Code did not match with the Image"
260
+
261
+ :add_to_base
262
+ --------------------------------------------------------------------------
263
+ if set to true, appends the error message to the base.
264
+
265
+ Model's Example
266
+ ==========================================================================
267
+
268
+ example
269
+ -------
270
+ class User < ActiveRecord::Base
271
+ apply_quick_captcha # the "old" way using save_with_captcha
272
+ end
273
+
274
+ example
275
+ -------
276
+ class User < ActiveRecord::Base
277
+ validates_captcha :message => "Are you a bot?", :add_to_base => true
278
+ end
279
+
280
+ ==========================================================================
@@ -0,0 +1,59 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the quick_captcha plugin.'
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc 'Generate documentation for the quick_captcha plugin.'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'QuickCaptcha'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ desc 'Generate captcha image samples.'
27
+ task :generate_samples do
28
+
29
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
30
+
31
+ require 'action_view'
32
+ require 'active_record'
33
+ require 'quick_captcha'
34
+ # prefer quick_magick (works with JRuby) :
35
+ begin
36
+ require 'quick_magick'
37
+ require 'quick_captcha/quick_magick_backend'
38
+ QuickCaptcha.backend = :quick_magick
39
+ rescue
40
+ raise "could not find quick_magick"
41
+ end
42
+
43
+ include QuickCaptcha::ViewHelpers
44
+ include QuickCaptcha::ImageHelpers
45
+
46
+ def self.simple_captcha_value(key) # stub
47
+ generate_simple_captcha_data
48
+ end
49
+
50
+ samples_dir = File.join(File.dirname(__FILE__), 'samples')
51
+ image_styles = QuickCaptcha::ImageHelpers::IMAGE_STYLES
52
+
53
+ (image_styles + [ nil ]).each do |image_style|
54
+ simple_captcha_img = generate_simple_captcha_image(:image_style => image_style)
55
+ filename = File.join(samples_dir, (image_style || 'default') + '.jpg')
56
+ File.open(filename, "wb") { |file| file << simple_captcha_img }
57
+ end
58
+
59
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ class QuickCaptchaController < ActionController::Base
4
+ include QuickCaptcha::ImageHelpers
5
+
6
+ def show #:nodoc
7
+ simple_captcha_key = params[:simple_captcha_key] || params[:captcha_key]
8
+ raise ":simple_captcha_key parameter missing" unless simple_captcha_key
9
+ send_data(
10
+ generate_simple_captcha_image(
11
+ :image_style => params[:image_style],
12
+ :distortion => params[:distortion],
13
+ :simple_captcha_key => simple_captcha_key),
14
+ :type => 'image/jpeg',
15
+ :disposition => 'inline',
16
+ :filename => 'simple_captcha.jpg')
17
+ end
18
+ alias_method :simple_captcha, :show # backward compatibility
19
+
20
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ class SimpleCaptchaData < ActiveRecord::Base
4
+ self.table_name = "simple_captcha_data"
5
+
6
+ class << self
7
+ def get_data(key)
8
+ find_by_key(key) || new(:key => key)
9
+ end
10
+
11
+ def remove_data(key)
12
+ clear_old_data
13
+ data = find_by_key(key)
14
+ data.destroy if data
15
+ end
16
+
17
+ def clear_old_data(time = 1.hour.ago)
18
+ return unless Time === time
19
+ destroy_all("updated_at < '#{time.to_s(:db)}'")
20
+ end
21
+ end
22
+
23
+ end
@@ -0,0 +1,39 @@
1
+ <!-- Copyright (c) 2007 [Sur http://expressica.com] -->
2
+
3
+ <style type="text/CSS">
4
+ #simple_captcha { border: 1px solid #ccc; padding: 5px !important; }
5
+ #simple_captcha,
6
+ #simple_captcha div { display: table; }
7
+ #simple_captcha .simple_captcha_field,
8
+ #simple_captcha .simple_captcha_image {
9
+ border: 1px solid #ccc;
10
+ margin: 0px 0px 2px 0px !important;
11
+ padding: 0px !important;
12
+ }
13
+ #simple_captcha .simple_captcha_image img {
14
+ margin: 0px !important;
15
+ padding: 0px !important;
16
+ width: 110px !important;
17
+ }
18
+ #simple_captcha .simple_captcha_label { font-size: 12px; }
19
+ #simple_captcha .simple_captcha_field input {
20
+ width: 150px !important;
21
+ font-size: 16px;
22
+ border: none;
23
+ background-color: #efefef;
24
+ }
25
+ </style>
26
+
27
+ <div id='simple_captcha'>
28
+ <div class='simple_captcha_image'>
29
+ <%= @simple_captcha_options[:image] %>
30
+ </div>
31
+
32
+ <div class='simple_captcha_field'>
33
+ <%= @simple_captcha_options[:field] %>
34
+ </div>
35
+
36
+ <div class='simple_captcha_label'>
37
+ <%= @simple_captcha_options[:label] %>
38
+ </div>
39
+ </div>
@@ -0,0 +1,7 @@
1
+ # QuickCaptcha Configuration
2
+ #
3
+ # put this in an initializer: config/initializers/quick_captcha.rb
4
+ #
5
+ # more info at http://github.com/portablemind/quick_captcha
6
+ #
7
+ QuickCaptcha.backend = :quick_magick
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+ match '/simple_captcha/:action', :to => 'quick_captcha', :as => :simple_captcha
3
+ match '/quick_captcha/:action', :to => 'quick_captcha', :as => :quick_captcha
4
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails/generators'
2
+
3
+ class QuickCaptchaGenerator < Rails::Generators::Base
4
+ include Rails::Generators::Migration
5
+
6
+ def self.source_root
7
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
8
+ end
9
+
10
+ def self.next_migration_number(dirname)
11
+ Time.now.strftime("%Y%m%d%H%M%S")
12
+ end
13
+
14
+ def create_migration
15
+ migration_template "migration.rb", File.join('db/migrate', "create_simple_captcha_data.rb")
16
+ end
17
+
18
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSimpleCaptchaData < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :simple_captcha_data do |t|
4
+ t.string :key, :limit => 40
5
+ t.string :value, :limit => 20
6
+ t.timestamps
7
+ end
8
+ add_index :simple_captcha_data, :key
9
+ end
10
+
11
+ def self.down
12
+ drop_table :simple_captcha_data
13
+ end
14
+ end
@@ -0,0 +1,69 @@
1
+ require "quick_captcha/version"
2
+ require "quick_captcha/engine"
3
+
4
+ require 'quick_captcha/captcha_utils'
5
+ require 'quick_captcha/image_helpers'
6
+ require 'quick_captcha/view_helpers'
7
+ require 'quick_captcha/quick_magick_backend'
8
+ require 'quick_captcha/controller_validation'
9
+ require 'quick_captcha/model_validation'
10
+
11
+
12
+ #ActiveRecord::Base.extend QuickCaptcha::ModelHelpers::ClassMethods
13
+ ActionView::Base.send :include, QuickCaptcha::ViewHelpers
14
+
15
+ module QuickCaptcha
16
+
17
+ @@image_options = {
18
+ :image_color => 'white',
19
+ :image_size => '110x30',
20
+ :text_color => 'black',
21
+ :text_font => 'arial',
22
+ :text_size => 22
23
+ }
24
+ def self.image_options
25
+ @@image_options
26
+ end
27
+
28
+ def self.image_options=(options)
29
+ @@image_options.merge! options
30
+ end
31
+
32
+ @@captcha_length = nil
33
+ def self.captcha_length
34
+ @@captcha_length ||= 6
35
+ end
36
+
37
+ def self.captcha_length=(length)
38
+ if length
39
+ raise "invalid captcha length < 0 : #{length}" if length <= 0
40
+ raise "invalid captcha length > 20 : #{length}" if length > 20
41
+ end
42
+ @@captcha_length = length
43
+ end
44
+
45
+ @@backend = nil
46
+ def self.backend
47
+ self.backend = :quick_magick unless @@backend
48
+ @@backend
49
+ end
50
+
51
+ def self.backend=(backend)
52
+ if backend.nil?
53
+ return @@backend = nil
54
+ end
55
+ if backend.is_a?(Symbol) || backend.is_a?(String)
56
+ backend = backend.to_s.camelize
57
+ backend_const = const_get(backend + 'Backend') rescue nil
58
+ backend_const = const_get(backend) rescue nil unless backend_const
59
+ raise "unsupported backend: #{backend}" unless backend_const
60
+ else
61
+ backend_const = backend
62
+ end
63
+ unless backend_const.respond_to?(:generate_simple_captcha_image)
64
+ raise "invalid backend: #{backend_const} - does not respond to :generate_simple_captcha_image"
65
+ end
66
+ @@backend = backend_const
67
+ end
68
+
69
+ end
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ require 'digest/sha1'
4
+
5
+ module QuickCaptcha #:nodoc
6
+ module CaptchaUtils
7
+
8
+ def self.simple_captcha_value(key)
9
+ SimpleCaptchaData.get_data(key).value rescue nil
10
+ end
11
+
12
+ def self.simple_captcha_matches?(captcha, key)
13
+ captcha && captcha.delete(" ").upcase == simple_captcha_value(key)
14
+ end
15
+
16
+ def self.simple_captcha_passed!(key)
17
+ SimpleCaptchaData.remove_data(key)
18
+ end
19
+
20
+ def simple_captcha_value
21
+ QuickCaptcha::CaptchaUtils.simple_captcha_value(simple_captcha_key)
22
+ end
23
+
24
+ def simple_captcha_matches?(captcha)
25
+ QuickCaptcha::CaptchaUtils.simple_captcha_matches?(captcha, simple_captcha_key)
26
+ end
27
+
28
+ def simple_captcha_passed!
29
+ QuickCaptcha::CaptchaUtils.simple_captcha_passed!(simple_captcha_key).tap do
30
+ session[:simple_captcha] = nil
31
+ end
32
+ end
33
+
34
+ def simple_captcha_key
35
+ session[:simple_captcha] ||= generate_simple_captcha_key
36
+ end
37
+
38
+ def generate_simple_captcha_key
39
+ session_id = session[:id] ||
40
+ request.respond_to?(:session_options) ?
41
+ request.session_options[:id] : session.session_id
42
+ Digest::SHA1.hexdigest(Time.now.to_s + session_id.to_s)
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ module QuickCaptcha #:nodoc
4
+ module ControllerValidation #:nodoc
5
+
6
+ include QuickCaptcha::CaptchaUtils
7
+
8
+ # This method is to validate the simple captcha in controller.
9
+ # It means when the captcha is controller based i.e. :object has not been passed to the method show_simple_captcha.
10
+ #
11
+ # *Example*
12
+ #
13
+ # If you want to save an object say @user only if the captcha is validated then do like this in action...
14
+ #
15
+ # if simple_captcha_valid?
16
+ # @user.save
17
+ # else
18
+ # flash[:notice] = "captcha did not match"
19
+ # redirect_to :action => "myaction"
20
+ # end
21
+ def quick_captcha_valid?
22
+ simple_captcha_valid?
23
+ end
24
+
25
+ def simple_captcha_valid?
26
+ if captcha = params[:captcha]
27
+ result = simple_captcha_matches?(captcha)
28
+ simple_captcha_passed! if result
29
+ result
30
+ else
31
+ false
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module QuickCaptcha
2
+ class Engine < Rails::Engine
3
+ isolate_namespace QuickCaptcha
4
+
5
+ end
6
+ end
@@ -0,0 +1,49 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ module QuickCaptcha #:nodoc
4
+ module ImageHelpers #:nodoc
5
+
6
+ def generate_simple_captcha_image(options = {})
7
+ options = QuickCaptcha.image_options.merge(options)
8
+ key = options.delete(:simple_captcha_key)
9
+ captcha_text = QuickCaptcha::CaptchaUtils.simple_captcha_value(key)
10
+ options[:captcha_text] = captcha_text
11
+ options[:distortion] = distortion(options[:distortion])
12
+ options[:image_style] = image_style(options[:image_style])
13
+ QuickCaptcha.backend.generate_simple_captcha_image(options)
14
+ end
15
+
16
+ IMAGE_STYLES = [
17
+ 'embosed_silver',
18
+ 'simply_red',
19
+ 'simply_green',
20
+ 'simply_blue',
21
+ 'distorted_black',
22
+ 'all_black',
23
+ 'charcoal_grey',
24
+ 'almost_invisible'
25
+ ]
26
+
27
+ private
28
+
29
+ def image_style(key)
30
+ return IMAGE_STYLES[rand(IMAGE_STYLES.length)] if key == 'random'
31
+ IMAGE_STYLES.include?(key) ? key : nil # 'simply_blue'
32
+ end
33
+
34
+ DISTORTIONS = ['low', 'medium', 'high']
35
+
36
+ def distortion(key)
37
+ key = key == 'random' ?
38
+ DISTORTIONS[rand(DISTORTIONS.length)] :
39
+ DISTORTIONS.include?(key) ? key : 'low'
40
+ case key
41
+ when 'low' then return [0 + rand(2), 80 + rand(20)]
42
+ when 'medium' then return [2 + rand(2), 50 + rand(20)]
43
+ when 'high' then return [4 + rand(2), 30 + rand(20)]
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ module QuickCaptcha #:nodoc
4
+ module ModelValidation #:nodoc
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ # To implement model based simple captcha use this method in the model as...
11
+ #
12
+ # class User < ActiveRecord::Base
13
+ # validates_captcha :message => "Are you a bot?"
14
+ # end
15
+ #
16
+ # Configuration options:
17
+ #
18
+ # * :add_to_base - Specifies if error should be added to base or captcha field. defaults to false.
19
+ # * :message - A custom error message (default is: "Secret Code did not match with the Image")
20
+ # * :on - Specifies when this validation is active (default is :save, other options :create, :update)
21
+ # * :if - Specifies a method, proc or string to call to determine if the validation should occur (e.g. :if => :allow_validation, or :if => Proc.new { |user| user.signup_step > 2 }). The method, proc or string should return or evaluate to a true or false value.
22
+ # * :unless - Specifies a method, proc or string to call to determine if the validation should not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The method, proc or string should return or evaluate to a true or false value.
23
+ #
24
+ module ClassMethods
25
+
26
+ def validates_captcha(options = {})
27
+ orig_options = options
28
+ # AR by default looks into the following i18n scope :
29
+ # :'activerecord.errors.messages.record_invalid'
30
+ options = { :message => :captcha }
31
+ options.update(orig_options)
32
+
33
+ attr_accessor :captcha, :captcha_key
34
+ include QuickCaptcha::ModelValidation::InstanceMethods
35
+
36
+ validate =
37
+ case (options[:on] || :save)
38
+ when :save then :validate
39
+ when :create then :validate_on_create
40
+ when :update then :validate_on_update
41
+ end
42
+ send(validate, options) do |record|
43
+ if !record.captcha_validation?
44
+ true
45
+ elsif record.captcha_is_valid?
46
+ true
47
+ elsif options[:add_to_base]
48
+ record.errors.add_to_base(options[:message])
49
+ false
50
+ else
51
+ record.errors.add(:captcha, options[:message])
52
+ false
53
+ end
54
+ end
55
+ end
56
+
57
+ def apply_quick_captcha(options = {})
58
+ apply_simple_captcha(options)
59
+ end
60
+
61
+ def apply_simple_captcha(options = {}) # 4 backward compatibility
62
+ outcome = validates_captcha(options)
63
+ self.captcha_validation = false
64
+ include QuickCaptcha::ModelValidation::SaveWithCaptcha
65
+ outcome
66
+ end
67
+
68
+ def captcha_validation?
69
+ defined?(@_captcha_validation) ? @_captcha_validation : true
70
+ end
71
+
72
+ def captcha_validation=(flag)
73
+ @_captcha_validation = flag
74
+ end
75
+
76
+ end
77
+
78
+ module InstanceMethods
79
+
80
+ def captcha_is_valid?
81
+ QuickCaptcha::CaptchaUtils.simple_captcha_matches?(captcha, captcha_key)
82
+ end
83
+
84
+ def captcha_validation?
85
+ if defined?(@_captcha_validation) && ! @_captcha_validation.nil?
86
+ @_captcha_validation
87
+ else
88
+ self.class.captcha_validation?
89
+ end
90
+ end
91
+
92
+ def captcha_validation(flag = true)
93
+ prev = @_captcha_validation
94
+ @_captcha_validation = flag
95
+ if block_given?
96
+ outcome = yield
97
+ @_captcha_validation = prev
98
+ end
99
+ outcome
100
+ end
101
+
102
+ end
103
+
104
+ module SaveWithCaptcha
105
+
106
+ if defined?(ActiveModel) && ActiveModel::VERSION::MAJOR >= 3
107
+
108
+ def save_with_captcha(options = {})
109
+ options[:validate] = true unless options.has_key?(:validate)
110
+ captcha_validation(true) { save(options) }
111
+ end
112
+
113
+ else
114
+
115
+ def save_with_captcha
116
+ captcha_validation(true) { save }
117
+ end
118
+
119
+ end
120
+ end
121
+
122
+
123
+ end
124
+ end
@@ -0,0 +1,68 @@
1
+
2
+ require 'quick_magick'
3
+
4
+ module QuickCaptcha
5
+
6
+ module QuickMagickBackend
7
+
8
+ def self.generate_simple_captcha_image(options)
9
+ width, height = options[:image_size].split('x')
10
+
11
+ image = QuickMagick::Image::solid(width, height, options[:image_color])
12
+ image.format = 'JPG'
13
+
14
+ image = set_simple_captcha_image_style(image, options)
15
+ image.implode(0.2).to_blob
16
+ end
17
+
18
+ private
19
+
20
+ def self.set_simple_captcha_image_style(image, options)
21
+ amplitude, frequency = options[:distortion]
22
+ case options[:image_style]
23
+ when 'embosed_silver'
24
+ append_simple_captcha_code(image, options)
25
+ image = image.wave(amplitude, frequency).shade('20x60')
26
+ when 'simply_red'
27
+ options[:text_color] = 'darkred'
28
+ append_simple_captcha_code(image, options)
29
+ image = image.wave(amplitude, frequency)
30
+ when 'simply_green'
31
+ options[:text_color] = 'darkgreen'
32
+ append_simple_captcha_code(image, options)
33
+ image = image.wave(amplitude, frequency)
34
+ when 'simply_blue'
35
+ options[:text_color] = 'darkblue'
36
+ append_simple_captcha_code(image, options)
37
+ image = image.wave(amplitude, frequency)
38
+ when 'distorted_black'
39
+ append_simple_captcha_code(image, options)
40
+ image = image.wave(amplitude, frequency).edge(10)
41
+ when 'all_black'
42
+ append_simple_captcha_code(image, options)
43
+ image = image.wave(amplitude, frequency).edge(2)
44
+ when 'charcoal_grey'
45
+ append_simple_captcha_code(image, options)
46
+ image = image.wave(amplitude, frequency).charcoal(0)
47
+ when 'almost_invisible'
48
+ options[:text_color] = 'red'
49
+ append_simple_captcha_code(image, options)
50
+ image = image.wave(amplitude, frequency).solarize(50)
51
+ else
52
+ append_simple_captcha_code(image, options)
53
+ image = image.wave(amplitude, frequency)
54
+ end
55
+ return image
56
+ end
57
+
58
+ def self.append_simple_captcha_code(image, options)
59
+ image.family = options[:text_font]
60
+ image.pointsize = options[:text_size]
61
+ image.fill = options[:text_color]
62
+ image.gravity = 'center'
63
+ image.draw_text 0, 5, options[:captcha_text]
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,10 @@
1
+ module QuickCaptcha
2
+ module VERSION #:nodoc:
3
+ MAJOR = 3
4
+ MINOR = 2
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
8
+ end
9
+ end
10
+
@@ -0,0 +1,132 @@
1
+ # Copyright (c) 2008 [Sur http://expressica.com]
2
+
3
+ module QuickCaptcha #:nodoc
4
+ module ViewHelpers #:nodoc
5
+
6
+ include QuickCaptcha::CaptchaUtils
7
+
8
+ # Simple Captcha is a very simplified captcha.
9
+ #
10
+ # It can be used as a *Model* or a *Controller* based Captcha depending on what options
11
+ # we are passing to the method show_simple_captcha.
12
+ #
13
+ # *show_simple_captcha* method will return the image, the label and the text box.
14
+ # This method should be called from the view within your form as...
15
+ #
16
+ # <%= show_simple_captcha %>
17
+ #
18
+ # The available options to pass to this method are
19
+ # * label
20
+ # * image_syle
21
+ # * object
22
+ # * distortion
23
+ #
24
+ # <b>Label:</b>
25
+ #
26
+ # default label is "type the text from the image", it can be modified by passing :label as
27
+ #
28
+ # <%= show_simple_captcha(:label => "new captcha label") %>.
29
+ #
30
+ # <b>Image Style:</b>
31
+ #
32
+ # There are eight different styles of images available as...
33
+ # * embosed_silver
34
+ # * simply_red
35
+ # * simply_green
36
+ # * simply_blue
37
+ # * distorted_black
38
+ # * all_black
39
+ # * charcoal_grey
40
+ # * almost_invisible
41
+ #
42
+ # The default image is simply_blue and can be modified by passing any of the above style as...
43
+ #
44
+ # <%= show_simple_captcha(:image_style => "simply_red") %>
45
+ #
46
+ # The images can also be selected randomly by using *random* in the image_style as
47
+ #
48
+ # <%= show_simple_captcha(:image_style => "random") %>
49
+ #
50
+ # *Object*
51
+ #
52
+ # This option is needed to create a model based captcha.
53
+ # If this option is not provided, the captcha will be controller based and
54
+ # should be checked in controller's action just by calling the method simple_captcha_valid?
55
+ #
56
+ # To make a model based captcha give this option as...
57
+ #
58
+ # <%= show_simple_captcha(:object => "user") %>
59
+ # and also call the method apply_simple_captcha in the model
60
+ # this will consider "user" as the object of the model class.
61
+ #
62
+ # *Examples*
63
+ # * controller based
64
+ # <%= show_simple_captcha(:image_style => "embosed_silver", :label => "Human Authentication: type the text from image above") %>
65
+ # * model based
66
+ # <%= show_simple_captcha(:object => "person", :image_style => "simply_blue", :label => "Human Authentication: type the text from image above") %>
67
+ #
68
+ # Find more detailed examples with sample images here on my blog http://EXPRESSICA.com
69
+ #
70
+ # All Feedbacks/Comments/Issues/Queries are welcome.
71
+ def show_quick_captcha(options = {})
72
+ show_simple_captcha(options)
73
+ end
74
+
75
+ def show_simple_captcha(options = {})
76
+ simple_captcha_key = self.simple_captcha_key
77
+ options[:field_value] = set_simple_captcha_data(simple_captcha_key, options[:code_type])
78
+ @simple_captcha_options = {
79
+ :image => simple_captcha_image(simple_captcha_key, options),
80
+ :label => options[:label] || "(type the code from the image)", # TODO label
81
+ :field => simple_captcha_field(options)
82
+ }
83
+ render :partial => 'quick_captcha/quick_captcha',
84
+ :locals => { :simple_captcha_options => @simple_captcha_options }
85
+ end
86
+
87
+ private
88
+
89
+ def simple_captcha_image(simple_captcha_key, options = {})
90
+ url = main_app.quick_captcha_url(
91
+ :action => 'show',
92
+ :simple_captcha_key => simple_captcha_key,
93
+ :image_style => options[:image_style],
94
+ :distortion => options[:distortion],
95
+ :time => Time.now.to_i
96
+ )
97
+
98
+ img = "<img src='#{url}' alt='captcha' />"
99
+ img = img.html_safe if img.respond_to? :html_safe
100
+ img
101
+ end
102
+
103
+ def simple_captcha_field(options = {})
104
+ if object = options[:object]
105
+ text_field(object, :captcha, :value => '', :autocomplete => 'off') +
106
+ hidden_field(object, :captcha_key, {:value => options[:field_value]})
107
+ else
108
+ text_field_tag(:captcha, nil, :autocomplete => 'off')
109
+ end
110
+ end
111
+
112
+ def set_simple_captcha_data(simple_captcha_key, code_type = nil)
113
+ key, value = simple_captcha_key, generate_simple_captcha_data(code_type)
114
+ data = SimpleCaptchaData.get_data(key)
115
+ data.value = value
116
+ data.save!
117
+ key
118
+ end
119
+
120
+ def generate_simple_captcha_data(code_type = nil)
121
+ value = ''
122
+ case code_type
123
+ when 'numeric'
124
+ QuickCaptcha.captcha_length.times{ value << (48 + rand(10)).chr }
125
+ else
126
+ QuickCaptcha.captcha_length.times{ value << (65 + rand(26)).chr }
127
+ end
128
+ value
129
+ end
130
+
131
+ end
132
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quick_captcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam H
9
+ - Marek de Heus
10
+ - Karol Bucek
11
+ - Kei Kusakari
12
+ - nap
13
+ - Sur
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+ date: 2012-06-26 00:00:00.000000000 Z
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: quick_magick
21
+ requirement: &70332610336100 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - =
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.0
27
+ type: :runtime
28
+ prerelease: false
29
+ version_requirements: *70332610336100
30
+ description: Forked from https://github.com/kares/simple_captcha
31
+ email:
32
+ - ahull@tnsolutionsinc.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - app/controllers/quick_captcha_controller.rb
38
+ - app/models/simple_captcha_data.rb
39
+ - app/views/quick_captcha/_quick_captcha.erb
40
+ - config/initializers/quick_captcha.rb
41
+ - config/routes.rb
42
+ - lib/generators/quick_captcha_generator.rb
43
+ - lib/generators/templates/migration.rb
44
+ - lib/quick_captcha/captcha_utils.rb
45
+ - lib/quick_captcha/controller_validation.rb
46
+ - lib/quick_captcha/engine.rb
47
+ - lib/quick_captcha/image_helpers.rb
48
+ - lib/quick_captcha/model_validation.rb
49
+ - lib/quick_captcha/quick_magick_backend.rb
50
+ - lib/quick_captcha/version.rb
51
+ - lib/quick_captcha/view_helpers.rb
52
+ - lib/quick_captcha.rb
53
+ - MIT-LICENSE
54
+ - Rakefile
55
+ - README.md
56
+ homepage: http://tnsolutionsinc.com
57
+ licenses: []
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 1.8.11
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: Simple Captcha solution using lightweight QuickMagick backend implemented
80
+ as Rails 3.2 engine
81
+ test_files: []