tiny_captcha 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/app/controllers/tiny_captcha/application_controller.rb +1 -0
- data/app/controllers/tiny_captcha/images_controller.rb +21 -0
- data/app/helpers/tiny_captcha/application_helper.rb +1 -0
- data/config/locales/en/tiny_captcha.en.yml +9 -0
- data/config/locales/zh-CN/tiny_captcha.zh-CN.yml +8 -0
- data/config/routes.rb +4 -0
- data/lib/generators/USAGE +4 -0
- data/lib/generators/templates/migration.rb +16 -0
- data/lib/generators/templates/partial.erb +37 -0
- data/lib/generators/tiny_captcha_generator.rb +22 -0
- data/lib/tiny_captcha.rb +64 -1
- data/lib/tiny_captcha/active_record.rb +93 -0
- data/lib/tiny_captcha/controller.rb +58 -0
- data/lib/tiny_captcha/engine.rb +28 -1
- data/lib/tiny_captcha/form_builder.rb +43 -0
- data/lib/tiny_captcha/formtastic.rb +12 -0
- data/lib/tiny_captcha/image.rb +85 -0
- data/lib/tiny_captcha/middleware.rb +70 -0
- data/lib/tiny_captcha/tiny_captcha_data.rb +36 -0
- data/lib/tiny_captcha/tiny_captcha_data_mongoid.rb +26 -0
- data/lib/tiny_captcha/utils.rb +80 -0
- data/lib/tiny_captcha/version.rb +2 -1
- data/lib/tiny_captcha/view.rb +99 -0
- data/test/dummy/app/controllers/application_controller.rb +1 -0
- data/test/dummy/app/helpers/application_helper.rb +1 -0
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/boot.rb +1 -0
- data/test/dummy/config/environment.rb +1 -0
- data/test/dummy/config/environments/development.rb +1 -0
- data/test/dummy/config/environments/production.rb +1 -0
- data/test/dummy/config/environments/test.rb +1 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +1 -0
- data/test/dummy/config/initializers/inflections.rb +1 -0
- data/test/dummy/config/initializers/mime_types.rb +1 -0
- data/test/dummy/config/initializers/secret_token.rb +1 -0
- data/test/dummy/config/initializers/session_store.rb +1 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +1 -0
- data/test/dummy/config/routes.rb +1 -0
- data/test/integration/navigation_test.rb +1 -0
- data/test/test_helper.rb +1 -0
- data/test/tiny_captcha_test.rb +1 -0
- metadata +85 -82
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a7470acbf45a2f9152ed8f19180067c67714090e
|
4
|
+
data.tar.gz: 6a9fb11adfc2d802b7a2579be6d279d48e83ec6b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e4590af09ba5857c23fe31f597afeef564b461f90dcacfd3f93fa24f62acbaf99f08f1a28878f7760f8eb60b55e15b903885dfd84cb08805f5ecac018c376a7e
|
7
|
+
data.tar.gz: e88bfba0336b263b24f8f3b041b258e16e11e2897cfd334a23bca7565f7bd9e144b86aa1542a7cf91f42e873e08f5fef3759be525f3cf0ae157239f185f8b466
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha
|
3
|
+
class ImagesController < ::ActionController::Base
|
4
|
+
#
|
5
|
+
# params:
|
6
|
+
# - object
|
7
|
+
#
|
8
|
+
def new
|
9
|
+
@tiny_captcha_options = generate_tiny_captcha_options(:object => params[:object])
|
10
|
+
|
11
|
+
respond_to do |format|
|
12
|
+
format.json {
|
13
|
+
render :json => {
|
14
|
+
:tiny_captcha_options => @tiny_captcha_options
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
class CreateTinyCaptchaData < ActiveRecord::Migration
|
3
|
+
def self.up
|
4
|
+
create_table :tiny_captcha_data do |t|
|
5
|
+
t.string :key, :limit => 40
|
6
|
+
t.string :value, :limit => 6
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :tiny_captcha_data, :key
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :tiny_captcha_data
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<style type="text/CSS">
|
2
|
+
.tiny_captcha{border: 1px solid #ccc; padding: 5px !important;}
|
3
|
+
.tiny_captcha,
|
4
|
+
.tiny_captcha div{display: table;}
|
5
|
+
.tiny_captcha .tiny_captcha_field,
|
6
|
+
.tiny_captcha .tiny_captcha_image{
|
7
|
+
border: 1px solid #ccc;
|
8
|
+
margin: 0px 0px 2px 0px !important;
|
9
|
+
padding: 0px !important;
|
10
|
+
}
|
11
|
+
.tiny_captcha .tiny_captcha_image img{
|
12
|
+
margin: 0px !important;
|
13
|
+
padding: 0px !important;
|
14
|
+
width: 110px !important;
|
15
|
+
}
|
16
|
+
.tiny_captcha .tiny_captcha_label{font-size: 12px;}
|
17
|
+
.tiny_captcha .tiny_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='tiny_captcha'>
|
26
|
+
<div class='tiny_captcha_image'>
|
27
|
+
<%%= tiny_captcha_options[:image] %>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class='tiny_captcha_field'>
|
31
|
+
<%%= tiny_captcha_options[:field] %>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<div class='tiny_captcha_label'>
|
35
|
+
<%%= tiny_captcha_options[:label] %>
|
36
|
+
</div>
|
37
|
+
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'rails/generators'
|
3
|
+
|
4
|
+
class TinyCaptchaGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates/'))
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.next_migration_number(dirname)
|
12
|
+
Time.now.strftime("%Y%m%d%H%M%S")
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_partial
|
16
|
+
template "partial.erb", File.join('app/views', 'tiny_captcha', "_tiny_captcha.erb")
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_migration
|
20
|
+
migration_template "migration.rb", File.join('db/migrate', "create_tiny_captcha_data.rb")
|
21
|
+
end
|
22
|
+
end
|
data/lib/tiny_captcha.rb
CHANGED
@@ -1,4 +1,67 @@
|
|
1
|
-
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
module TinyCaptcha
|
4
|
+
autoload :Utils, 'tiny_captcha/utils'
|
5
|
+
|
6
|
+
autoload :ImageHelpers, 'tiny_captcha/image'
|
7
|
+
autoload :ViewHelper, 'tiny_captcha/view'
|
8
|
+
autoload :ControllerHelpers, 'tiny_captcha/controller'
|
9
|
+
|
10
|
+
autoload :FormBuilder, 'tiny_captcha/form_builder'
|
11
|
+
autoload :CustomFormBuilder, 'tiny_captcha/formtastic'
|
12
|
+
|
13
|
+
if defined?(ActiveRecord)
|
14
|
+
autoload :ModelHelpers, 'tiny_captcha/active_record'
|
15
|
+
autoload :TinyCaptchaData, 'tiny_captcha/tiny_captcha_data'
|
16
|
+
else
|
17
|
+
autoload :TinyCaptchaData, 'tiny_captcha/tiny_captcha_data_mongoid.rb'
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
autoload :Middleware, 'tiny_captcha/middleware'
|
22
|
+
|
23
|
+
mattr_accessor :image_size
|
24
|
+
@@image_size = "100x28"
|
25
|
+
|
26
|
+
mattr_accessor :length
|
27
|
+
@@length = 6
|
28
|
+
|
29
|
+
# 'embosed_silver',
|
30
|
+
# 'simply_red',
|
31
|
+
# 'simply_green',
|
32
|
+
# 'simply_blue',
|
33
|
+
# 'distorted_black',
|
34
|
+
# 'all_black',
|
35
|
+
# 'charcoal_grey',
|
36
|
+
# 'almost_invisible'
|
37
|
+
# 'random'
|
38
|
+
mattr_accessor :image_style
|
39
|
+
@@image_style = 'simply_blue'
|
40
|
+
|
41
|
+
# 'low', 'medium', 'high', 'random'
|
42
|
+
mattr_accessor :distortion
|
43
|
+
@@distortion = 'low'
|
44
|
+
|
45
|
+
# command path
|
46
|
+
mattr_accessor :image_magick_path
|
47
|
+
@@image_magick_path = ''
|
48
|
+
|
49
|
+
# tmp directory
|
50
|
+
mattr_accessor :tmp_path
|
51
|
+
@@tmp_path = nil
|
52
|
+
|
53
|
+
mattr_accessor :image_show_path
|
54
|
+
@@image_show_path = '/tiny_captcha/images/show'
|
55
|
+
|
56
|
+
def self.add_image_style(name, params = [])
|
57
|
+
::TinyCaptcha::ImageHelpers.image_styles.update(name.to_s => params)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.setup
|
61
|
+
yield self
|
62
|
+
end
|
4
63
|
end
|
64
|
+
|
65
|
+
I18n.load_path += Dir[Pathname.new(__FILE__).join('..', '..', 'config', 'locales', '**', '*.{rb,yml}').to_s]
|
66
|
+
|
67
|
+
require 'tiny_captcha/engine' if defined?(Rails)
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha #:nodoc
|
3
|
+
module ModelHelpers #:nodoc
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(SingletonMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
# To implement model based simple captcha use this method in the model as...
|
9
|
+
#
|
10
|
+
# class User < ActiveRecord::Base
|
11
|
+
#
|
12
|
+
# apply_tiny_captcha :message => "my customized message"
|
13
|
+
#
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Customize the error message by using :message, the default message is "Captcha did not match".
|
17
|
+
# As in the applications captcha is needed with a very few cases like signing up the new user, but
|
18
|
+
# not every time you need to authenticate the captcha with @user.save. So as to maintain simplicity
|
19
|
+
# here we have the explicit method to save the instace with captcha validation as...
|
20
|
+
#
|
21
|
+
# * to validate the instance
|
22
|
+
#
|
23
|
+
# @user.valid_with_captcha? # whene captcha validation is required.
|
24
|
+
#
|
25
|
+
# @user.valid? # when captcha validation is not required.
|
26
|
+
#
|
27
|
+
# * to save the instance
|
28
|
+
#
|
29
|
+
# @user.save_with_captcha # whene captcha validation is required.
|
30
|
+
#
|
31
|
+
# @user.save # when captcha validation is not required.
|
32
|
+
module SingletonMethods
|
33
|
+
def apply_tiny_captcha(options = {})
|
34
|
+
options = { :add_to_base => false }.merge(options)
|
35
|
+
|
36
|
+
class_attribute :tiny_captcha_options
|
37
|
+
self.tiny_captcha_options = options
|
38
|
+
|
39
|
+
unless self.is_a?(ClassMethods)
|
40
|
+
include InstanceMethods
|
41
|
+
extend ClassMethods
|
42
|
+
|
43
|
+
attr_accessor :captcha, :captcha_key
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module ClassMethods
|
49
|
+
end
|
50
|
+
|
51
|
+
module InstanceMethods
|
52
|
+
|
53
|
+
def valid_with_captcha?
|
54
|
+
[valid?, is_captcha_valid?].all?
|
55
|
+
end
|
56
|
+
|
57
|
+
def tiny_captcha_valid?
|
58
|
+
self.errors[:captcha].empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_captcha_valid?
|
62
|
+
return true if Rails.env.test?
|
63
|
+
|
64
|
+
if captcha && captcha.upcase.delete(" ") == ::TinyCaptcha::Utils::tiny_captcha_value(captcha_key)
|
65
|
+
::TinyCaptcha::Utils::tiny_captcha_passed!(captcha_key)
|
66
|
+
return true
|
67
|
+
else
|
68
|
+
message = tiny_captcha_options[:message] || I18n.t(
|
69
|
+
self.class.model_name.to_s.downcase, :scope => [:tiny_captcha, :message], :default => :default
|
70
|
+
)
|
71
|
+
|
72
|
+
# tiny_captcha_options[:add_to_base] ? errors.add(:base, message) : errors.add(:captcha, message)
|
73
|
+
errors.add(:captcha, message)
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def update_attributes_with_captcha *args
|
79
|
+
valid_with_captcha? && update_attributes(*args)
|
80
|
+
end
|
81
|
+
|
82
|
+
def save_with_captcha
|
83
|
+
# valid_with_captcha? && save(:validate => false)
|
84
|
+
valid_with_captcha? && self.save
|
85
|
+
end
|
86
|
+
|
87
|
+
def save_with_captcha!
|
88
|
+
valid_with_captcha? && self.save!
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha #:nodoc
|
3
|
+
module ControllerHelpers #:nodoc
|
4
|
+
def self.included base
|
5
|
+
base.class_eval do
|
6
|
+
include InstanceMethods
|
7
|
+
helper_method :generate_tiny_captcha_options
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
# This method is to validate the simple captcha in controller.
|
13
|
+
# It means when the captcha is controller based i.e. :object has not been passed to the method show_tiny_captcha.
|
14
|
+
#
|
15
|
+
# *Example*
|
16
|
+
#
|
17
|
+
# If you want to save an object say @user only if the captcha is validated then do like this in action...
|
18
|
+
#
|
19
|
+
# if tiny_captcha_valid?
|
20
|
+
# @user.save
|
21
|
+
# else
|
22
|
+
# flash[:notice] = "captcha did not match"
|
23
|
+
# redirect_to :action => "myaction"
|
24
|
+
# end
|
25
|
+
def tiny_captcha_valid?
|
26
|
+
return true if Rails.env.test?
|
27
|
+
|
28
|
+
if params[:captcha]
|
29
|
+
data = TinyCaptcha::Utils::tiny_captcha_value(params[:captcha_key] || session[:captcha])
|
30
|
+
result = data == params[:captcha].delete(" ").upcase
|
31
|
+
TinyCaptcha::Utils::tiny_captcha_passed!(session[:captcha]) if result
|
32
|
+
return result
|
33
|
+
else
|
34
|
+
return false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# 生成验证的信息
|
39
|
+
# options:
|
40
|
+
# - object
|
41
|
+
def generate_tiny_captcha_options *args
|
42
|
+
options = args.extract_options!
|
43
|
+
|
44
|
+
key = TinyCaptcha::Utils.generate_key_use_session(
|
45
|
+
session, options[:object]
|
46
|
+
)
|
47
|
+
|
48
|
+
{
|
49
|
+
:image_url => ::TinyCaptcha::Utils.generate_image_url(key, request.base_url, options),
|
50
|
+
:label => options[:label] || I18n.t('tiny_captcha.label'),
|
51
|
+
:captcha_key => ::TinyCaptcha::Utils.set_tiny_captcha_data(key, options),
|
52
|
+
:object => options[:object]
|
53
|
+
}
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/tiny_captcha/engine.rb
CHANGED
@@ -1,5 +1,32 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'rails'
|
3
|
+
require 'tiny_captcha'
|
4
|
+
|
1
5
|
module TinyCaptcha
|
2
6
|
class Engine < ::Rails::Engine
|
3
|
-
|
7
|
+
config.before_initialize do
|
8
|
+
ActiveSupport.on_load :active_record do
|
9
|
+
ActiveRecord::Base.send(:include, TinyCaptcha::ModelHelpers)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
config.after_initialize do
|
14
|
+
ActionView::Base.send(:include, TinyCaptcha::ViewHelper)
|
15
|
+
ActionView::Helpers::FormBuilder.send(:include, TinyCaptcha::FormBuilder)
|
16
|
+
|
17
|
+
ActionController::Base.send :include, ::TinyCaptcha::ControllerHelpers
|
18
|
+
|
19
|
+
if Object.const_defined?("Formtastic")
|
20
|
+
if Formtastic.const_defined?("Helpers")
|
21
|
+
Formtastic::Helpers::FormHelper.builder = TinyCaptcha::CustomFormBuilder
|
22
|
+
else
|
23
|
+
Formtastic::SemanticFormHelper.builder = TinyCaptcha::CustomFormBuilder
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
config.app_middleware.use TinyCaptcha::Middleware
|
4
29
|
end
|
5
30
|
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha
|
3
|
+
module FormBuilder
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, TinyCaptcha::ViewHelper)
|
6
|
+
base.send(:include, TinyCaptcha::FormBuilder::ClassMethods)
|
7
|
+
base.send(:include, ActionView::Helpers)
|
8
|
+
# base.send(:include, Sprockets::Helpers::RailsHelper)
|
9
|
+
# base.send(:include, Sprockets::Helpers::IsolatedHelper)
|
10
|
+
|
11
|
+
base.delegate :render, :session, :to => :template
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# Example:
|
16
|
+
# <% form_for :post, :url => posts_path do |form| %>
|
17
|
+
# ...
|
18
|
+
# <%= form.tiny_captcha :label => "Enter numbers.." %>
|
19
|
+
# <% end %>
|
20
|
+
#
|
21
|
+
def tiny_captcha(options = {})
|
22
|
+
options.update :object => @object_name
|
23
|
+
show_tiny_captcha(objectify_options(options))
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def template
|
29
|
+
@template
|
30
|
+
end
|
31
|
+
|
32
|
+
def tiny_captcha_field(options={})
|
33
|
+
html = {:autocomplete => 'off', :required => 'required', :value => ''}
|
34
|
+
html.merge!(options[:input_html] || {})
|
35
|
+
html[:placeholder] = options[:placeholder] || I18n.t('tiny_captcha.placeholder')
|
36
|
+
|
37
|
+
text_field(:captcha, html) + hidden_field(:captcha_key, {
|
38
|
+
:value => options[:captcha_key], :class => 'captcha-key'
|
39
|
+
})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha
|
3
|
+
class CustomFormBuilder < Formtastic::FormBuilder
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
def tiny_captcha_input(method, options)
|
8
|
+
options.update :object => sanitized_object_name
|
9
|
+
self.send(:show_tiny_captcha, options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'tempfile'
|
3
|
+
module TinyCaptcha #:nodoc
|
4
|
+
module ImageHelpers #:nodoc
|
5
|
+
|
6
|
+
mattr_accessor :image_styles
|
7
|
+
@@image_styles = {
|
8
|
+
'embosed_silver' => ['-fill darkblue', '-shade 20x60', '-background white'],
|
9
|
+
'simply_red' => ['-fill darkred', '-background white'],
|
10
|
+
'simply_green' => ['-fill darkgreen', '-background white'],
|
11
|
+
'simply_blue' => ['-fill darkblue', '-background white'],
|
12
|
+
'distorted_black' => ['-fill darkblue', '-edge 10', '-background white'],
|
13
|
+
'all_black' => ['-fill darkblue', '-edge 2', '-background white'],
|
14
|
+
'charcoal_grey' => ['-fill darkblue', '-charcoal 5', '-background white'],
|
15
|
+
'almost_invisible' => ['-fill red', '-solarize 50', '-background white']
|
16
|
+
}
|
17
|
+
|
18
|
+
DISTORTIONS = ['low', 'medium', 'high']
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
def image_params(key = 'simply_blue')
|
23
|
+
image_keys = @@image_styles.keys
|
24
|
+
|
25
|
+
style = begin
|
26
|
+
if key == 'random'
|
27
|
+
image_keys[rand(image_keys.length)]
|
28
|
+
else
|
29
|
+
image_keys.include?(key) ? key : 'simply_blue'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
@@image_styles[style]
|
34
|
+
end
|
35
|
+
|
36
|
+
def distortion(key='low')
|
37
|
+
key =
|
38
|
+
key == 'random' ?
|
39
|
+
DISTORTIONS[rand(DISTORTIONS.length)] :
|
40
|
+
DISTORTIONS.include?(key) ? key : 'low'
|
41
|
+
case key.to_s
|
42
|
+
when 'low' then return [2 + rand(2), 80 + rand(20)]
|
43
|
+
when 'medium' then return [4 + rand(2), 50 + rand(20)]
|
44
|
+
when 'high' then return [6 + rand(2), 30 + rand(20)]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if RUBY_VERSION < '1.9'
|
50
|
+
class Tempfile < ::Tempfile
|
51
|
+
# Replaces Tempfile's +make_tmpname+ with one that honors file extensions.
|
52
|
+
def make_tmpname(basename, n = 0)
|
53
|
+
extension = File.extname(basename)
|
54
|
+
sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n, extension)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def generate_tiny_captcha_image(tiny_captcha_key) #:nodoc
|
62
|
+
amplitude, frequency = ImageHelpers.distortion(TinyCaptcha.distortion)
|
63
|
+
text = Utils::tiny_captcha_value(tiny_captcha_key)
|
64
|
+
|
65
|
+
params = ImageHelpers.image_params(TinyCaptcha.image_style).dup
|
66
|
+
params << "-size #{TinyCaptcha.image_size}"
|
67
|
+
params << "-wave #{amplitude}x#{frequency}"
|
68
|
+
params << "-gravity \"Center\""
|
69
|
+
params << "-pointsize 22"
|
70
|
+
params << "-implode 0.2"
|
71
|
+
|
72
|
+
dst = Tempfile.new(RUBY_VERSION < '1.9' ? 'tiny_captcha.jpg' : ['tiny_captcha', '.jpg'], TinyCaptcha.tmp_path)
|
73
|
+
dst.binmode
|
74
|
+
|
75
|
+
params << "label:#{text} \"#{File.expand_path(dst.path)}\""
|
76
|
+
|
77
|
+
TinyCaptcha::Utils::run("convert", params.join(' '))
|
78
|
+
|
79
|
+
dst.close
|
80
|
+
|
81
|
+
File.expand_path(dst.path)
|
82
|
+
#dst
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha
|
3
|
+
class Middleware
|
4
|
+
include TinyCaptcha::ImageHelpers
|
5
|
+
|
6
|
+
DEFAULT_SEND_FILE_OPTIONS = {
|
7
|
+
:type => 'application/octet-stream'.freeze,
|
8
|
+
:disposition => 'attachment'.freeze,
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
CODE_KEY = 'code'
|
12
|
+
|
13
|
+
def initialize(app, options={})
|
14
|
+
@app = app
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env) # :nodoc:
|
19
|
+
if env["REQUEST_METHOD"] == "GET" && env['PATH_INFO'].start_with?(::TinyCaptcha.image_show_path)
|
20
|
+
# /tiny_captcha/images/show?code=abcdefg
|
21
|
+
make_image(env)
|
22
|
+
else
|
23
|
+
@app.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def render_json(env, data={}, headers={}, status=404)
|
30
|
+
body = []
|
31
|
+
body << data.to_json
|
32
|
+
headers['Content-Type'] = 'application/json'
|
33
|
+
[status, headers, body]
|
34
|
+
end
|
35
|
+
|
36
|
+
def make_image(env, headers = {}, status = 404)
|
37
|
+
request = Rack::Request.new(env)
|
38
|
+
code = request.params[CODE_KEY]
|
39
|
+
body = []
|
40
|
+
|
41
|
+
if !code.blank? && ::TinyCaptcha::Utils::tiny_captcha_value(code)
|
42
|
+
#status, headers, body = @app.call(env)
|
43
|
+
#status = 200
|
44
|
+
#body = generate_tiny_captcha_image(code)
|
45
|
+
#headers['Content-Type'] = 'image/jpeg'
|
46
|
+
|
47
|
+
return send_file(
|
48
|
+
generate_tiny_captcha_image(code),
|
49
|
+
:type => 'image/jpeg',
|
50
|
+
:disposition => 'inline',
|
51
|
+
:filename => 'tiny_captcha.jpg'
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
[status, headers, body]
|
56
|
+
end
|
57
|
+
|
58
|
+
def send_file(path, options = {})
|
59
|
+
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
|
60
|
+
|
61
|
+
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
|
62
|
+
|
63
|
+
status = options[:status] || 200
|
64
|
+
headers = {"Content-Disposition" => "#{options[:disposition]}; filename='#{options[:filename]}'", "Content-Type" => options[:type], 'Content-Transfer-Encoding' => 'binary', 'Cache-Control' => 'private'}
|
65
|
+
response_body = File.open(path, "rb")
|
66
|
+
|
67
|
+
[status, headers, response_body]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha
|
3
|
+
class TinyCaptchaData < ::ActiveRecord::Base
|
4
|
+
def self.rails3?
|
5
|
+
::ActiveRecord::VERSION::MAJOR == 3
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.rails4?
|
9
|
+
::ActiveRecord::VERSION::MAJOR == 4
|
10
|
+
end
|
11
|
+
|
12
|
+
if rails3? || rails4?
|
13
|
+
self.table_name = "tiny_captcha_data"
|
14
|
+
else
|
15
|
+
set_table_name "tiny_captcha_data"
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessible :key, :value
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def get_data(key)
|
22
|
+
data = find_by_key(key) || new(:key => key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove_data(key)
|
26
|
+
delete_all(["#{connection.quote_column_name(:key)} = ?", key])
|
27
|
+
clear_old_data(1.hour.ago)
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear_old_data(time = 1.hour.ago)
|
31
|
+
return unless Time === time
|
32
|
+
delete_all(["#{connection.quote_column_name(:updated_at)} < ?", time])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha
|
3
|
+
class TinyCaptchaData
|
4
|
+
include Mongoid::Document
|
5
|
+
include Mongoid::Timestamps
|
6
|
+
|
7
|
+
field :key, type: String
|
8
|
+
field :value, type: String
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def get_data(key)
|
12
|
+
data = where(:key => key).first || new(:key => key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove_data(key)
|
16
|
+
where(:key => key).delete_all
|
17
|
+
clear_old_data(1.hour.ago)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clear_old_data(time = 1.hour.ago)
|
21
|
+
return unless Time === time
|
22
|
+
where(:updated_at.lte => time).delete_all
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'digest/sha1'
|
3
|
+
|
4
|
+
module TinyCaptcha #:nodoc
|
5
|
+
module Utils #:nodoc
|
6
|
+
# Execute command with params and return output if exit status equal expected_outcodes
|
7
|
+
def self.run(cmd, params = "", expected_outcodes = 0)
|
8
|
+
command = %Q[#{cmd} #{params}].gsub(/\s+/, " ")
|
9
|
+
command = "#{command} 2>&1"
|
10
|
+
|
11
|
+
unless (image_magick_path = TinyCaptcha.image_magick_path).blank?
|
12
|
+
command = File.join(image_magick_path, command)
|
13
|
+
end
|
14
|
+
|
15
|
+
output = `#{command}`
|
16
|
+
|
17
|
+
unless [expected_outcodes].flatten.include?($?.exitstatus)
|
18
|
+
raise ::StandardError, "Error while running #{cmd}: #{output}"
|
19
|
+
end
|
20
|
+
|
21
|
+
output
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.tiny_captcha_value(key) #:nodoc
|
25
|
+
TinyCaptchaData.get_data(key).value rescue nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.tiny_captcha_passed!(key) #:nodoc
|
29
|
+
TinyCaptchaData.remove_data(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.generate_key(*args)
|
33
|
+
args << Time.now.to_s
|
34
|
+
Digest::SHA1.hexdigest(args.join)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.set_tiny_captcha_data(key, options={})
|
38
|
+
code_type = options[:code_type]
|
39
|
+
|
40
|
+
data = TinyCaptcha::TinyCaptchaData.get_data(key)
|
41
|
+
data.value = generate_tiny_captcha_data(code_type)
|
42
|
+
data.save
|
43
|
+
key
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.generate_tiny_captcha_data(code)
|
47
|
+
value = ''
|
48
|
+
|
49
|
+
case code
|
50
|
+
when 'numeric' then
|
51
|
+
::TinyCaptcha.length.times{value << (48 + rand(10)).chr}
|
52
|
+
else
|
53
|
+
::TinyCaptcha.length.times{value << (65 + rand(26)).chr}
|
54
|
+
end
|
55
|
+
|
56
|
+
return value
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.generate_image_url key, *args
|
60
|
+
options = args.extract_options!
|
61
|
+
|
62
|
+
defaults = {}
|
63
|
+
defaults[:time] = options[:time] || Time.now.to_i
|
64
|
+
|
65
|
+
base_url = args.first || ENV['RAILS_RELATIVE_URL_ROOT']
|
66
|
+
|
67
|
+
"#{base_url}#{::TinyCaptcha.image_show_path}?code=#{key}&#{defaults.to_query}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.generate_key_use_session session, *args
|
71
|
+
key_name = args.first
|
72
|
+
|
73
|
+
if key_name.nil?
|
74
|
+
session[:captcha] ||= TinyCaptcha::Utils.generate_key(session[:id].to_s, 'captcha')
|
75
|
+
else
|
76
|
+
TinyCaptcha::Utils.generate_key(session[:id].to_s, key_name)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/tiny_captcha/version.rb
CHANGED
@@ -0,0 +1,99 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module TinyCaptcha #:nodoc
|
3
|
+
module ViewHelper #:nodoc
|
4
|
+
|
5
|
+
# Tiny Captcha is a very simplified captcha.
|
6
|
+
#
|
7
|
+
# It can be used as a *Model* or a *Controller* based Captcha depending on what options
|
8
|
+
# we are passing to the method show_tiny_captcha.
|
9
|
+
#
|
10
|
+
# *show_tiny_captcha* method will return the image, the label and the text box.
|
11
|
+
# This method should be called from the view within your form as...
|
12
|
+
#
|
13
|
+
# <%= show_tiny_captcha %>
|
14
|
+
#
|
15
|
+
# The available options to pass to this method are
|
16
|
+
# * label
|
17
|
+
# * object
|
18
|
+
#
|
19
|
+
# <b>Label:</b>
|
20
|
+
#
|
21
|
+
# default label is "type the text from the image", it can be modified by passing :label as
|
22
|
+
#
|
23
|
+
# <%= show_tiny_captcha(:label => "new captcha label") %>.
|
24
|
+
#
|
25
|
+
# *Object*
|
26
|
+
#
|
27
|
+
# This option is needed to create a model based captcha.
|
28
|
+
# If this option is not provided, the captcha will be controller based and
|
29
|
+
# should be checked in controller's action just by calling the method tiny_captcha_valid?
|
30
|
+
#
|
31
|
+
# To make a model based captcha give this option as...
|
32
|
+
#
|
33
|
+
# <%= show_tiny_captcha(:object => "user") %>
|
34
|
+
# and also call the method apply_tiny_captcha in the model
|
35
|
+
# this will consider "user" as the object of the model class.
|
36
|
+
#
|
37
|
+
# *Examples*
|
38
|
+
# * controller based
|
39
|
+
# <%= show_tiny_captcha(:label => "Human Authentication: type the text from image above") %>
|
40
|
+
# * model based
|
41
|
+
# <%= show_tiny_captcha(:object => "person", :label => "Human Authentication: type the text from image above") %>
|
42
|
+
#
|
43
|
+
# Find more detailed examples with sample images here on my blog http://EXPRESSICA.com
|
44
|
+
#
|
45
|
+
# All Feedbacks/CommentS/Issues/Queries are welcome.
|
46
|
+
#
|
47
|
+
#
|
48
|
+
# eg. show_tiny_captcha :label => '', :captcha_key => '', :image_url => ''
|
49
|
+
def show_tiny_captcha(*args)
|
50
|
+
options = args.extract_options!
|
51
|
+
|
52
|
+
options[:captcha_key] ||= set_tiny_captcha_data(
|
53
|
+
(
|
54
|
+
args.first || tiny_captcha_key(options[:object])
|
55
|
+
),
|
56
|
+
options
|
57
|
+
)
|
58
|
+
|
59
|
+
key = options[:captcha_key]
|
60
|
+
|
61
|
+
defaults = {
|
62
|
+
:image => tiny_captcha_image(key, options),
|
63
|
+
:label => options[:label] || I18n.t('tiny_captcha.label'),
|
64
|
+
:field => tiny_captcha_field(options)
|
65
|
+
}
|
66
|
+
|
67
|
+
render :partial => 'tiny_captcha/tiny_captcha', :locals => { :tiny_captcha_options => defaults }
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def tiny_captcha_image(key, options = {})
|
73
|
+
url = options[:image_url] || ::TinyCaptcha::Utils.generate_image_url(key, options)
|
74
|
+
tag('img', :src => url, :alt => 'captcha', :class => 'captcha-image')
|
75
|
+
end
|
76
|
+
|
77
|
+
def tiny_captcha_field(options={})
|
78
|
+
html = {:autocomplete => 'off', :required => 'required'}
|
79
|
+
html.merge!(options[:input_html] || {})
|
80
|
+
html[:placeholder] = options[:placeholder] || I18n.t('tiny_captcha.placeholder')
|
81
|
+
|
82
|
+
if options[:object]
|
83
|
+
text_field(options[:object], :captcha, html.merge(:value => '')) +
|
84
|
+
hidden_field(options[:object], :captcha_key, {:value => options[:captcha_key], :class => 'captcha-key'})
|
85
|
+
else
|
86
|
+
text_field_tag(:captcha, nil, html) +
|
87
|
+
hidden_field_tag(:captcha_key, options[:captcha_key], :class => 'captcha-key')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def set_tiny_captcha_data(key, options={})
|
92
|
+
::TinyCaptcha::Utils.set_tiny_captcha_data key, options
|
93
|
+
end
|
94
|
+
|
95
|
+
def tiny_captcha_key(key_name = nil)
|
96
|
+
TinyCaptcha::Utils.generate_key_use_session session, key_name
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/test/dummy/config/boot.rb
CHANGED
data/test/dummy/config/routes.rb
CHANGED
data/test/test_helper.rb
CHANGED
data/test/tiny_captcha_test.rb
CHANGED
metadata
CHANGED
@@ -1,62 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tiny_captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- happy
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-01-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rails
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 4.0.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 4.0.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: tiny_util
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: sqlite3
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
description: Description of TinyCaptcha.
|
@@ -66,115 +59,125 @@ executables: []
|
|
66
59
|
extensions: []
|
67
60
|
extra_rdoc_files: []
|
68
61
|
files:
|
69
|
-
-
|
70
|
-
-
|
62
|
+
- MIT-LICENSE
|
63
|
+
- README.rdoc
|
64
|
+
- Rakefile
|
71
65
|
- app/assets/javascripts/tiny_captcha/application.js
|
72
66
|
- app/assets/stylesheets/tiny_captcha/application.css
|
67
|
+
- app/controllers/tiny_captcha/application_controller.rb
|
68
|
+
- app/controllers/tiny_captcha/images_controller.rb
|
73
69
|
- app/helpers/tiny_captcha/application_helper.rb
|
70
|
+
- app/views/layouts/tiny_captcha/application.html.erb
|
71
|
+
- config/locales/en/tiny_captcha.en.yml
|
72
|
+
- config/locales/zh-CN/tiny_captcha.zh-CN.yml
|
74
73
|
- config/routes.rb
|
75
|
-
- lib/
|
76
|
-
- lib/
|
74
|
+
- lib/generators/USAGE
|
75
|
+
- lib/generators/templates/migration.rb
|
76
|
+
- lib/generators/templates/partial.erb
|
77
|
+
- lib/generators/tiny_captcha_generator.rb
|
77
78
|
- lib/tasks/tiny_captcha_tasks.rake
|
78
79
|
- lib/tiny_captcha.rb
|
79
|
-
-
|
80
|
-
-
|
81
|
-
-
|
82
|
-
-
|
83
|
-
-
|
84
|
-
-
|
85
|
-
-
|
86
|
-
-
|
80
|
+
- lib/tiny_captcha/active_record.rb
|
81
|
+
- lib/tiny_captcha/controller.rb
|
82
|
+
- lib/tiny_captcha/engine.rb
|
83
|
+
- lib/tiny_captcha/form_builder.rb
|
84
|
+
- lib/tiny_captcha/formtastic.rb
|
85
|
+
- lib/tiny_captcha/image.rb
|
86
|
+
- lib/tiny_captcha/middleware.rb
|
87
|
+
- lib/tiny_captcha/tiny_captcha_data.rb
|
88
|
+
- lib/tiny_captcha/tiny_captcha_data_mongoid.rb
|
89
|
+
- lib/tiny_captcha/utils.rb
|
90
|
+
- lib/tiny_captcha/version.rb
|
91
|
+
- lib/tiny_captcha/view.rb
|
87
92
|
- test/dummy/README.rdoc
|
88
|
-
- test/dummy/config.ru
|
89
93
|
- test/dummy/Rakefile
|
90
|
-
- test/dummy/app/views/layouts/application.html.erb
|
91
|
-
- test/dummy/app/controllers/application_controller.rb
|
92
94
|
- test/dummy/app/assets/javascripts/application.js
|
93
95
|
- test/dummy/app/assets/stylesheets/application.css
|
96
|
+
- test/dummy/app/controllers/application_controller.rb
|
94
97
|
- test/dummy/app/helpers/application_helper.rb
|
95
|
-
- test/dummy/
|
96
|
-
- test/dummy/
|
97
|
-
- test/dummy/
|
98
|
-
- test/dummy/
|
99
|
-
- test/dummy/config
|
100
|
-
- test/dummy/config/
|
101
|
-
- test/dummy/config/
|
98
|
+
- test/dummy/app/views/layouts/application.html.erb
|
99
|
+
- test/dummy/bin/bundle
|
100
|
+
- test/dummy/bin/rails
|
101
|
+
- test/dummy/bin/rake
|
102
|
+
- test/dummy/config.ru
|
103
|
+
- test/dummy/config/application.rb
|
104
|
+
- test/dummy/config/boot.rb
|
105
|
+
- test/dummy/config/database.yml
|
106
|
+
- test/dummy/config/environment.rb
|
102
107
|
- test/dummy/config/environments/development.rb
|
103
|
-
- test/dummy/config/
|
108
|
+
- test/dummy/config/environments/production.rb
|
109
|
+
- test/dummy/config/environments/test.rb
|
104
110
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
105
|
-
- test/dummy/config/initializers/mime_types.rb
|
106
|
-
- test/dummy/config/initializers/inflections.rb
|
107
111
|
- test/dummy/config/initializers/filter_parameter_logging.rb
|
108
|
-
- test/dummy/config/initializers/
|
112
|
+
- test/dummy/config/initializers/inflections.rb
|
113
|
+
- test/dummy/config/initializers/mime_types.rb
|
114
|
+
- test/dummy/config/initializers/secret_token.rb
|
109
115
|
- test/dummy/config/initializers/session_store.rb
|
116
|
+
- test/dummy/config/initializers/wrap_parameters.rb
|
117
|
+
- test/dummy/config/locales/en.yml
|
110
118
|
- test/dummy/config/routes.rb
|
111
|
-
- test/dummy/
|
112
|
-
- test/dummy/
|
113
|
-
- test/dummy/
|
114
|
-
- test/dummy/
|
119
|
+
- test/dummy/public/404.html
|
120
|
+
- test/dummy/public/422.html
|
121
|
+
- test/dummy/public/500.html
|
122
|
+
- test/dummy/public/favicon.ico
|
115
123
|
- test/integration/navigation_test.rb
|
124
|
+
- test/test_helper.rb
|
125
|
+
- test/tiny_captcha_test.rb
|
116
126
|
homepage: http://github.com/xiuxian123/tiny_passport
|
117
127
|
licenses: []
|
128
|
+
metadata: {}
|
118
129
|
post_install_message:
|
119
130
|
rdoc_options: []
|
120
131
|
require_paths:
|
121
132
|
- lib
|
122
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
134
|
requirements:
|
125
|
-
- -
|
135
|
+
- - ">="
|
126
136
|
- !ruby/object:Gem::Version
|
127
137
|
version: '0'
|
128
|
-
segments:
|
129
|
-
- 0
|
130
|
-
hash: 965235565
|
131
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
139
|
requirements:
|
134
|
-
- -
|
140
|
+
- - ">="
|
135
141
|
- !ruby/object:Gem::Version
|
136
142
|
version: '0'
|
137
|
-
segments:
|
138
|
-
- 0
|
139
|
-
hash: 965235565
|
140
143
|
requirements: []
|
141
144
|
rubyforge_project:
|
142
|
-
rubygems_version:
|
145
|
+
rubygems_version: 2.2.1
|
143
146
|
signing_key:
|
144
|
-
specification_version:
|
147
|
+
specification_version: 4
|
145
148
|
summary: Summary of TinyCaptcha.
|
146
149
|
test_files:
|
147
|
-
- test/tiny_captcha_test.rb
|
148
|
-
- test/test_helper.rb
|
149
|
-
- test/dummy/bin/bundle
|
150
|
-
- test/dummy/bin/rake
|
151
|
-
- test/dummy/bin/rails
|
152
|
-
- test/dummy/README.rdoc
|
153
|
-
- test/dummy/config.ru
|
154
|
-
- test/dummy/Rakefile
|
155
|
-
- test/dummy/app/views/layouts/application.html.erb
|
156
|
-
- test/dummy/app/controllers/application_controller.rb
|
157
150
|
- test/dummy/app/assets/javascripts/application.js
|
158
151
|
- test/dummy/app/assets/stylesheets/application.css
|
152
|
+
- test/dummy/app/controllers/application_controller.rb
|
159
153
|
- test/dummy/app/helpers/application_helper.rb
|
160
|
-
- test/dummy/
|
161
|
-
- test/dummy/
|
162
|
-
- test/dummy/
|
163
|
-
- test/dummy/
|
164
|
-
- test/dummy/config/
|
165
|
-
- test/dummy/config/
|
166
|
-
- test/dummy/config/
|
154
|
+
- test/dummy/app/views/layouts/application.html.erb
|
155
|
+
- test/dummy/bin/bundle
|
156
|
+
- test/dummy/bin/rails
|
157
|
+
- test/dummy/bin/rake
|
158
|
+
- test/dummy/config/application.rb
|
159
|
+
- test/dummy/config/boot.rb
|
160
|
+
- test/dummy/config/database.yml
|
161
|
+
- test/dummy/config/environment.rb
|
167
162
|
- test/dummy/config/environments/development.rb
|
168
|
-
- test/dummy/config/
|
163
|
+
- test/dummy/config/environments/production.rb
|
164
|
+
- test/dummy/config/environments/test.rb
|
169
165
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
170
|
-
- test/dummy/config/initializers/mime_types.rb
|
171
|
-
- test/dummy/config/initializers/inflections.rb
|
172
166
|
- test/dummy/config/initializers/filter_parameter_logging.rb
|
173
|
-
- test/dummy/config/initializers/
|
167
|
+
- test/dummy/config/initializers/inflections.rb
|
168
|
+
- test/dummy/config/initializers/mime_types.rb
|
169
|
+
- test/dummy/config/initializers/secret_token.rb
|
174
170
|
- test/dummy/config/initializers/session_store.rb
|
171
|
+
- test/dummy/config/initializers/wrap_parameters.rb
|
172
|
+
- test/dummy/config/locales/en.yml
|
175
173
|
- test/dummy/config/routes.rb
|
176
|
-
- test/dummy/config
|
177
|
-
- test/dummy/
|
178
|
-
- test/dummy/
|
179
|
-
- test/dummy/
|
174
|
+
- test/dummy/config.ru
|
175
|
+
- test/dummy/public/404.html
|
176
|
+
- test/dummy/public/422.html
|
177
|
+
- test/dummy/public/500.html
|
178
|
+
- test/dummy/public/favicon.ico
|
179
|
+
- test/dummy/Rakefile
|
180
|
+
- test/dummy/README.rdoc
|
180
181
|
- test/integration/navigation_test.rb
|
182
|
+
- test/test_helper.rb
|
183
|
+
- test/tiny_captcha_test.rb
|