the_captcha 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,229 @@
1
+ =SimpleCaptcha
2
+
3
+ SimpleCaptcha is the simplest and a robust captcha plugin. Its implementation requires
4
+ adding up a single line in views and in controllers/models.
5
+ SimpleCaptcha is available to be used with Rails 3 or above and also it provides the
6
+ backward compatibility with previous versions of Rails.
7
+
8
+ ==Features
9
+
10
+ * Zero FileSystem usage(secret code moved to db-store and image storage removed).
11
+ * Provides various image styles.
12
+ * Provides three level of complexity of images.
13
+ * Works absolutely fine in distributed environment(session and db based implementation works fine in distributed environment).
14
+ * Implementation is as easy as just writing a single line in your view. "<%= show_simple_captcha %>" within the 'form' tags.
15
+ * Flexible DOM and CSS handling(There is a separate view partial for rednering SimpleCaptcha DOM elements).
16
+ * Automated removal of 1 hour old unmatched simple_captcha data.
17
+
18
+ ==Requirements
19
+
20
+ * {Ruby}[http://ruby-lang.org/] >= 1.8.7
21
+ * {Rails}[http://github.com/rails/rails] >= 3
22
+ * ImageMagick should be installed on your machine to use this plugin.
23
+ visit http://www.imagemagick.org/script/index.php for more details.
24
+
25
+ ==Installation
26
+
27
+ gem "galetahub-simple_captcha", :require => "simple_captcha"
28
+
29
+ or
30
+
31
+ gem 'galetahub-simple_captcha', :require => 'simple_captcha', :git => 'git://github.com/galetahub/simple-captcha.git'
32
+
33
+ ==Setup
34
+
35
+ After installation, follow these simple steps to setup the plugin. The setup will depend
36
+ on the version of rails your application is using.
37
+
38
+ rails generate simple_captcha
39
+
40
+ rake db:migrate
41
+
42
+ ==Usage
43
+
44
+ ===Controller Based
45
+
46
+ Add the following line in the file "app/controllers/application.rb"
47
+
48
+ ApplicationController < ActionController::Base
49
+ include SimpleCaptcha::ControllerHelpers
50
+ end
51
+
52
+ In the view file within the form tags add this code
53
+
54
+ <%= show_simple_captcha %>
55
+
56
+ and in the controller's action authenticate it as
57
+
58
+ if simple_captcha_valid?
59
+ do this
60
+ else
61
+ do that
62
+ end
63
+
64
+ ===Model Based
65
+
66
+ In the view file within the form tags write this code
67
+
68
+ <%= show_simple_captcha(:object=>"user") %>
69
+
70
+ and in the model class add this code
71
+
72
+ class User < ActiveRecord::Basse
73
+ apply_simple_captcha
74
+ end
75
+
76
+ ====FormBuilder helper
77
+
78
+ <%= form_for @user do |form| -%>
79
+ ...
80
+ <%= form.simple_captcha :label => "Enter numbers.." %>
81
+ ...
82
+ <% end -%>
83
+
84
+ ====Validating with captcha
85
+ NOTE: @user.valid? will still work as it should, it will not validate the captcha code.
86
+
87
+ @user.valid_with_captcha?
88
+
89
+ ====Saving with captcha
90
+ NOTE: @user.save will still work as it should, it will not validate the captcha code.
91
+
92
+ @user.save_with_captcha
93
+
94
+ ===Formtastic integration
95
+ SimpleCaptcha detects if your use Formtastic and appends "SimpleCaptcha::CustomFormBuilder".
96
+
97
+ <%= form.input :captcha, :as => :simple_captcha %>
98
+
99
+ ==Options & Examples
100
+ ===View Options
101
+
102
+ * *label* - provides the custom text b/w the image and the text field, the default is "type the code from the image"
103
+
104
+ * *object* - the name of the object of the model class, to implement the model based captcha.
105
+
106
+ * *code_type* - return numeric only if set to 'numeric'
107
+
108
+ ===Global options
109
+
110
+ * *image_style* - provides the specific image style for the captcha image.
111
+ There are eight different styles available with the plugin as...
112
+ 1) simply_blue
113
+ 2) simply_red
114
+ 3) simply_green
115
+ 4) charcoal_grey
116
+ 5) embosed_silver
117
+ 6) all_black
118
+ 7) distorted_black
119
+ 8) almost_invisible
120
+ Default style is 'simply_blue'.
121
+ You can also specify 'random' to select the random image style.
122
+
123
+ * *distortion* - handles the complexity of the image. The :distortion can be set to 'low', 'medium' or 'high'. Default is 'low'.
124
+
125
+ Create "rails_root/config/initializers/simple_captcha.rb"
126
+
127
+ SimpleCaptcha.setup do |sc|
128
+ # default: 100x28
129
+ sc.image_size = '120x40'
130
+
131
+ # default: 5
132
+ sc.length = 6
133
+
134
+ # default: simply_blue
135
+ # possible values:
136
+ # 'embosed_silver',
137
+ # 'simply_red',
138
+ # 'simply_green',
139
+ # 'simply_blue',
140
+ # 'distorted_black',
141
+ # 'all_black',
142
+ # 'charcoal_grey',
143
+ # 'almost_invisible'
144
+ # 'random'
145
+ sc.image_style = 'simply_green'
146
+
147
+ # default: low
148
+ # possible values: 'low', 'medium', 'high', 'random'
149
+ sc.distortion = 'medium'
150
+ end
151
+
152
+ You can add your own style:
153
+
154
+ SimpleCaptcha.setup do |sc|
155
+ sc.image_style = 'mycaptha'
156
+ sc.add_image_style('mycaptha', [
157
+ "-background '#F4F7F8'",
158
+ "-fill '#86818B'",
159
+ "-border 1",
160
+ "-bordercolor '#E0E2E3'"])
161
+ end
162
+
163
+ You can provide the path where image_magick is installed as well:
164
+
165
+ SimpleCaptcha.setup do |sc|
166
+ sc.image_magick_path = '/usr/bin' # you can check this from console by running: which convert
167
+ end
168
+
169
+ You can provide the path where should be stored tmp files.
170
+ It's usefull when you dont have acces to /tmp (default directory)
171
+
172
+ SimpleCaptcha.setup do |sc|
173
+ sc.tmp_path = '/tmp' # or somewhere in project eg. Rails.root.join('tmp/simple_captcha').to_s, make shure directory exists
174
+ end
175
+
176
+
177
+ ===How to change the CSS for SimpleCaptcha DOM elements?
178
+ You can change the CSS of the SimpleCaptcha DOM elements as per your need in this file.
179
+ /app/views/simple_captcha/_simple_captcha.erb
180
+
181
+ ===View's Examples
182
+ ====Controller Based Example
183
+
184
+ <%= show_simple_captcha %>
185
+
186
+ <%= show_simple_captcha(:label => "human authentication") %>
187
+
188
+ ====Model Based Example
189
+
190
+ <%= show_simple_captcha(:object => 'user', :label => "human authentication") %>
191
+
192
+ ====Model Options
193
+
194
+ * *message* - provides the custom message on failure of captcha authentication the default is "Secret Code did not match with the Image"
195
+
196
+ * *add_to_base* - if set to true, appends the error message to the base.
197
+
198
+ =====Model's Example
199
+
200
+ class User < ActiveRecord::Base
201
+ apply_simple_captcha
202
+ end
203
+
204
+ class User < ActiveRecord::Base
205
+ apply_simple_captcha :message => "The secret Image and code were different", :add_to_base => true
206
+ end
207
+
208
+ ==I18n
209
+
210
+ simple_captcha:
211
+ message:
212
+ default: "Secret Code did not match with the Image"
213
+ user: "The secret Image and code were different"
214
+
215
+ ==Who's who?
216
+
217
+ Enjoy the simplest captcha implementation.
218
+
219
+ Author: Sur
220
+
221
+ Blog: http://expressica.com
222
+
223
+ Contact: sur.max@gmail.com
224
+
225
+ Plugin Homepage: http://expressica.com/simple_captcha
226
+
227
+ Plugin update for rails 3: http://github.com/galetahub
228
+
229
+ Any feedback/comment/issue/donation is welcome!
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the simple_captcha plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the simple_captcha plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'SimpleCaptcha'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,4 @@
1
+ SimplaCaptcha
2
+ =============
3
+ # Generate migration and copy view partial
4
+ rails generate simple_captcha
@@ -0,0 +1,21 @@
1
+ require 'rails/generators'
2
+
3
+ class SimpleCaptchaGenerator < 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_partial
15
+ template "partial.erb", File.join('app/views', 'simple_captcha', "_simple_captcha.erb")
16
+ end
17
+
18
+ def create_migration
19
+ migration_template "migration.rb", File.join('db/migrate', "create_simple_captcha_data.rb")
20
+ end
21
+ end
@@ -0,0 +1,15 @@
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 => 6
6
+ t.timestamps
7
+ end
8
+
9
+ add_index :simple_captcha_data, :key, :name => "idx_key"
10
+ end
11
+
12
+ def self.down
13
+ drop_table :simple_captcha_data
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ <style type="text/CSS">
2
+ .simple_captcha{border: 1px solid #ccc; padding: 5px !important;}
3
+ .simple_captcha,
4
+ .simple_captcha div{display: table;}
5
+ .simple_captcha .simple_captcha_field,
6
+ .simple_captcha .simple_captcha_image{
7
+ border: 1px solid #ccc;
8
+ margin: 0px 0px 2px 0px !important;
9
+ padding: 0px !important;
10
+ }
11
+ .simple_captcha .simple_captcha_image img{
12
+ margin: 0px !important;
13
+ padding: 0px !important;
14
+ width: 110px !important;
15
+ }
16
+ .simple_captcha .simple_captcha_label{font-size: 12px;}
17
+ .simple_captcha .simple_captcha_field input{
18
+ width: 150px !important;
19
+ font-size: 16px;
20
+ border: none;
21
+ background-color: #efefef;
22
+ }
23
+ </style>
24
+
25
+ <div class='simple_captcha'>
26
+ <div class='simple_captcha_image'>
27
+ <%%= simple_captcha_options[:image] %>
28
+ </div>
29
+
30
+ <div class='simple_captcha_field'>
31
+ <%%= simple_captcha_options[:field] %>
32
+ </div>
33
+
34
+ <div class='simple_captcha_label'>
35
+ <%%= simple_captcha_options[:label] %>
36
+ </div>
37
+ </div>
@@ -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 Rails.env.test?
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.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,29 @@
1
+ module SimpleCaptcha #:nodoc
2
+ module ControllerHelpers #:nodoc
3
+ # This method is to validate the simple captcha in controller.
4
+ # It means when the captcha is controller based i.e. :object has not been passed to the method show_simple_captcha.
5
+ #
6
+ # *Example*
7
+ #
8
+ # If you want to save an object say @user only if the captcha is validated then do like this in action...
9
+ #
10
+ # if simple_captcha_valid?
11
+ # @user.save
12
+ # else
13
+ # flash[:notice] = "captcha did not match"
14
+ # redirect_to :action => "myaction"
15
+ # end
16
+ def simple_captcha_valid?
17
+ return true if Rails.env.test?
18
+
19
+ if params[:captcha]
20
+ data = SimpleCaptcha::Utils::simple_captcha_value(session[:captcha])
21
+ result = data == params[:captcha].delete(" ").upcase
22
+ SimpleCaptcha::Utils::simple_captcha_passed!(session[:captcha]) if result
23
+ return result
24
+ else
25
+ return false
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ require 'rails'
3
+ require 'simple_captcha'
4
+
5
+ module SimpleCaptcha
6
+ class Engine < ::Rails::Engine
7
+ config.before_initialize do
8
+ ActiveSupport.on_load :active_record do
9
+ ActiveRecord::Base.send(:include, SimpleCaptcha::ModelHelpers)
10
+ end
11
+ end
12
+
13
+ config.after_initialize do
14
+ ActionView::Base.send(:include, SimpleCaptcha::ViewHelper)
15
+ ActionView::Helpers::FormBuilder.send(:include, SimpleCaptcha::FormBuilder)
16
+
17
+ if Object.const_defined?("Formtastic")
18
+ if Formtastic.const_defined?("Helpers")
19
+ Formtastic::Helpers::FormHelper.builder = SimpleCaptcha::CustomFormBuilder
20
+ else
21
+ Formtastic::SemanticFormHelper.builder = SimpleCaptcha::CustomFormBuilder
22
+ end
23
+ end
24
+ end
25
+
26
+ config.app_middleware.use SimpleCaptcha::Middleware
27
+ end
28
+ end
29
+
30
+
@@ -0,0 +1,34 @@
1
+ module SimpleCaptcha
2
+ module FormBuilder
3
+ def self.included(base)
4
+ base.send(:include, SimpleCaptcha::ViewHelper)
5
+ base.send(:include, SimpleCaptcha::FormBuilder::ClassMethods)
6
+
7
+ base.delegate :render, :session, :to => :template
8
+ end
9
+
10
+ module ClassMethods
11
+ # Example:
12
+ # <% form_for :post, :url => posts_path do |form| %>
13
+ # ...
14
+ # <%= form.simple_captcha :label => "Enter numbers.." %>
15
+ # <% end %>
16
+ #
17
+ def simple_captcha(options = {})
18
+ options.update :object => @object_name
19
+ show_simple_captcha(objectify_options(options))
20
+ end
21
+
22
+ private
23
+
24
+ def template
25
+ @template
26
+ end
27
+
28
+ def simple_captcha_field(options={})
29
+ text_field(:captcha, :value => '', :autocomplete => 'off') +
30
+ hidden_field(:captcha_key, {:value => options[:field_value]})
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module SimpleCaptcha
2
+ class CustomFormBuilder < Formtastic::FormBuilder
3
+
4
+ private
5
+
6
+ def simple_captcha_input(method, options)
7
+ options.update :object => sanitized_object_name
8
+ self.send(:show_simple_captcha, options)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,84 @@
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
+ class << self
20
+
21
+ def image_params(key = 'simply_blue')
22
+ image_keys = @@image_styles.keys
23
+
24
+ style = begin
25
+ if key == 'random'
26
+ image_keys[rand(image_keys.length)]
27
+ else
28
+ image_keys.include?(key) ? key : 'simply_blue'
29
+ end
30
+ end
31
+
32
+ @@image_styles[style]
33
+ end
34
+
35
+ def distortion(key='low')
36
+ key =
37
+ key == 'random' ?
38
+ DISTORTIONS[rand(DISTORTIONS.length)] :
39
+ DISTORTIONS.include?(key) ? key : 'low'
40
+ case key.to_s
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
+ end
47
+
48
+ if RUBY_VERSION < '1.9'
49
+ class Tempfile < ::Tempfile
50
+ # Replaces Tempfile's +make_tmpname+ with one that honors file extensions.
51
+ def make_tmpname(basename, n = 0)
52
+ extension = File.extname(basename)
53
+ sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n, extension)
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def generate_simple_captcha_image(simple_captcha_key) #:nodoc
61
+ amplitude, frequency = ImageHelpers.distortion(SimpleCaptcha.distortion)
62
+ text = Utils::simple_captcha_value(simple_captcha_key)
63
+
64
+ params = ImageHelpers.image_params(SimpleCaptcha.image_style).dup
65
+ params << "-size #{SimpleCaptcha.image_size}"
66
+ params << "-wave #{amplitude}x#{frequency}"
67
+ params << "-gravity 'Center'"
68
+ params << "-pointsize 22"
69
+ params << "-implode 0.2"
70
+
71
+ dst = Tempfile.new(RUBY_VERSION < '1.9' ? 'simple_captcha.jpg' : ['simple_captcha', '.jpg'], SimpleCaptcha.tmp_path)
72
+ dst.binmode
73
+
74
+ params << "label:#{text} '#{File.expand_path(dst.path)}'"
75
+
76
+ SimpleCaptcha::Utils::run("convert", params.join(' '))
77
+
78
+ dst.close
79
+
80
+ File.expand_path(dst.path)
81
+ #dst
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module SimpleCaptcha
3
+ class Middleware
4
+ include SimpleCaptcha::ImageHelpers
5
+
6
+ DEFAULT_SEND_FILE_OPTIONS = {
7
+ :type => 'application/octet-stream'.freeze,
8
+ :disposition => 'attachment'.freeze,
9
+ }.freeze
10
+
11
+ def initialize(app, options={})
12
+ @app = app
13
+ self
14
+ end
15
+
16
+ def call(env) # :nodoc:
17
+ if env["REQUEST_METHOD"] == "GET" && captcha_path?(env['PATH_INFO'])
18
+ make_image(env)
19
+ else
20
+ @app.call(env)
21
+ end
22
+ end
23
+
24
+ protected
25
+ def make_image(env, headers = {}, status = 404)
26
+ request = Rack::Request.new(env)
27
+ code = request.params["code"]
28
+ body = []
29
+
30
+ if !code.blank? && Utils::simple_captcha_value(code)
31
+ #status, headers, body = @app.call(env)
32
+ #status = 200
33
+ #body = generate_simple_captcha_image(code)
34
+ #headers['Content-Type'] = 'image/jpeg'
35
+
36
+ return send_file(generate_simple_captcha_image(code), :type => 'image/jpeg', :disposition => 'inline', :filename => 'simple_captcha.jpg')
37
+ end
38
+
39
+ [status, headers, body]
40
+ end
41
+
42
+ def captcha_path?(request_path)
43
+ request_path.include?('/simple_captcha')
44
+ end
45
+
46
+ def send_file(path, options = {})
47
+ raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
48
+
49
+ options[:filename] ||= File.basename(path) unless options[:url_based_filename]
50
+
51
+ status = options[:status] || 200
52
+ headers = {"Content-Disposition" => "#{options[:disposition]}; filename='#{options[:filename]}'", "Content-Type" => options[:type], 'Content-Transfer-Encoding' => 'binary', 'Cache-Control' => 'private'}
53
+ response_body = File.open(path, "rb")
54
+
55
+ [status, headers, response_body]
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,33 @@
1
+ module SimpleCaptcha
2
+ class SimpleCaptchaData < ::ActiveRecord::Base
3
+ def self.rails3?
4
+ ::ActiveRecord::VERSION::MAJOR == 3
5
+ end
6
+
7
+ if rails3?
8
+ # Fixes deprecation warning in Rails 3.2:
9
+ # DEPRECATION WARNING: Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.
10
+ self.table_name = "simple_captcha_data"
11
+ else
12
+ set_table_name "simple_captcha_data"
13
+ end
14
+
15
+ attr_accessible :key, :value
16
+
17
+ class << self
18
+ def get_data(key)
19
+ data = find_by_key(key) || new(:key => key)
20
+ end
21
+
22
+ def remove_data(key)
23
+ delete_all(["#{connection.quote_column_name(:key)} = ?", key])
24
+ clear_old_data(1.hour.ago)
25
+ end
26
+
27
+ def clear_old_data(time = 1.hour.ago)
28
+ return unless Time === time
29
+ delete_all(["#{connection.quote_column_name(:updated_at)} < ?", time])
30
+ end
31
+ end
32
+ end
33
+ 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_s
33
+ Digest::SHA1.hexdigest(args.join)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ module SimpleCaptcha
3
+ VERSION = "0.1.0".freeze
4
+ end
@@ -0,0 +1,110 @@
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
+ key = simple_captcha_key(options[:object])
47
+ options[:field_value] = set_simple_captcha_data(key, options)
48
+
49
+ defaults = {
50
+ :image => simple_captcha_image(key, options),
51
+ :label => options[:label] || I18n.t('simple_captcha.label'),
52
+ :field => simple_captcha_field(options)
53
+ }
54
+
55
+ render :partial => 'simple_captcha/simple_captcha', :locals => { :simple_captcha_options => defaults }
56
+ end
57
+
58
+ private
59
+
60
+ def simple_captcha_image(simple_captcha_key, options = {})
61
+ defaults = {}
62
+ defaults[:time] = options[:time] || Time.now.to_i
63
+
64
+ query = defaults.collect{ |key, value| "#{key}=#{value}" }.join('&')
65
+ url = "/simple_captcha?code=#{simple_captcha_key}&#{query}"
66
+
67
+ "<img src='#{url}' alt='captcha' />".html_safe
68
+ end
69
+
70
+ def simple_captcha_field(options={})
71
+ if options[:object]
72
+ text_field(options[:object], :captcha, :value => '', :autocomplete => 'off') +
73
+ hidden_field(options[:object], :captcha_key, {:value => options[:field_value]})
74
+ else
75
+ text_field_tag(:captcha, nil, :autocomplete => 'off')
76
+ end
77
+ end
78
+
79
+ def set_simple_captcha_data(key, options={})
80
+ code_type = options[:code_type]
81
+
82
+ value = generate_simple_captcha_data(code_type)
83
+ data = SimpleCaptcha::SimpleCaptchaData.get_data(key)
84
+ data.value = value
85
+ data.save
86
+ key
87
+ end
88
+
89
+ def generate_simple_captcha_data(code)
90
+ value = ''
91
+
92
+ case code
93
+ when 'numeric' then
94
+ SimpleCaptcha.length.times{value << (48 + rand(10)).chr}
95
+ else
96
+ SimpleCaptcha.length.times{value << (65 + rand(26)).chr}
97
+ end
98
+
99
+ return value
100
+ end
101
+
102
+ def simple_captcha_key(key_name = nil)
103
+ if key_name.nil?
104
+ session[:captcha] ||= SimpleCaptcha::Utils.generate_key(session[:id].to_s, 'captcha')
105
+ else
106
+ SimpleCaptcha::Utils.generate_key(session[:id].to_s, key_name)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ module SimpleCaptcha
4
+ autoload :Utils, 'simple_captcha/utils'
5
+
6
+ autoload :ImageHelpers, 'simple_captcha/image'
7
+ autoload :ViewHelper, 'simple_captcha/view'
8
+ autoload :ControllerHelpers, 'simple_captcha/controller'
9
+ autoload :ModelHelpers, 'simple_captcha/active_record'
10
+
11
+ autoload :FormBuilder, 'simple_captcha/form_builder'
12
+ autoload :CustomFormBuilder, 'simple_captcha/formtastic'
13
+
14
+ autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data'
15
+ autoload :Middleware, 'simple_captcha/middleware'
16
+
17
+ mattr_accessor :image_size
18
+ @@image_size = "100x28"
19
+
20
+ mattr_accessor :length
21
+ @@length = 5
22
+
23
+ # 'embosed_silver',
24
+ # 'simply_red',
25
+ # 'simply_green',
26
+ # 'simply_blue',
27
+ # 'distorted_black',
28
+ # 'all_black',
29
+ # 'charcoal_grey',
30
+ # 'almost_invisible'
31
+ # 'random'
32
+ mattr_accessor :image_style
33
+ @@image_style = 'simply_blue'
34
+
35
+ # 'low', 'medium', 'high', 'random'
36
+ mattr_accessor :distortion
37
+ @@distortion = 'low'
38
+
39
+ # command path
40
+ mattr_accessor :image_magick_path
41
+ @@image_magick_path = ''
42
+
43
+ # tmp directory
44
+ mattr_accessor :tmp_path
45
+ @@tmp_path = nil
46
+
47
+ def self.add_image_style(name, params = [])
48
+ SimpleCaptcha::ImageHelpers.image_styles.update(name.to_s => params)
49
+ end
50
+
51
+ def self.setup
52
+ yield self
53
+ end
54
+ end
55
+
56
+ require 'simple_captcha/engine' if defined?(Rails)
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+
3
+ class SimpleCaptchaTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_this_plugin
6
+ flunk
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: the_captcha
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Ilya N. Zykin
14
+ - Pavlo Galeta
15
+ - Igor Galeta
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2012-04-17 00:00:00 +04:00
21
+ default_executable:
22
+ dependencies: []
23
+
24
+ description: My version of SimpleCaptcha
25
+ email: galeta.igor@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README.rdoc
32
+ files:
33
+ - lib/generators/simple_captcha_generator.rb
34
+ - lib/generators/templates/migration.rb
35
+ - lib/generators/templates/partial.erb
36
+ - lib/generators/USAGE
37
+ - lib/simple_captcha/active_record.rb
38
+ - lib/simple_captcha/image.rb
39
+ - lib/simple_captcha/controller.rb
40
+ - lib/simple_captcha/form_builder.rb
41
+ - lib/simple_captcha/utils.rb
42
+ - lib/simple_captcha/simple_captcha_data.rb
43
+ - lib/simple_captcha/version.rb
44
+ - lib/simple_captcha/view.rb
45
+ - lib/simple_captcha/formtastic.rb
46
+ - lib/simple_captcha/middleware.rb
47
+ - lib/simple_captcha/engine.rb
48
+ - lib/simple_captcha.rb
49
+ - Rakefile
50
+ - README.rdoc
51
+ - test/simple_captcha_test.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/the-teacher/the-captcha
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project: the_captcha
82
+ rubygems_version: 1.6.2
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: My version of SimpleCaptcha
86
+ test_files:
87
+ - test/simple_captcha_test.rb