easy_captcha_rails 0.6.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/LICENSE +23 -0
- data/README.md +24 -0
- data/easy_captcha-0.6.5.patch +24 -0
- data/easy_captcha_rails.gemspec +34 -0
- data/init.rb +1 -0
- data/lib/easy_captcha/captcha.rb +26 -0
- data/lib/easy_captcha/captcha_controller.rb +22 -0
- data/lib/easy_captcha/controller_helpers.rb +93 -0
- data/lib/easy_captcha/espeak.rb +79 -0
- data/lib/easy_captcha/generator/base.rb +19 -0
- data/lib/easy_captcha/generator/default.rb +119 -0
- data/lib/easy_captcha/generator.rb +8 -0
- data/lib/easy_captcha/model_helpers.rb +29 -0
- data/lib/easy_captcha/routes.rb +10 -0
- data/lib/easy_captcha/version.rb +3 -0
- data/lib/easy_captcha/view_helpers.rb +11 -0
- data/lib/easy_captcha.rb +131 -0
- data/lib/generators/easy_captcha/install_generator.rb +23 -0
- data/lib/generators/templates/easy_captcha.rb +66 -0
- data/resources/captcha.ttf +0 -0
- metadata +95 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2b4c250c05bf457fa0af1e4ff8990def2c1cb4af909db64a64c8dfd3c0dee30f
|
4
|
+
data.tar.gz: 3be88f8158042815abb41b9e9374ec35f83685aab9a979ba8775d3c9f7d1e876
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bb7a71989173f327ac81433f19224d357850a225eb8ee1e7928b533b1a3cc83496b7238f227ba49c3997f85fa7d9b10f15936b8534be9929405b9ef211ab7ded
|
7
|
+
data.tar.gz: e1405291bb13511a00ee020b3a8786672da84fd8844b86375f6adbfc8f284e693ba709f44a6ba3bfcfd6b4f77444efc11979f27275d8f6183a383ffc227e6da2
|
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2021 Huitao Chen
|
4
|
+
Copyright (c) 2010 Marco Scholl
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Captcha-Plugin for Rails 5+
|
2
|
+
|
3
|
+
PLEASE DO NOT USE THIS GEM.
|
4
|
+
|
5
|
+
USE MODERN IMAGE LIBS OF RAILS.
|
6
|
+
|
7
|
+
This project is based on <https://github.com/phatworx/easy_captcha>.
|
8
|
+
|
9
|
+
This gem is for an ancient project.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
add to Gemfile
|
14
|
+
```
|
15
|
+
gem 'easy_captcha_rails', require: 'easy_captcha'
|
16
|
+
```
|
17
|
+
|
18
|
+
## Patch original gem without install this
|
19
|
+
|
20
|
+
use the "easy_captcha-0.6.5.patch" file to patch the original gem.
|
21
|
+
|
22
|
+
## License
|
23
|
+
|
24
|
+
This project is released under the [MIT license](LICENSE).
|
@@ -0,0 +1,24 @@
|
|
1
|
+
diff -Naur easy_captcha-0.6.5.orig/lib/easy_captcha/captcha_controller.rb easy_captcha-0.6.5/lib/easy_captcha/captcha_controller.rb
|
2
|
+
--- easy_captcha-0.6.5.orig/lib/easy_captcha/captcha_controller.rb 2021-10-28 13:31:54.126630362 +0800
|
3
|
+
+++ easy_captcha-0.6.5/lib/easy_captcha/captcha_controller.rb 2021-10-28 13:29:57.245066835 +0800
|
4
|
+
@@ -1,7 +1,7 @@
|
5
|
+
module EasyCaptcha
|
6
|
+
# captcha controller
|
7
|
+
class CaptchaController < ActionController::Base
|
8
|
+
- before_filter :overwrite_cache_control
|
9
|
+
+ before_action :overwrite_cache_control
|
10
|
+
# captcha action send the generated image to browser
|
11
|
+
def captcha
|
12
|
+
if params[:format] == "wav" and EasyCaptcha.espeak?
|
13
|
+
diff -Naur easy_captcha-0.6.5.orig/lib/easy_captcha/generator/default.rb easy_captcha-0.6.5/lib/easy_captcha/generator/default.rb
|
14
|
+
--- easy_captcha-0.6.5.orig/lib/easy_captcha/generator/default.rb 2021-10-28 13:31:54.130630415 +0800
|
15
|
+
+++ easy_captcha-0.6.5/lib/easy_captcha/generator/default.rb 2021-10-28 11:17:44.000000000 +0800
|
16
|
+
@@ -61,7 +61,7 @@
|
17
|
+
require 'rmagick' unless defined?(Magick)
|
18
|
+
|
19
|
+
config = self
|
20
|
+
- canvas = Magick::Image.new(EasyCaptcha.image_width, EasyCaptcha.image_height) do |variable|
|
21
|
+
+ canvas = Magick::Image.new(EasyCaptcha.image_width, EasyCaptcha.image_height) do
|
22
|
+
self.background_color = config.image_background_color unless config.image_background_color.nil?
|
23
|
+
self.background_color = 'none' if config.background_image.present?
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "easy_captcha/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "easy_captcha_rails"
|
7
|
+
s.version = EasyCaptcha::VERSION
|
8
|
+
|
9
|
+
s.required_ruby_version = ">= 2.2.2"
|
10
|
+
s.required_rubygems_version = ">= 1.8.11"
|
11
|
+
s.authors = ["Huitao Chen", "Marco Scholl", "Alexander Dreher"]
|
12
|
+
s.date = "2021-10-28"
|
13
|
+
s.description = "Captcha-Plugin for Rails"
|
14
|
+
s.email = "h980501427@163.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
|
21
|
+
s.homepage = "https://github.com/chenhuitao/easy_captcha_rails"
|
22
|
+
s.licenses = ["MIT"]
|
23
|
+
s.summary = "Captcha-Plugin for Rails 5+"
|
24
|
+
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
|
27
|
+
s.add_dependency("rails", [">= 5.0.0"])
|
28
|
+
|
29
|
+
if defined?(PLATFORM) && PLATFORM == "java"
|
30
|
+
s.add_runtime_dependency("rmagick4j", ">= 0.3.7")
|
31
|
+
else
|
32
|
+
s.add_runtime_dependency("rmagick", ">= 2.13.1")
|
33
|
+
end
|
34
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'easy_captcha'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module EasyCaptcha
|
3
|
+
# captcha generation class
|
4
|
+
class Captcha
|
5
|
+
# code for captcha generation
|
6
|
+
attr_reader :code
|
7
|
+
# blob of generated captcha image
|
8
|
+
attr_reader :image
|
9
|
+
|
10
|
+
# generate captcha by code
|
11
|
+
def initialize code
|
12
|
+
@code = code
|
13
|
+
generate_captcha
|
14
|
+
end
|
15
|
+
|
16
|
+
def inspect #:nodoc:
|
17
|
+
"<EasyCaptcha::Captcha @code=#{code}>"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def generate_captcha #:nodoc:
|
23
|
+
@image = EasyCaptcha.generator.generate(@code)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
# captcha controller
|
3
|
+
class CaptchaController < ActionController::Base
|
4
|
+
before_action :overwrite_cache_control
|
5
|
+
# captcha action send the generated image to browser
|
6
|
+
def captcha
|
7
|
+
if params[:format] == "wav" and EasyCaptcha.espeak?
|
8
|
+
send_data generate_speech_captcha, :disposition => 'inline', :type => 'audio/wav'
|
9
|
+
else
|
10
|
+
send_data generate_captcha, :disposition => 'inline', :type => 'image/png'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
# Overwrite cache control for Samsung Galaxy S3 (remove no-store)
|
16
|
+
def overwrite_cache_control
|
17
|
+
response.headers["Cache-Control"] = "no-cache, max-age=0, must-revalidate"
|
18
|
+
response.headers["Pragma"] = "no-cache"
|
19
|
+
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
# helper class for ActionController
|
3
|
+
module ControllerHelpers
|
4
|
+
|
5
|
+
def self.included(base) #:nodoc:
|
6
|
+
base.class_eval do
|
7
|
+
helper_method :valid_captcha?, :captcha_valid?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# generate captcha image and return it as blob
|
12
|
+
def generate_captcha
|
13
|
+
if EasyCaptcha.cache
|
14
|
+
# create cache dir
|
15
|
+
FileUtils.mkdir_p(EasyCaptcha.cache_temp_dir)
|
16
|
+
|
17
|
+
# select all generated captchas from cache
|
18
|
+
files = Dir.glob(EasyCaptcha.cache_temp_dir + "*.png")
|
19
|
+
|
20
|
+
unless files.size < EasyCaptcha.cache_size
|
21
|
+
file = File.open(files.at(Kernel.rand(files.size)))
|
22
|
+
session[:captcha] = File.basename(file.path, '.*')
|
23
|
+
|
24
|
+
if file.mtime < EasyCaptcha.cache_expire.ago
|
25
|
+
File.unlink(file.path)
|
26
|
+
# remove speech version
|
27
|
+
File.unlink(file.path.gsub(/png\z/, "wav")) if File.exists?(file.path.gsub(/png\z/, "wav"))
|
28
|
+
else
|
29
|
+
return file.readlines.join
|
30
|
+
end
|
31
|
+
end
|
32
|
+
generated_code = generate_captcha_code
|
33
|
+
image = Captcha.new(generated_code).image
|
34
|
+
|
35
|
+
# write captcha for caching
|
36
|
+
File.open(captcha_cache_path(generated_code), 'w') { |f| f.write image }
|
37
|
+
|
38
|
+
# write speech file if u create a new captcha image
|
39
|
+
EasyCaptcha.espeak.generate(generated_code, speech_captcha_cache_path(generated_code)) if EasyCaptcha.espeak?
|
40
|
+
|
41
|
+
# return image
|
42
|
+
image
|
43
|
+
else
|
44
|
+
Captcha.new(generate_captcha_code).image
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# generate speech by captcha from session
|
49
|
+
def generate_speech_captcha
|
50
|
+
raise RuntimeError, "espeak disabled" unless EasyCaptcha.espeak?
|
51
|
+
if EasyCaptcha.cache
|
52
|
+
File.read(speech_captcha_cache_path(current_captcha_code))
|
53
|
+
else
|
54
|
+
wav_file = Tempfile.new("#{current_captcha_code}.wav")
|
55
|
+
EasyCaptcha.espeak.generate(current_captcha_code, wav_file.path)
|
56
|
+
File.read(wav_file.path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# return cache path of captcha image
|
61
|
+
def captcha_cache_path(code)
|
62
|
+
"#{EasyCaptcha.cache_temp_dir}/#{code}.png"
|
63
|
+
end
|
64
|
+
|
65
|
+
# return cache path of speech captcha
|
66
|
+
def speech_captcha_cache_path(code)
|
67
|
+
"#{EasyCaptcha.cache_temp_dir}/#{code}.wav"
|
68
|
+
end
|
69
|
+
|
70
|
+
# current active captcha from session
|
71
|
+
def current_captcha_code
|
72
|
+
session[:captcha]
|
73
|
+
end
|
74
|
+
|
75
|
+
# generate captcha code, save in session and return
|
76
|
+
def generate_captcha_code
|
77
|
+
session[:captcha] = EasyCaptcha.length.times.collect { EasyCaptcha.chars[rand(EasyCaptcha.chars.size)] }.join
|
78
|
+
end
|
79
|
+
|
80
|
+
# validate given captcha code and re
|
81
|
+
def captcha_valid?(code)
|
82
|
+
return false if session[:captcha].blank? or code.blank?
|
83
|
+
session[:captcha].to_s.upcase == code.to_s.upcase
|
84
|
+
end
|
85
|
+
alias_method :valid_captcha?, :captcha_valid?
|
86
|
+
|
87
|
+
# reset the captcha code in session for security after each request
|
88
|
+
def reset_last_captcha_code!
|
89
|
+
session.delete(:captcha)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
# espeak wrapper
|
3
|
+
class Espeak
|
4
|
+
|
5
|
+
# generator for captcha images
|
6
|
+
def initialize(&block)
|
7
|
+
defaults
|
8
|
+
yield self if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
# set default values
|
12
|
+
def defaults
|
13
|
+
@amplitude = 80..120
|
14
|
+
@pitch = 30..70
|
15
|
+
@gap = 80
|
16
|
+
@voice = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_writer :amplitude, :pitch, :gap, :voice
|
20
|
+
|
21
|
+
# return amplitude
|
22
|
+
def amplitude
|
23
|
+
if @amplitude.is_a? Range
|
24
|
+
@amplitude.to_a.sort_by { rand }.first
|
25
|
+
else
|
26
|
+
@amplitude.to_i
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# return amplitude
|
31
|
+
def pitch
|
32
|
+
if @pitch.is_a? Range
|
33
|
+
@pitch.to_a.sort_by { rand }.first
|
34
|
+
else
|
35
|
+
@pitch.to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def gap
|
40
|
+
@gap.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
def voice
|
44
|
+
if @voice.is_a? Array
|
45
|
+
v = @voice.sort_by { rand }.first
|
46
|
+
else
|
47
|
+
v = @voice
|
48
|
+
end
|
49
|
+
|
50
|
+
v.try :gsub, /[^A-Za-z0-9\-\+]/, ""
|
51
|
+
end
|
52
|
+
|
53
|
+
# generate wav file by captcha
|
54
|
+
def generate(captcha, wav_file)
|
55
|
+
# get code
|
56
|
+
if captcha.is_a? Captcha
|
57
|
+
code = captcha.code
|
58
|
+
elsif captcha.is_a? String
|
59
|
+
code = captcha
|
60
|
+
else
|
61
|
+
raise ArgumentError, "invalid captcha"
|
62
|
+
end
|
63
|
+
|
64
|
+
# add spaces
|
65
|
+
code = code.each_char.to_a.join(" ")
|
66
|
+
|
67
|
+
cmd = "espeak -g 10"
|
68
|
+
cmd << " -a #{amplitude}" unless @amplitude.nil?
|
69
|
+
cmd << " -p #{pitch}" unless @pitch.nil?
|
70
|
+
cmd << " -g #{gap}" unless @gap.nil?
|
71
|
+
cmd << " -v '#{voice}'" unless @voice.nil?
|
72
|
+
cmd << " -w #{wav_file} '#{code}'"
|
73
|
+
|
74
|
+
%x{#{cmd}}
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
module Generator
|
3
|
+
|
4
|
+
# base class for generators
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# generator for captcha images
|
8
|
+
def initialize(&block)
|
9
|
+
defaults
|
10
|
+
yield self if block_given?
|
11
|
+
end
|
12
|
+
|
13
|
+
# default values for generator
|
14
|
+
def defaults
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module EasyCaptcha
|
4
|
+
module Generator
|
5
|
+
|
6
|
+
# default generator
|
7
|
+
class Default < Base
|
8
|
+
|
9
|
+
# set default values
|
10
|
+
def defaults
|
11
|
+
@font_size = 24
|
12
|
+
@font_fill_color = '#333333'
|
13
|
+
@font = File.expand_path('../../../../resources/captcha.ttf', __FILE__)
|
14
|
+
@font_stroke = '#000000'
|
15
|
+
@font_stroke_color = 0
|
16
|
+
@image_background_color = '#FFFFFF'
|
17
|
+
@sketch = true
|
18
|
+
@sketch_radius = 3
|
19
|
+
@sketch_sigma = 1
|
20
|
+
@wave = true
|
21
|
+
@wave_length = (60..100)
|
22
|
+
@wave_amplitude = (3..5)
|
23
|
+
@implode = 0.05
|
24
|
+
@blur = true
|
25
|
+
@blur_radius = 1
|
26
|
+
@blur_sigma = 2
|
27
|
+
end
|
28
|
+
|
29
|
+
# Font
|
30
|
+
attr_accessor :font_size, :font_fill_color, :font, :font_family, :font_stroke, :font_stroke_color
|
31
|
+
|
32
|
+
# Background
|
33
|
+
attr_accessor :image_background_color, :background_image
|
34
|
+
|
35
|
+
# Sketch
|
36
|
+
attr_accessor :sketch, :sketch_radius, :sketch_sigma
|
37
|
+
|
38
|
+
# Wave
|
39
|
+
attr_accessor :wave, :wave_length, :wave_amplitude
|
40
|
+
|
41
|
+
# Implode
|
42
|
+
attr_accessor :implode
|
43
|
+
|
44
|
+
# Gaussian Blur
|
45
|
+
attr_accessor :blur, :blur_radius, :blur_sigma
|
46
|
+
|
47
|
+
def sketch? #:nodoc:
|
48
|
+
@sketch
|
49
|
+
end
|
50
|
+
|
51
|
+
def wave? #:nodoc:
|
52
|
+
@wave
|
53
|
+
end
|
54
|
+
|
55
|
+
def blur? #:nodoc:
|
56
|
+
@blur
|
57
|
+
end
|
58
|
+
|
59
|
+
# generate image
|
60
|
+
def generate(code)
|
61
|
+
require 'rmagick' unless defined?(Magick)
|
62
|
+
|
63
|
+
config = self
|
64
|
+
canvas = Magick::Image.new(EasyCaptcha.image_width, EasyCaptcha.image_height) do
|
65
|
+
self.background_color = config.image_background_color unless config.image_background_color.nil?
|
66
|
+
self.background_color = 'none' if config.background_image.present?
|
67
|
+
end
|
68
|
+
|
69
|
+
# Render the text in the image
|
70
|
+
canvas.annotate(Magick::Draw.new, 0, 0, 0, 0, code) {
|
71
|
+
self.gravity = Magick::CenterGravity
|
72
|
+
self.font = config.font
|
73
|
+
self.font_weight = Magick::LighterWeight
|
74
|
+
self.fill = config.font_fill_color
|
75
|
+
if config.font_stroke.to_i > 0
|
76
|
+
self.stroke = config.font_stroke_color
|
77
|
+
self.stroke_width = config.font_stroke
|
78
|
+
end
|
79
|
+
self.pointsize = config.font_size
|
80
|
+
}
|
81
|
+
|
82
|
+
# Blur
|
83
|
+
canvas = canvas.blur_image(config.blur_radius, config.blur_sigma) if config.blur?
|
84
|
+
|
85
|
+
# Wave
|
86
|
+
w = config.wave_length
|
87
|
+
a = config.wave_amplitude
|
88
|
+
canvas = canvas.wave(rand(a.last - a.first) + a.first, rand(w.last - w.first) + w.first) if config.wave?
|
89
|
+
|
90
|
+
# Sketch
|
91
|
+
canvas = canvas.sketch(config.sketch_radius, config.sketch_sigma, rand(180)) if config.sketch?
|
92
|
+
|
93
|
+
# Implode
|
94
|
+
canvas = canvas.implode(config.implode.to_f) if config.implode.is_a? Float
|
95
|
+
|
96
|
+
# Crop image because to big after waveing
|
97
|
+
canvas = canvas.crop(Magick::CenterGravity, EasyCaptcha.image_width, EasyCaptcha.image_height)
|
98
|
+
|
99
|
+
|
100
|
+
# Combine images if background image is present
|
101
|
+
if config.background_image.present?
|
102
|
+
background = Magick::Image.read(config.background_image).first
|
103
|
+
background.composite!(canvas, Magick::CenterGravity, Magick::OverCompositeOp)
|
104
|
+
|
105
|
+
image = background.to_blob { self.format = 'PNG' }
|
106
|
+
else
|
107
|
+
image = canvas.to_blob { self.format = 'PNG' }
|
108
|
+
end
|
109
|
+
|
110
|
+
# ruby-1.9
|
111
|
+
image = image.force_encoding 'UTF-8' if image.respond_to? :force_encoding
|
112
|
+
|
113
|
+
canvas.destroy!
|
114
|
+
image
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
module ModelHelpers #:nodoc:
|
3
|
+
# helper class for ActiveRecord
|
4
|
+
def self.included(base) #:nodoc:
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods #:nodoc:
|
9
|
+
# to activate model captcha validation
|
10
|
+
def acts_as_easy_captcha
|
11
|
+
include InstanceMethods
|
12
|
+
attr_writer :captcha, :captcha_verification
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods #:nodoc:
|
17
|
+
|
18
|
+
def captcha #:nodoc:
|
19
|
+
""
|
20
|
+
end
|
21
|
+
|
22
|
+
# validate captcha
|
23
|
+
def captcha_valid?
|
24
|
+
errors.add(:captcha, :invalid) if @captcha.blank? or @captcha_verification.blank? or @captcha.to_s.upcase != @captcha_verification.to_s.upcase
|
25
|
+
end
|
26
|
+
alias_method :valid_captcha?, :captcha_valid?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
# helper class for ActionView
|
3
|
+
module ViewHelpers
|
4
|
+
# generate an image_tag for captcha image
|
5
|
+
def captcha_tag(*args)
|
6
|
+
options = { :alt => 'captcha', :width => EasyCaptcha.image_width, :height => EasyCaptcha.image_height }
|
7
|
+
options.merge! args.extract_options!
|
8
|
+
image_tag(captcha_url(:i => Time.now.to_i), options)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/easy_captcha.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'active_record'
|
4
|
+
require 'active_support'
|
5
|
+
|
6
|
+
# Captcha-Plugin for Rails
|
7
|
+
module EasyCaptcha
|
8
|
+
autoload :Espeak, 'easy_captcha/espeak'
|
9
|
+
autoload :Captcha, 'easy_captcha/captcha'
|
10
|
+
autoload :CaptchaController, 'easy_captcha/captcha_controller'
|
11
|
+
autoload :ModelHelpers, 'easy_captcha/model_helpers'
|
12
|
+
autoload :ViewHelpers, 'easy_captcha/view_helpers'
|
13
|
+
autoload :ControllerHelpers, 'easy_captcha/controller_helpers'
|
14
|
+
autoload :Generator, 'easy_captcha/generator'
|
15
|
+
|
16
|
+
# Cache
|
17
|
+
mattr_accessor :cache
|
18
|
+
@@cache = false
|
19
|
+
|
20
|
+
# Cache temp
|
21
|
+
mattr_accessor :cache_temp_dir
|
22
|
+
@@cache_temp_dir = nil
|
23
|
+
|
24
|
+
# Cache size
|
25
|
+
mattr_accessor :cache_size
|
26
|
+
@@cache_size = 500
|
27
|
+
|
28
|
+
# Cache expire
|
29
|
+
mattr_accessor :cache_expire
|
30
|
+
@@cache_expire = nil
|
31
|
+
|
32
|
+
# Chars
|
33
|
+
mattr_accessor :chars
|
34
|
+
@@chars = %w(2 3 4 5 6 7 9 A C D E F G H J K L M N P Q R S T U X Y Z)
|
35
|
+
|
36
|
+
# Length
|
37
|
+
mattr_accessor :length
|
38
|
+
@@length = 6
|
39
|
+
|
40
|
+
# Length
|
41
|
+
mattr_accessor :image_width, :image_height
|
42
|
+
@@image_width = 140
|
43
|
+
@@image_height = 40
|
44
|
+
|
45
|
+
class << self
|
46
|
+
# to configure easy_captcha
|
47
|
+
# for a sample look the readme.rdoc file
|
48
|
+
def setup
|
49
|
+
yield self
|
50
|
+
end
|
51
|
+
|
52
|
+
def cache? #:nodoc:
|
53
|
+
cache
|
54
|
+
end
|
55
|
+
|
56
|
+
# select generator and configure this
|
57
|
+
def generator(generator = nil, &block)
|
58
|
+
if generator.nil?
|
59
|
+
@generator
|
60
|
+
else
|
61
|
+
generator = generator.to_s if generator.is_a? Symbol
|
62
|
+
|
63
|
+
if generator.is_a? String
|
64
|
+
generator.gsub!(/^[a-z]|\s+[a-z]/) { |a| a.upcase }
|
65
|
+
generator = "EasyCaptcha::Generator::#{generator}".constantize
|
66
|
+
end
|
67
|
+
|
68
|
+
@generator = generator.new &block
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def espeak=(state)
|
73
|
+
if state === true
|
74
|
+
@espeak = Espeak.new
|
75
|
+
else
|
76
|
+
@espeak = false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def espeak(&block)
|
81
|
+
if block_given?
|
82
|
+
@espeak = Espeak.new &block
|
83
|
+
else
|
84
|
+
@espeak ||= false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def espeak?
|
89
|
+
not espeak === false
|
90
|
+
end
|
91
|
+
|
92
|
+
# depracated
|
93
|
+
def method_missing name, *args
|
94
|
+
name = name.to_s # fix for jruby
|
95
|
+
depracations = [
|
96
|
+
:font_size, :font_fill_color, :font_family, :font_stroke, :font_stroke_color,
|
97
|
+
:image_background_color, :sketch, :sketch_radius, :sketch_sigma, :wave,
|
98
|
+
:wave_length, :wave_amplitude, :implode, :blur, :blur_radius, :blur_sigma
|
99
|
+
]
|
100
|
+
|
101
|
+
if depracations.include? name[0..-2].to_sym or depracations.include? name.to_sym
|
102
|
+
ActiveSupport::Deprecation.warn "EasyCaptcha.#{name} is deprecated."
|
103
|
+
if name[-1,1] == '='
|
104
|
+
self.generator.send(name, args.first)
|
105
|
+
else
|
106
|
+
self.generator.send(name)
|
107
|
+
end
|
108
|
+
else
|
109
|
+
super
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# called by rails after initialize
|
115
|
+
def init
|
116
|
+
require 'easy_captcha/routes'
|
117
|
+
ActiveRecord::Base.send :include, ModelHelpers
|
118
|
+
ActionController::Base.send :include, ControllerHelpers
|
119
|
+
ActionView::Base.send :include, ViewHelpers
|
120
|
+
|
121
|
+
# set default generator
|
122
|
+
generator :default
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
EasyCaptcha.init
|
129
|
+
|
130
|
+
|
131
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module EasyCaptcha
|
2
|
+
module Generators #:nodoc:
|
3
|
+
class InstallGenerator < Rails::Generators::Base #:nodoc:
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
desc "Install easy_captcha"
|
7
|
+
|
8
|
+
def copy_initializer #:nodoc:
|
9
|
+
template "easy_captcha.rb", "config/initializers/easy_captcha.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_devise_routes #:nodoc:
|
13
|
+
route 'captcha_route'
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_after_filter #:nodoc:
|
17
|
+
inject_into_class "app/controllers/application_controller.rb", ApplicationController do
|
18
|
+
" # reset captcha code after each request for security\n after_filter :reset_last_captcha_code!\n\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
EasyCaptcha.setup do |config|
|
2
|
+
# Cache
|
3
|
+
# config.cache = true
|
4
|
+
# Cache temp dir from Rails.root
|
5
|
+
# config.cache_temp_dir = Rails.root + 'tmp' + 'captchas'
|
6
|
+
# Cache size
|
7
|
+
# config.cache_size = 500
|
8
|
+
# Cache expire
|
9
|
+
# config.cache_expire = 1.days
|
10
|
+
|
11
|
+
# Chars
|
12
|
+
# config.chars = %w(2 3 4 5 6 7 9 A C D E F G H J K L M N P Q R S T U X Y Z)
|
13
|
+
|
14
|
+
# Length
|
15
|
+
# config.length = 6
|
16
|
+
|
17
|
+
# Image
|
18
|
+
# config.image_height = 40
|
19
|
+
# config.image_width = 140
|
20
|
+
|
21
|
+
# eSpeak
|
22
|
+
# config.espeak do |espeak|
|
23
|
+
# Amplitude, 0 to 200
|
24
|
+
# espeak.amplitude = 80..120
|
25
|
+
|
26
|
+
# Word gap. Pause between words
|
27
|
+
# espeak.gap = 80
|
28
|
+
|
29
|
+
# Pitch adjustment, 0 to 99
|
30
|
+
# espeak.pitch = 30..70
|
31
|
+
|
32
|
+
# Use voice file of this name from espeak-data/voices
|
33
|
+
# espeak.voice = nil
|
34
|
+
# end
|
35
|
+
|
36
|
+
# configure generator
|
37
|
+
# config.generator :default do |generator|
|
38
|
+
|
39
|
+
# Font
|
40
|
+
# generator.font_size = 24
|
41
|
+
# generator.font_fill_color = '#333333'
|
42
|
+
# generator.font_stroke_color = '#000000'
|
43
|
+
# generator.font_stroke = 0
|
44
|
+
# generator.font_family = File.expand_path('../../resources/afont.ttf', __FILE__)
|
45
|
+
|
46
|
+
# generator.image_background_color = "#FFFFFF"
|
47
|
+
|
48
|
+
# Wave
|
49
|
+
# generator.wave = true
|
50
|
+
# generator.wave_length = (60..100)
|
51
|
+
# generator.wave_amplitude = (3..5)
|
52
|
+
|
53
|
+
# Sketch
|
54
|
+
# generator.sketch = true
|
55
|
+
# generator.sketch_radius = 3
|
56
|
+
# generator.sketch_sigma = 1
|
57
|
+
|
58
|
+
# Implode
|
59
|
+
# generator.implode = 0.1
|
60
|
+
|
61
|
+
# Blur
|
62
|
+
# generator.blur = true
|
63
|
+
# generator.blur_radius = 1
|
64
|
+
# generator.blur_sigma = 2
|
65
|
+
# end
|
66
|
+
end
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: easy_captcha_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.6.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Huitao Chen
|
8
|
+
- Marco Scholl
|
9
|
+
- Alexander Dreher
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2021-10-28 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: 5.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 5.0.0
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: rmagick
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.13.1
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 2.13.1
|
43
|
+
description: Captcha-Plugin for Rails
|
44
|
+
email: h980501427@163.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files:
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
50
|
+
files:
|
51
|
+
- ".gitignore"
|
52
|
+
- LICENSE
|
53
|
+
- README.md
|
54
|
+
- easy_captcha-0.6.5.patch
|
55
|
+
- easy_captcha_rails.gemspec
|
56
|
+
- init.rb
|
57
|
+
- lib/easy_captcha.rb
|
58
|
+
- lib/easy_captcha/captcha.rb
|
59
|
+
- lib/easy_captcha/captcha_controller.rb
|
60
|
+
- lib/easy_captcha/controller_helpers.rb
|
61
|
+
- lib/easy_captcha/espeak.rb
|
62
|
+
- lib/easy_captcha/generator.rb
|
63
|
+
- lib/easy_captcha/generator/base.rb
|
64
|
+
- lib/easy_captcha/generator/default.rb
|
65
|
+
- lib/easy_captcha/model_helpers.rb
|
66
|
+
- lib/easy_captcha/routes.rb
|
67
|
+
- lib/easy_captcha/version.rb
|
68
|
+
- lib/easy_captcha/view_helpers.rb
|
69
|
+
- lib/generators/easy_captcha/install_generator.rb
|
70
|
+
- lib/generators/templates/easy_captcha.rb
|
71
|
+
- resources/captcha.ttf
|
72
|
+
homepage: https://github.com/chenhuitao/easy_captcha_rails
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.2.2
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.8.11
|
90
|
+
requirements: []
|
91
|
+
rubygems_version: 3.1.2
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Captcha-Plugin for Rails 5+
|
95
|
+
test_files: []
|