simple_captcha2 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6621a6904b50c409e89e74475975dd3c6c74f149
4
+ data.tar.gz: 265c44d59754f47e0b822072364b1eba94d63a92
5
+ SHA512:
6
+ metadata.gz: a121023c470455b51fecb402780637ba1f3b6a2bfa52b39b27fd6b7a986c788ec02e49c29eb32588598fec10f7cefcc9db10cdf4ea795ac0e1bd9ebd56786dc6
7
+ data.tar.gz: 5c8af3bfd86e3e2e5fe1bb9e1cc6681b3e0e6a2ded5d92834203425c1fae26ad90e6a12c9f82e5c21be49301559a38863944e16202df98cb9b05e8b4a5083ce4
@@ -0,0 +1,244 @@
1
+ =SimpleCaptcha2
2
+
3
+ SimpleCaptcha(2) is the simplest and a robust captcha plugin. Its implementation requires
4
+ adding up a single line in views and in controllers/models.
5
+ SimpleCaptcha2 is available to be used with Rails 3 + 4.
6
+ This is a fork of the popular Rubygem simple_captcha which got abandoned.
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 rendering 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_captcha2'
28
+
29
+ # OR
30
+
31
+ gem 'simple_captcha', :git => 'git://github.com/pludoni/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::Base
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
+ placeholder: "Enter the image value"
212
+ label: "Enter the code in the box:"
213
+ message:
214
+ default: "Secret Code did not match with the Image"
215
+ user: "The secret Image and code were different"
216
+
217
+ ==Contributing
218
+
219
+ For testing, generate a temporary Rails dummy app inside test:
220
+
221
+ rake dummy:setup
222
+ rake app:db:migrate
223
+ rake app:db:migrate RAILS_ENV=test
224
+ export BUNDLE_GEMFILE=$PWD/Gemfile
225
+ cd test/dummy && rake db:migrate db:test:prepare
226
+ rake test
227
+
228
+ Please add test cases when adding new functionality. I started with some basic example integration tests for a very basic coverage.
229
+
230
+ ==Who's who?
231
+
232
+ Enjoy the simplest captcha implementation.
233
+
234
+ Author: Sur
235
+
236
+ Blog: http://expressica.com
237
+
238
+ Contact: sur.max@gmail.com
239
+
240
+ Plugin Homepage: http://expressica.com/simple_captcha
241
+
242
+ Plugin update for rails 3: http://github.com/galetahub
243
+
244
+ Any feedback/comment/issue/donation is welcome!
@@ -0,0 +1,54 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'SimpleCaptcha'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ if File.exists? APP_RAKEFILE
19
+ load 'rails/tasks/engine.rake'
20
+ end
21
+
22
+ namespace :dummy do
23
+ desc 'Setup dummy Rails app for test purpose'
24
+ task :setup do
25
+ require 'rails'
26
+ require 'simple_captcha'
27
+ require File.expand_path('../test/lib/generators/simple_captcha/dummy/dummy_generator', __FILE__)
28
+ SimpleCaptcha::DummyGenerator.start %w(--quiet)
29
+ end
30
+
31
+ desc 'destroy dummy Rails app under test/dummy'
32
+ task :destroy do
33
+ FileUtils.rm_rf "test/dummy" if File.exists?("test/dummy")
34
+ end
35
+
36
+ end
37
+
38
+
39
+
40
+
41
+ Bundler::GemHelper.install_tasks :name => 'simple_captcha2'
42
+
43
+ require 'rake/testtask'
44
+
45
+ Rake::TestTask.new(:test) do |t|
46
+ t.libs << 'lib'
47
+ t.libs << 'test'
48
+ t.pattern = 'test/**/*_test.rb'
49
+ t.verbose = false
50
+ end
51
+
52
+
53
+ task default: :test
54
+
@@ -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,66 @@
1
+ # encoding: utf-8
2
+
3
+ module SimpleCaptcha
4
+ class << self
5
+ attr_accessor :always_pass
6
+ end
7
+ self.always_pass = Rails.env.test?
8
+ autoload :Utils, 'simple_captcha/utils'
9
+
10
+ autoload :ImageHelpers, 'simple_captcha/image'
11
+ autoload :ViewHelper, 'simple_captcha/view'
12
+ autoload :ControllerHelpers, 'simple_captcha/controller'
13
+
14
+ autoload :FormBuilder, 'simple_captcha/form_builder'
15
+ autoload :CustomFormBuilder, 'simple_captcha/formtastic'
16
+
17
+ if defined?(ActiveRecord)
18
+ autoload :ModelHelpers, 'simple_captcha/active_record'
19
+ autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data'
20
+ else
21
+ autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data_mongoid.rb'
22
+ end
23
+
24
+
25
+ autoload :Middleware, 'simple_captcha/middleware'
26
+
27
+ mattr_accessor :image_size
28
+ @@image_size = "100x28"
29
+
30
+ mattr_accessor :length
31
+ @@length = 5
32
+
33
+ # 'embosed_silver',
34
+ # 'simply_red',
35
+ # 'simply_green',
36
+ # 'simply_blue',
37
+ # 'distorted_black',
38
+ # 'all_black',
39
+ # 'charcoal_grey',
40
+ # 'almost_invisible'
41
+ # 'random'
42
+ mattr_accessor :image_style
43
+ @@image_style = 'simply_blue'
44
+
45
+ # 'low', 'medium', 'high', 'random'
46
+ mattr_accessor :distortion
47
+ @@distortion = 'low'
48
+
49
+ # command path
50
+ mattr_accessor :image_magick_path
51
+ @@image_magick_path = ''
52
+
53
+ # tmp directory
54
+ mattr_accessor :tmp_path
55
+ @@tmp_path = nil
56
+
57
+ def self.add_image_style(name, params = [])
58
+ SimpleCaptcha::ImageHelpers.image_styles.update(name.to_s => params)
59
+ end
60
+
61
+ def self.setup
62
+ yield self
63
+ end
64
+ end
65
+
66
+ require 'simple_captcha/engine' if defined?(Rails)
@@ -0,0 +1,74 @@
1
+ module SimpleCaptcha #:nodoc
2
+ module ModelHelpers #:nodoc
3
+ def self.included(base)
4
+ base.extend(SingletonMethods)
5
+ end
6
+
7
+ # To implement model based simple captcha use this method in the model as...
8
+ #
9
+ # class User < ActiveRecord::Base
10
+ #
11
+ # apply_simple_captcha :message => "my customized message"
12
+ #
13
+ # end
14
+ #
15
+ # Customize the error message by using :message, the default message is "Captcha did not match".
16
+ # As in the applications captcha is needed with a very few cases like signing up the new user, but
17
+ # not every time you need to authenticate the captcha with @user.save. So as to maintain simplicity
18
+ # here we have the explicit method to save the instace with captcha validation as...
19
+ #
20
+ # * to validate the instance
21
+ #
22
+ # @user.valid_with_captcha? # whene captcha validation is required.
23
+ #
24
+ # @user.valid? # when captcha validation is not required.
25
+ #
26
+ # * to save the instance
27
+ #
28
+ # @user.save_with_captcha # whene captcha validation is required.
29
+ #
30
+ # @user.save # when captcha validation is not required.
31
+ module SingletonMethods
32
+ def apply_simple_captcha(options = {})
33
+ options = { :add_to_base => false }.merge(options)
34
+
35
+ class_attribute :simple_captcha_options
36
+ self.simple_captcha_options = options
37
+
38
+ unless self.is_a?(ClassMethods)
39
+ include InstanceMethods
40
+ extend ClassMethods
41
+
42
+ attr_accessor :captcha, :captcha_key
43
+ end
44
+ end
45
+ end
46
+
47
+ module ClassMethods
48
+ end
49
+
50
+ module InstanceMethods
51
+
52
+ def valid_with_captcha?
53
+ [valid?, is_captcha_valid?].all?
54
+ end
55
+
56
+ def is_captcha_valid?
57
+ return true if SimpleCaptcha.always_pass
58
+
59
+ if captcha && captcha.upcase.delete(" ") == SimpleCaptcha::Utils::simple_captcha_value(captcha_key)
60
+ SimpleCaptcha::Utils::simple_captcha_passed!(captcha_key)
61
+ return true
62
+ else
63
+ message = simple_captcha_options[:message] || I18n.t(self.class.model_name.to_s.downcase, :scope => [:simple_captcha, :message], :default => :default)
64
+ simple_captcha_options[:add_to_base] ? errors.add(:base, message) : errors.add(:captcha, message)
65
+ return false
66
+ end
67
+ end
68
+
69
+ def save_with_captcha
70
+ valid_with_captcha? && save(:validate => false)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,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 SimpleCaptcha.always_pass
18
+
19
+ if params[:captcha]
20
+ data = SimpleCaptcha::Utils::simple_captcha_value(params[:captcha_key] || 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,26 @@
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
+ require 'simple_captcha/formtastic'
19
+ end
20
+ end
21
+
22
+ config.app_middleware.use SimpleCaptcha::Middleware
23
+ end
24
+ end
25
+
26
+
@@ -0,0 +1,43 @@
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
+ base.send(:include, ActionView::Helpers)
7
+ if defined? Sprockets::Helpers
8
+ base.send(:include, Sprockets::Helpers::RailsHelper)
9
+ base.send(:include, Sprockets::Helpers::IsolatedHelper)
10
+ end
11
+
12
+ base.delegate :render, :session, :to => :template
13
+ end
14
+
15
+ module ClassMethods
16
+ # Example:
17
+ # <% form_for :post, :url => posts_path do |form| %>
18
+ # ...
19
+ # <%= form.simple_captcha :label => "Enter numbers.." %>
20
+ # <% end %>
21
+ #
22
+ def simple_captcha(options = {})
23
+ options.update :object => @object_name
24
+ show_simple_captcha(objectify_options(options))
25
+ end
26
+
27
+ private
28
+
29
+ def template
30
+ @template
31
+ end
32
+
33
+ def simple_captcha_field(options={})
34
+ html = {:autocomplete => 'off', :required => 'required', :value => ''}
35
+ html.merge!(options[:input_html] || {})
36
+ html[:placeholder] = options[:placeholder] || I18n.t('simple_captcha.placeholder')
37
+
38
+ text_field(:captcha, html) +
39
+ hidden_field(:captcha_key, {:value => options[:field_value]})
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ if defined? Formtastic
2
+ require 'formtastic/version'
3
+ if Formtastic::VERSION < '2.2'
4
+ raise 'Only Formtastic Version 2.2 or greater is supported by SimpleCaptcha'
5
+ end
6
+
7
+ class SimpleCaptchaInput
8
+ include Formtastic::Inputs::Base
9
+ def to_html
10
+ options.update :object => sanitized_object_name
11
+ builder.send(:show_simple_captcha, options)
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,86 @@
1
+ require 'tempfile'
2
+ module SimpleCaptcha #:nodoc
3
+ module ImageHelpers #:nodoc
4
+
5
+ mattr_accessor :image_styles
6
+ @@image_styles = {
7
+ 'embosed_silver' => ['-fill darkblue', '-shade 20x60', '-background white'],
8
+ 'simply_red' => ['-fill darkred', '-background white'],
9
+ 'simply_green' => ['-fill darkgreen', '-background white'],
10
+ 'simply_blue' => ['-fill darkblue', '-background white'],
11
+ 'distorted_black' => ['-fill darkblue', '-edge 10', '-background white'],
12
+ 'all_black' => ['-fill darkblue', '-edge 2', '-background white'],
13
+ 'charcoal_grey' => ['-fill darkblue', '-charcoal 5', '-background white'],
14
+ 'almost_invisible' => ['-fill red', '-solarize 50', '-background white']
15
+ }
16
+
17
+ DISTORTIONS = ['low', 'medium', 'high']
18
+
19
+ 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 << "-gravity \"Center\""
69
+ params << "-pointsize 22"
70
+ params << "-implode 0.2"
71
+
72
+ dst = Tempfile.new(RUBY_VERSION < '1.9' ? 'simple_captcha.jpg' : ['simple_captcha', '.jpg'], SimpleCaptcha.tmp_path)
73
+ dst.binmode
74
+
75
+ #params << "label:#{text} '#{File.expand_path(dst.path)}'"
76
+ params << "label:#{text} \"#{File.expand_path(dst.path)}\""
77
+
78
+ SimpleCaptcha::Utils::run("convert", params.join(' '))
79
+
80
+ dst.close
81
+
82
+ File.expand_path(dst.path)
83
+ #dst
84
+ end
85
+ end
86
+ 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,32 @@
1
+ module SimpleCaptcha
2
+ class SimpleCaptchaData < ::ActiveRecord::Base
3
+
4
+ if ::ActiveRecord::VERSION::MAJOR >= 3
5
+ # Fixes deprecation warning in Rails 3.2:
6
+ # DEPRECATION WARNING: Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.
7
+ self.table_name = "simple_captcha_data"
8
+ else
9
+ set_table_name "simple_captcha_data"
10
+ end
11
+ if ::ActiveRecord::VERSION::MAJOR == 3 and defined? attr_protected
12
+ attr_protected
13
+ end
14
+
15
+
16
+ class << self
17
+ def get_data(key)
18
+ where(key: key).first || new(key: key)
19
+ end
20
+
21
+ def remove_data(key)
22
+ delete_all(["#{connection.quote_column_name(:key)} = ?", key])
23
+ clear_old_data(1.hour.ago)
24
+ end
25
+
26
+ def clear_old_data(time = 1.hour.ago)
27
+ return unless Time === time
28
+ delete_all(["#{connection.quote_column_name(:updated_at)} < ?", time])
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ module SimpleCaptcha
2
+ class SimpleCaptchaData
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+
6
+ field :key, type: String
7
+ field :value, type: String
8
+
9
+ class << self
10
+ def get_data(key)
11
+ data = where(:key => key).first || new(:key => key)
12
+ end
13
+
14
+ def remove_data(key)
15
+ where(:key => key).delete_all
16
+ clear_old_data(1.hour.ago)
17
+ end
18
+
19
+ def clear_old_data(time = 1.hour.ago)
20
+ return unless Time === time
21
+ where(:updated_at.lte => time).delete_all
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ require 'digest/sha1'
2
+
3
+ module SimpleCaptcha #:nodoc
4
+ module Utils #:nodoc
5
+ # Execute command with params and return output if exit status equal expected_outcodes
6
+ def self.run(cmd, params = "", expected_outcodes = 0)
7
+ command = %Q[#{cmd} #{params}].gsub(/\s+/, " ")
8
+ command = "#{command} 2>&1"
9
+
10
+ unless (image_magick_path = SimpleCaptcha.image_magick_path).blank?
11
+ command = File.join(image_magick_path, command)
12
+ end
13
+
14
+ output = `#{command}`
15
+
16
+ unless [expected_outcodes].flatten.include?($?.exitstatus)
17
+ raise ::StandardError, "Error while running #{cmd}: #{output}"
18
+ end
19
+
20
+ output
21
+ end
22
+
23
+ def self.simple_captcha_value(key) #:nodoc
24
+ SimpleCaptchaData.get_data(key).value rescue nil
25
+ end
26
+
27
+ def self.simple_captcha_passed!(key) #:nodoc
28
+ SimpleCaptchaData.remove_data(key)
29
+ end
30
+
31
+ def self.generate_key(*args)
32
+ args << Time.now.to_s
33
+ Digest::SHA1.hexdigest(args.join)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleCaptcha
2
+ VERSION = "0.2.0".freeze
3
+ end
@@ -0,0 +1,115 @@
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 = "#{ENV['RAILS_RELATIVE_URL_ROOT']}/simple_captcha?code=#{simple_captcha_key}&#{query}"
66
+
67
+ tag('img', :src => url, :alt => 'captcha')
68
+ end
69
+
70
+ def simple_captcha_field(options={})
71
+ html = {:autocomplete => 'off', :required => 'required'}
72
+ html.merge!(options[:input_html] || {})
73
+ html[:placeholder] = options[:placeholder] || I18n.t('simple_captcha.placeholder')
74
+
75
+ if options[:object]
76
+ text_field(options[:object], :captcha, html.merge(:value => '')) +
77
+ hidden_field(options[:object], :captcha_key, {:value => options[:field_value]})
78
+ else
79
+ text_field_tag(:captcha, nil, html) +
80
+ hidden_field_tag(:captcha_key, options[:field_value])
81
+ end
82
+ end
83
+
84
+ def set_simple_captcha_data(key, options={})
85
+ code_type = options[:code_type]
86
+
87
+ value = generate_simple_captcha_data(code_type)
88
+ data = SimpleCaptcha::SimpleCaptchaData.get_data(key)
89
+ data.value = value
90
+ data.save
91
+ key
92
+ end
93
+
94
+ def generate_simple_captcha_data(code)
95
+ value = ''
96
+
97
+ case code
98
+ when 'numeric' then
99
+ SimpleCaptcha.length.times{value << (48 + rand(10)).chr}
100
+ else
101
+ SimpleCaptcha.length.times{value << (65 + rand(26)).chr}
102
+ end
103
+
104
+ return value
105
+ end
106
+
107
+ def simple_captcha_key(key_name = nil)
108
+ if key_name.nil?
109
+ session[:captcha] ||= SimpleCaptcha::Utils.generate_key(session[:id].to_s, 'captcha')
110
+ else
111
+ SimpleCaptcha::Utils.generate_key(session[:id].to_s, key_name)
112
+ end
113
+ end
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_captcha2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Pavlo Galeta
8
+ - Igor Galeta
9
+ - Stefan Wienert
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-12-01 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '3.1'
29
+ - !ruby/object:Gem::Dependency
30
+ name: sqlite3
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: capybara-mechanize
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: pry
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ description: SimpleCaptcha is available to be used with Rails 3 + 4 or above and also
72
+ it provides the backward compatibility with previous versions of Rails.
73
+ email: stwienert@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files:
77
+ - README.rdoc
78
+ files:
79
+ - lib/generators/templates/migration.rb
80
+ - lib/generators/templates/partial.erb
81
+ - lib/generators/USAGE
82
+ - lib/generators/simple_captcha_generator.rb
83
+ - lib/simple_captcha.rb
84
+ - lib/simple_captcha/engine.rb
85
+ - lib/simple_captcha/active_record.rb
86
+ - lib/simple_captcha/controller.rb
87
+ - lib/simple_captcha/middleware.rb
88
+ - lib/simple_captcha/simple_captcha_data_mongoid.rb
89
+ - lib/simple_captcha/simple_captcha_data.rb
90
+ - lib/simple_captcha/utils.rb
91
+ - lib/simple_captcha/form_builder.rb
92
+ - lib/simple_captcha/image.rb
93
+ - lib/simple_captcha/view.rb
94
+ - lib/simple_captcha/formtastic.rb
95
+ - lib/simple_captcha/version.rb
96
+ - Rakefile
97
+ - README.rdoc
98
+ homepage: http://github.com/pludoni/simple-captcha
99
+ licenses: []
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.0.3
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: SimpleCaptcha is the simplest and a robust captcha plugin.
121
+ test_files: []