wxianfeng_simple_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,223 @@
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 'simple_captcha', :git => 'git://github.com/wxianfeng/simple-captcha.git'
28
+
29
+ ==Setup
30
+
31
+ After installation, follow these simple steps to setup the plugin. The setup will depend
32
+ on the version of rails your application is using.
33
+
34
+ rails generate simple_captcha
35
+
36
+ rake db:migrate
37
+
38
+ ==Usage
39
+
40
+ ===Controller Based
41
+
42
+ Add the following line in the file "app/controllers/application.rb"
43
+
44
+ ApplicationController < ActionController::Base
45
+ include SimpleCaptcha::ControllerHelpers
46
+ end
47
+
48
+ In the view file within the form tags add this code
49
+
50
+ <%= show_simple_captcha %>
51
+
52
+ and in the controller's action authenticate it as
53
+
54
+ if simple_captcha_valid?
55
+ do this
56
+ else
57
+ do that
58
+ end
59
+
60
+ ===Model Based
61
+
62
+ In the view file within the form tags write this code
63
+
64
+ <%= show_simple_captcha(:object=>"user") %>
65
+
66
+ and in the model class add this code
67
+
68
+ class User < ActiveRecord::Basse
69
+ apply_simple_captcha
70
+ attr_accessible :captcha,:captcha_key
71
+ end
72
+
73
+ ====FormBuilder helper
74
+
75
+ <%= form_for @user do |form| -%>
76
+ ...
77
+ <%= form.simple_captcha :label => "Enter numbers.." %>
78
+ ...
79
+ <% end -%>
80
+
81
+ ====Validating with captcha
82
+ NOTE: @user.valid? will still work as it should, it will not validate the captcha code.
83
+
84
+ @user.valid_with_captcha?
85
+
86
+ ====Saving with captcha
87
+ NOTE: @user.save will still work as it should, it will not validate the captcha code.
88
+
89
+ @user.save_with_captcha
90
+
91
+ ===Formtastic integration
92
+ SimpleCaptcha detects if your use Formtastic and appends "SimpleCaptcha::CustomFormBuilder".
93
+
94
+ <%= form.input :captcha, :as => :simple_captcha %>
95
+
96
+ ==Options & Examples
97
+ ===View Options
98
+
99
+ * *label* - provides the custom text b/w the image and the text field, the default is "type the code from the image"
100
+
101
+ * *object* - the name of the object of the model class, to implement the model based captcha.
102
+
103
+ * *code_type* - return numeric only if set to 'numeric'
104
+
105
+ ===Global options
106
+
107
+ * *image_style* - provides the specific image style for the captcha image.
108
+ There are eight different styles available with the plugin as...
109
+ 1) simply_blue
110
+ 2) simply_red
111
+ 3) simply_green
112
+ 4) charcoal_grey
113
+ 5) embosed_silver
114
+ 6) all_black
115
+ 7) distorted_black
116
+ 8) almost_invisible
117
+ Default style is 'simply_blue'.
118
+ You can also specify 'random' to select the random image style.
119
+
120
+ * *distortion* - handles the complexity of the image. The :distortion can be set to 'low', 'medium' or 'high'. Default is 'low'.
121
+
122
+ Create "rails_root/config/initializers/simple_captcha.rb"
123
+
124
+ SimpleCaptcha.setup do |sc|
125
+ # default: 100x28
126
+ sc.image_size = '120x40'
127
+
128
+ # default: 5
129
+ sc.length = 6
130
+
131
+ # default: simply_blue
132
+ # possible values:
133
+ # 'embosed_silver',
134
+ # 'simply_red',
135
+ # 'simply_green',
136
+ # 'simply_blue',
137
+ # 'distorted_black',
138
+ # 'all_black',
139
+ # 'charcoal_grey',
140
+ # 'almost_invisible'
141
+ # 'random'
142
+ sc.image_style = 'simply_green'
143
+
144
+ # default: low
145
+ # possible values: 'low', 'medium', 'high', 'random'
146
+ sc.distortion = 'medium'
147
+ end
148
+
149
+ You can add your own style:
150
+
151
+ SimpleCaptcha.setup do |sc|
152
+ sc.image_style = 'mycaptha'
153
+ sc.add_image_style('mycaptha', [
154
+ "-background '#F4F7F8'",
155
+ "-fill '#86818B'",
156
+ "-border 1",
157
+ "-bordercolor '#E0E2E3'"])
158
+ end
159
+
160
+ You can provide the path where image_magick is installed as well:
161
+
162
+ SimpleCaptcha.setup do |sc|
163
+ sc.image_magick_path = '/usr/bin' # you can check this from console by running: which convert
164
+ end
165
+
166
+
167
+ ===How to change the CSS for SimpleCaptcha DOM elements?
168
+ You can change the CSS of the SimpleCaptcha DOM elements as per your need in this file.
169
+ /app/views/simple_captcha/_simple_captcha.erb
170
+
171
+ ===View's Examples
172
+ ====Controller Based Example
173
+
174
+ <%= show_simple_captcha %>
175
+
176
+ <%= show_simple_captcha(:label => "human authentication") %>
177
+
178
+ <%= image_tag show_image_src %>
179
+
180
+ <%= image_tag show_image_src(:object=>"signup") %>
181
+
182
+ ====Model Based Example
183
+
184
+ <%= show_simple_captcha(:object => 'user', :label => "human authentication") %>
185
+
186
+ ====Model Options
187
+
188
+ * *message* - provides the custom message on failure of captcha authentication the default is "Secret Code did not match with the Image"
189
+
190
+ * *add_to_base* - if set to true, appends the error message to the base.
191
+
192
+ =====Model's Example
193
+
194
+ class User < ActiveRecord::Base
195
+ apply_simple_captcha
196
+ end
197
+
198
+ class User < ActiveRecord::Base
199
+ apply_simple_captcha :message => "The secret Image and code were different", :add_to_base => true
200
+ end
201
+
202
+ ==I18n
203
+
204
+ simple_captcha:
205
+ message:
206
+ default: "Secret Code did not match with the Image"
207
+ user: "The secret Image and code were different"
208
+
209
+ ==Who's who?
210
+
211
+ Enjoy the simplest captcha implementation.
212
+
213
+ Author: Sur
214
+
215
+ Blog: http://expressica.com
216
+
217
+ Contact: sur.max@gmail.com
218
+
219
+ Plugin Homepage: http://expressica.com/simple_captcha
220
+
221
+ Plugin update for rails 3: http://github.com/galetahub
222
+
223
+ Any feedback/comment/issue/donation is welcome!
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ require File.expand_path("../lib/simple_captcha/version", __FILE__)
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the simple_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 simple_captcha plugin.'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'SimpleCaptcha'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
25
+
26
+ task :build do
27
+ system "gem build wxianfeng_simple_captcha.gemspec"
28
+ end
29
+
30
+ task :install => :build do
31
+ system "sudo gem install wxianfeng_simple_captcha-#{SimpleCaptcha::VERSION}.gem"
32
+ end
33
+
34
+ task :release => :build do
35
+ puts "Tagging #{SimpleCaptcha::VERSION}..."
36
+ system "git tag -a #{SimpleCaptcha::VERSION} -m 'Tagging #{SimpleCaptcha::VERSION}'"
37
+ puts "Pushing to Github..."
38
+ system "git push --tags"
39
+ puts "Pushing to rubygems.org..."
40
+ system "gem push hanzi_to_pinyin-#{SimpleCaptcha::VERSION}.gem"
41
+ end
@@ -0,0 +1,18 @@
1
+ # encoding:utf-8
2
+ class SimpleCaptchaController < ActionController::Metal
3
+ include ActionController::Streaming
4
+ include SimpleCaptcha::ImageHelpers
5
+
6
+ # GET /simple_captcha
7
+ def show
8
+ unless params[:id].blank?
9
+ send_file(
10
+ generate_simple_captcha_image(params[:id]),
11
+ :type => 'image/png',
12
+ :disposition => 'inline',
13
+ :filename => 'simple_captcha.png')
14
+ else
15
+ self.response_body = [404, {"Content-Type" => "text/html"}, ["Not Found"]]
16
+ end
17
+ end
18
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ match '/simple_captcha/:id', :to => 'simple_captcha#show', :as => :simple_captcha
3
+ 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,51 @@
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
+
16
+ mattr_accessor :image_size
17
+ @@image_size = "100x28"
18
+
19
+ mattr_accessor :length
20
+ @@length = 5
21
+
22
+ # 'embosed_silver',
23
+ # 'simply_red',
24
+ # 'simply_green',
25
+ # 'simply_blue',
26
+ # 'distorted_black',
27
+ # 'all_black',
28
+ # 'charcoal_grey',
29
+ # 'almost_invisible'
30
+ # 'random'
31
+ mattr_accessor :image_style
32
+ @@image_style = 'simply_blue'
33
+
34
+ # 'low', 'medium', 'high', 'random'
35
+ mattr_accessor :distortion
36
+ @@distortion = 'low'
37
+
38
+ # command path
39
+ mattr_accessor :image_magick_path
40
+ @@image_magick_path = ''
41
+
42
+ def self.add_image_style(name, params = [])
43
+ SimpleCaptcha::ImageHelpers.image_styles.update(name.to_s => params)
44
+ end
45
+
46
+ def self.setup
47
+ yield self
48
+ end
49
+ end
50
+
51
+ require 'simple_captcha/railtie'
@@ -0,0 +1,72 @@
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
+ write_inheritable_attribute :simple_captcha_options, options
36
+ class_inheritable_reader :simple_captcha_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
+ if captcha && captcha.upcase.delete(" ") == SimpleCaptcha::Utils::simple_captcha_value(captcha_key)
58
+ SimpleCaptcha::Utils::simple_captcha_passed!(captcha_key)
59
+ return true
60
+ else
61
+ message = simple_captcha_options[:message] || I18n.t(self.class.model_name.downcase, :scope => [:simple_captcha, :message], :default => :default)
62
+ simple_captcha_options[:add_to_base] ? errors.add_to_base(message) : errors.add(:captcha, message)
63
+ return false
64
+ end
65
+ end
66
+
67
+ def save_with_captcha
68
+ valid_with_captcha? && save(:validate => false)
69
+ end
70
+ end
71
+ end
72
+ 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,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::SemanticFormBuilder
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,82 @@
1
+ module SimpleCaptcha #:nodoc
2
+ module ImageHelpers #:nodoc
3
+
4
+ mattr_accessor :image_styles
5
+ @@image_styles = {
6
+ 'embosed_silver' => ['-fill darkblue', '-shade 20x60', '-background white'],
7
+ 'simply_red' => ['-fill darkred', '-background white'],
8
+ 'simply_green' => ['-fill darkgreen', '-background white'],
9
+ 'simply_blue' => ['-fill darkblue', '-background white'],
10
+ 'distorted_black' => ['-fill darkblue', '-edge 10', '-background white'],
11
+ 'all_black' => ['-fill darkblue', '-edge 2', '-background white'],
12
+ 'charcoal_grey' => ['-fill darkblue', '-charcoal 5', '-background white'],
13
+ 'almost_invisible' => ['-fill red', '-solarize 50', '-background white']
14
+ }
15
+
16
+ DISTORTIONS = ['low', 'medium', 'high']
17
+
18
+ class << self
19
+
20
+ def image_params(key = 'simply_blue')
21
+ image_keys = @@image_styles.keys
22
+
23
+ style = begin
24
+ if key == 'random'
25
+ image_keys[rand(image_keys.length)]
26
+ else
27
+ image_keys.include?(key) ? key : 'simply_blue'
28
+ end
29
+ end
30
+
31
+ @@image_styles[style]
32
+ end
33
+
34
+ def distortion(key='low')
35
+ key =
36
+ key == 'random' ?
37
+ DISTORTIONS[rand(DISTORTIONS.length)] :
38
+ DISTORTIONS.include?(key) ? key : 'low'
39
+ case key.to_s
40
+ when 'low' then return [0 + rand(2), 80 + rand(20)]
41
+ when 'medium' then return [2 + rand(2), 50 + rand(20)]
42
+ when 'high' then return [4 + rand(2), 30 + rand(20)]
43
+ end
44
+ end
45
+ end
46
+
47
+ if RUBY_VERSION < '1.9'
48
+ class Tempfile < ::Tempfile
49
+ # Replaces Tempfile's +make_tmpname+ with one that honors file extensions.
50
+ def make_tmpname(basename, n = 0)
51
+ extension = File.extname(basename)
52
+ sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n, extension)
53
+ end
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def generate_simple_captcha_image(simple_captcha_key) #:nodoc
60
+ amplitude, frequency = ImageHelpers.distortion(SimpleCaptcha.distortion)
61
+ text = Utils::simple_captcha_value(simple_captcha_key)
62
+
63
+ params = ImageHelpers.image_params(SimpleCaptcha.image_style).dup
64
+ params << "-size #{SimpleCaptcha.image_size}"
65
+ params << "-wave #{amplitude}x#{frequency}"
66
+ params << "-gravity 'Center'"
67
+ params << "-pointsize 22"
68
+ params << "-implode 0.2"
69
+
70
+ dst = RUBY_VERSION < '1.9' ? Tempfile.new('simple_captcha.png') : Tempfile.new(['simple_captcha', '.png'])
71
+ dst.binmode
72
+
73
+ params << "label:#{text} '#{File.expand_path(dst.path)}'"
74
+
75
+ SimpleCaptcha::Utils::run("convert", params.join(' '))
76
+
77
+ dst.close
78
+
79
+ File.expand_path(dst.path)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'rails'
3
+ require 'simple_captcha'
4
+
5
+ module SimpleCaptcha
6
+ class Railtie < ::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
+ Formtastic::SemanticFormHelper.builder = SimpleCaptcha::CustomFormBuilder
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+
@@ -0,0 +1,23 @@
1
+ module SimpleCaptcha
2
+ class SimpleCaptchaData < ::ActiveRecord::Base
3
+ set_table_name "simple_captcha_data"
4
+
5
+ attr_accessible :key, :value
6
+
7
+ class << self
8
+ def get_data(key)
9
+ data = find_by_key(key) || new(:key => key)
10
+ end
11
+
12
+ def remove_data(key)
13
+ delete_all(["#{connection.quote_column_name(:key)} = ?", key])
14
+ clear_old_data(1.hour.ago)
15
+ end
16
+
17
+ def clear_old_data(time = 1.hour.ago)
18
+ return unless Time === time
19
+ delete_all(["#{connection.quote_column_name(:updated_at)} < ?", time])
20
+ end
21
+ end
22
+ end
23
+ 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,116 @@
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
+ def show_image_src(options={})
59
+ key = simple_captcha_key(options[:object])
60
+ set_simple_captcha_data(key, options)
61
+ %Q(/simple_captcha/#{key}?time=#{Time.now.to_i}).html_safe
62
+ end
63
+
64
+ private
65
+
66
+ def simple_captcha_image(simple_captcha_key, options = {})
67
+ defaults = {}
68
+ defaults[:time] = options[:time] || Time.now.to_i
69
+
70
+ query = defaults.collect{ |key, value| "#{key}=#{value}" }.join('&')
71
+ url = "/simple_captcha/#{simple_captcha_key}?#{query}"
72
+
73
+ "<img src='#{url}' alt='captcha' />".html_safe
74
+ end
75
+
76
+ def simple_captcha_field(options={})
77
+ if options[:object]
78
+ text_field(options[:object], :captcha, :value => '', :autocomplete => 'off') +
79
+ hidden_field(options[:object], :captcha_key, {:value => options[:field_value]})
80
+ else
81
+ text_field_tag(:captcha, nil, :autocomplete => 'off')
82
+ end
83
+ end
84
+
85
+ def set_simple_captcha_data(key, options={})
86
+ code_type = options[:code_type]
87
+
88
+ value = generate_simple_captcha_data(code_type)
89
+ data = SimpleCaptcha::SimpleCaptchaData.get_data(key)
90
+ data.value = value
91
+ data.save
92
+ key
93
+ end
94
+
95
+ def generate_simple_captcha_data(code)
96
+ value = ''
97
+
98
+ case code
99
+ when 'numeric' then
100
+ SimpleCaptcha.length.times{value << (48 + rand(10)).chr}
101
+ else
102
+ SimpleCaptcha.length.times{value << (65 + rand(26)).chr}
103
+ end
104
+
105
+ return value
106
+ end
107
+
108
+ def simple_captcha_key(key_name = nil)
109
+ if key_name.nil?
110
+ session[:captcha] ||= SimpleCaptcha::Utils.generate_key(session[:id].to_s, 'captcha')
111
+ else
112
+ SimpleCaptcha::Utils.generate_key(session[:id].to_s, key_name)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -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,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wxianfeng_simple_captcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pavlo Galeta
9
+ - Igor Galeta
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2010-10-26 00:00:00.000000000 +08:00
14
+ default_executable:
15
+ dependencies: []
16
+ description: SimpleCaptcha is available to be used with Rails 3 or above and also
17
+ it provides the backward compatibility with previous versions of Rails.
18
+ email: wang.fl1429@gmail.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files:
22
+ - README.rdoc
23
+ files:
24
+ - README.rdoc
25
+ - Rakefile
26
+ - app/controllers/simple_captcha_controller.rb
27
+ - config/routes.rb
28
+ - lib/generators/USAGE
29
+ - lib/generators/simple_captcha_generator.rb
30
+ - lib/generators/templates/migration.rb
31
+ - lib/generators/templates/partial.erb
32
+ - lib/simple_captcha.rb
33
+ - lib/simple_captcha/active_record.rb
34
+ - lib/simple_captcha/controller.rb
35
+ - lib/simple_captcha/form_builder.rb
36
+ - lib/simple_captcha/formtastic.rb
37
+ - lib/simple_captcha/image.rb
38
+ - lib/simple_captcha/railtie.rb
39
+ - lib/simple_captcha/simple_captcha_data.rb
40
+ - lib/simple_captcha/utils.rb
41
+ - lib/simple_captcha/view.rb
42
+ - test/simple_captcha_test.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/galetahub/simple-captcha
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=UTF-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project: simple_captcha
65
+ rubygems_version: 1.6.2
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: SimpleCaptcha is the simplest and a robust captcha plugin.
69
+ test_files:
70
+ - test/simple_captcha_test.rb