daqing_rucaptcha 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +188 -0
- data/Rakefile +71 -0
- data/app/controllers/ru_captcha/captcha_controller.rb +14 -0
- data/config/locales/rucaptcha.de-DE.yml +3 -0
- data/config/locales/rucaptcha.en.yml +3 -0
- data/config/locales/rucaptcha.pt-BR.yml +3 -0
- data/config/locales/rucaptcha.zh-CN.yml +3 -0
- data/config/locales/rucaptcha.zh-TW.yml +3 -0
- data/config/routes.rb +3 -0
- data/ext/rucaptcha/Cargo.lock +1226 -0
- data/ext/rucaptcha/Cargo.toml +14 -0
- data/ext/rucaptcha/extconf.rb +4 -0
- data/ext/rucaptcha/fonts/FuzzyBubbles-Regular.ttf +0 -0
- data/ext/rucaptcha/fonts/Handlee-Regular.ttf +0 -0
- data/ext/rucaptcha/src/captcha.rs +341 -0
- data/ext/rucaptcha/src/lib.rs +30 -0
- data/ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/common.rs +355 -0
- data/ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/dynamic.rs +257 -0
- data/ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/macros.rs +38 -0
- data/ext/rucaptcha/target/release/build/num-bigint-34c75daf72c2b049/out/radix_bases.rs +780 -0
- data/ext/rucaptcha/target/release/build/rb-sys-6bdd5b2895b9570a/out/bindings-0.9.78-arm64-darwin22-3.2.2.rs +19775 -0
- data/ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/consts.rs +2248 -0
- data/ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/op.rs +1030 -0
- data/ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/tests.rs +20565 -0
- data/lib/rucaptcha/cache.rb +12 -0
- data/lib/rucaptcha/configuration.rb +21 -0
- data/lib/rucaptcha/controller_helpers.rb +90 -0
- data/lib/rucaptcha/engine.rb +15 -0
- data/lib/rucaptcha/errors/configuration.rb +5 -0
- data/lib/rucaptcha/version.rb +3 -0
- data/lib/rucaptcha/view_helpers.rb +22 -0
- data/lib/rucaptcha.rb +86 -0
- metadata +103 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
module RuCaptcha
|
2
|
+
class Configuration
|
3
|
+
# Store Captcha code where, this config more like Rails config.cache_store
|
4
|
+
# default: Rails application config.cache_store
|
5
|
+
attr_accessor :cache_store
|
6
|
+
# rucaptcha expire time, default 2 minutes
|
7
|
+
attr_accessor :expires_in
|
8
|
+
# Chars length: default 5, allows: [3..7]
|
9
|
+
attr_accessor :length
|
10
|
+
# Hard mode, default: 5, allows: [1..10]
|
11
|
+
attr_accessor :difficulty
|
12
|
+
# Enable or disable strikethrough lines on captcha image, default: true
|
13
|
+
attr_accessor :line
|
14
|
+
# Enable or disable noise on captcha image, default: false
|
15
|
+
attr_accessor :noise
|
16
|
+
# Image format allow: ['jpeg', 'png', 'webp'], default: 'png'
|
17
|
+
attr_accessor :format
|
18
|
+
# skip_cache_store_check, default: false
|
19
|
+
attr_accessor :skip_cache_store_check
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module RuCaptcha
|
2
|
+
module ControllerHelpers
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
helper_method :verify_rucaptcha?
|
7
|
+
end
|
8
|
+
|
9
|
+
def rucaptcha_session_id
|
10
|
+
cookies[:_rucaptcha_session_id]
|
11
|
+
end
|
12
|
+
|
13
|
+
# session key of rucaptcha
|
14
|
+
def rucaptcha_sesion_key_key
|
15
|
+
warning_when_session_invalid if rucaptcha_session_id.blank?
|
16
|
+
|
17
|
+
# With https://github.com/rack/rack/commit/7fecaee81f59926b6e1913511c90650e76673b38
|
18
|
+
# to protected session_id into secret
|
19
|
+
session_id_digest = Digest::SHA256.hexdigest(rucaptcha_session_id.inspect)
|
20
|
+
["rucaptcha-session", session_id_digest].join(":")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Generate a new Captcha
|
24
|
+
def generate_rucaptcha
|
25
|
+
generate_rucaptcha_session_id
|
26
|
+
|
27
|
+
res = RuCaptcha.generate
|
28
|
+
session_val = {
|
29
|
+
code: res[0],
|
30
|
+
time: Time.now.to_i
|
31
|
+
}
|
32
|
+
RuCaptcha.cache.write(rucaptcha_sesion_key_key, session_val, expires_in: RuCaptcha.config.expires_in)
|
33
|
+
res[1]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Verify captcha code
|
37
|
+
#
|
38
|
+
# @param [String] code the captcha code to check against
|
39
|
+
# @param [Boolean] keep_session true to keep the session
|
40
|
+
# @return [Hash] { success: true, message: "validation_ok"} or { success: false, message: "error_reason" }
|
41
|
+
def verify_rucaptcha?(code, keep_session)
|
42
|
+
store_info = RuCaptcha.cache.read(rucaptcha_sesion_key_key)
|
43
|
+
|
44
|
+
# make sure move used key
|
45
|
+
RuCaptcha.cache.delete(rucaptcha_sesion_key_key) unless keep_session
|
46
|
+
|
47
|
+
# Make sure session exist
|
48
|
+
return { success: false, message: "store_info_is_blank" } if store_info.blank?
|
49
|
+
|
50
|
+
# Make sure not expire
|
51
|
+
return { success: false, message: "captcha_is_expired" } if (Time.now.to_i - store_info[:time]) > RuCaptcha.config.expires_in
|
52
|
+
|
53
|
+
# Make sure parama have captcha
|
54
|
+
captcha = code.downcase.strip
|
55
|
+
actual = store_info[:code]
|
56
|
+
|
57
|
+
return { success: false, message: "captcha_is_blank" } if captcha.blank?
|
58
|
+
return { success: false, message: "captcha_not_match_with_#{actual}" } if captcha != actual
|
59
|
+
|
60
|
+
{ success: true, message: "validation_ok" }
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def generate_rucaptcha_session_id
|
66
|
+
return if rucaptcha_session_id.present?
|
67
|
+
|
68
|
+
cookies[:_rucaptcha_session_id] = {
|
69
|
+
value: SecureRandom.hex(16),
|
70
|
+
expires: 1.day
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
# def add_rucaptcha_validation_error
|
75
|
+
# if defined?(resource) && resource && resource.respond_to?(:errors)
|
76
|
+
# resource.errors.add(:base, t("rucaptcha.invalid"))
|
77
|
+
# end
|
78
|
+
# false
|
79
|
+
# end
|
80
|
+
|
81
|
+
def warning_when_session_invalid
|
82
|
+
return unless Rails.env.development?
|
83
|
+
|
84
|
+
Rails.logger.warn "
|
85
|
+
WARNING! The session.id is blank, RuCaptcha can't work properly, please keep session available.
|
86
|
+
More details about this: https://github.com/huacnlee/rucaptcha/pull/66
|
87
|
+
"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RuCaptcha
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace RuCaptcha
|
4
|
+
|
5
|
+
initializer "rucaptcha.init" do |app|
|
6
|
+
# https://github.com/rails/rails/blob/3-2-stable/actionpack/lib/action_dispatch/routing/route_set.rb#L268
|
7
|
+
# `app.routes.prepend` start from Rails 3.2 - 5.0
|
8
|
+
app.routes.prepend do
|
9
|
+
mount RuCaptcha::Engine => "/rucaptcha"
|
10
|
+
end
|
11
|
+
|
12
|
+
RuCaptcha.check_cache_store! unless RuCaptcha.config.skip_cache_store_check
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RuCaptcha
|
2
|
+
module ViewHelpers
|
3
|
+
def rucaptcha_input_tag(opts = {})
|
4
|
+
opts[:name] = "_rucaptcha"
|
5
|
+
opts[:type] = "text"
|
6
|
+
opts[:autocorrect] = "off"
|
7
|
+
opts[:autocapitalize] = "off"
|
8
|
+
opts[:pattern] = "[a-zA-Z0-9]*"
|
9
|
+
opts[:autocomplete] = "off"
|
10
|
+
opts[:maxlength] = RuCaptcha.config.length
|
11
|
+
tag(:input, opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def rucaptcha_image_tag(opts = {})
|
15
|
+
@rucaptcha_image_tag__image_path_in_this_request ||= "#{ru_captcha.root_path}?t=#{Time.now.strftime('%s%L')}"
|
16
|
+
opts[:class] = opts[:class] || "rucaptcha-image"
|
17
|
+
opts[:src] = @rucaptcha_image_tag__image_path_in_this_request
|
18
|
+
opts[:onclick] = "this.src = '#{ru_captcha.root_path}?t=' + Date.now();"
|
19
|
+
tag(:img, opts)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/rucaptcha.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require "rails"
|
2
|
+
require "action_controller"
|
3
|
+
require "active_support/all"
|
4
|
+
|
5
|
+
begin
|
6
|
+
# load the precompiled extension file
|
7
|
+
ruby_version = /(\d+\.\d+)/.match(::RUBY_VERSION)
|
8
|
+
require_relative "rucaptcha/#{ruby_version}/rucaptcha"
|
9
|
+
rescue LoadError
|
10
|
+
require "rucaptcha/rucaptcha"
|
11
|
+
end
|
12
|
+
|
13
|
+
require "rucaptcha/version"
|
14
|
+
require "rucaptcha/configuration"
|
15
|
+
require "rucaptcha/controller_helpers"
|
16
|
+
require "rucaptcha/view_helpers"
|
17
|
+
require "rucaptcha/cache"
|
18
|
+
require "rucaptcha/engine"
|
19
|
+
require "rucaptcha/errors/configuration"
|
20
|
+
|
21
|
+
module RuCaptcha
|
22
|
+
class << self
|
23
|
+
def config
|
24
|
+
return @config if defined?(@config)
|
25
|
+
|
26
|
+
@config = Configuration.new
|
27
|
+
@config.length = 5
|
28
|
+
@config.difficulty = 3
|
29
|
+
@config.expires_in = 2.minutes
|
30
|
+
@config.skip_cache_store_check = false
|
31
|
+
@config.line = true
|
32
|
+
@config.noise = true
|
33
|
+
@config.format = "png"
|
34
|
+
|
35
|
+
@config.cache_store = if Rails.application
|
36
|
+
Rails.application.config.cache_store
|
37
|
+
else
|
38
|
+
:mem_cache_store
|
39
|
+
end
|
40
|
+
@config.cache_store
|
41
|
+
@config
|
42
|
+
end
|
43
|
+
|
44
|
+
def configure(&block)
|
45
|
+
config.instance_exec(&block)
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate
|
49
|
+
length = config.length
|
50
|
+
|
51
|
+
raise RuCaptcha::Errors::Configuration, "length config error, value must in 3..7" unless length.in?(3..7)
|
52
|
+
|
53
|
+
result = RuCaptchaCore.create(length, config.difficulty || 5, config.line, config.noise, config.format)
|
54
|
+
[result[0].downcase, result[1].pack("c*")]
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_cache_store!
|
58
|
+
cache_store = RuCaptcha.config.cache_store
|
59
|
+
store_name = cache_store.is_a?(Array) ? cache_store.first : cache_store
|
60
|
+
if %i[memory_store null_store file_store].include?(store_name)
|
61
|
+
RuCaptcha.config.cache_store = [:file_store, Rails.root.join("tmp/cache/rucaptcha/session")]
|
62
|
+
|
63
|
+
puts "
|
64
|
+
|
65
|
+
RuCaptcha's cache_store requirements are stored across processes and machines,
|
66
|
+
such as :mem_cache_store, :redis_store, or other distributed storage.
|
67
|
+
But your current set is #{cache_store}, it has changed to :file_store for working.
|
68
|
+
NOTE: :file_store is still not a good way, it only works with single server case.
|
69
|
+
|
70
|
+
Please make config file `config/initializers/rucaptcha.rb` to setup `cache_store`.
|
71
|
+
More infomation please read GitHub RuCaptcha README file.
|
72
|
+
https://github.com/huacnlee/rucaptcha
|
73
|
+
|
74
|
+
"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
ActiveSupport.on_load(:action_controller) do
|
81
|
+
ActionController::Base.include RuCaptcha::ControllerHelpers
|
82
|
+
end
|
83
|
+
|
84
|
+
ActiveSupport.on_load(:action_view) do
|
85
|
+
include RuCaptcha::ViewHelpers
|
86
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: daqing_rucaptcha
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Zhang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-07-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: railties
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rb_sys
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.18
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.9.18
|
41
|
+
description:
|
42
|
+
email: daqing@v8os.com
|
43
|
+
executables: []
|
44
|
+
extensions:
|
45
|
+
- ext/rucaptcha/extconf.rb
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- app/controllers/ru_captcha/captcha_controller.rb
|
51
|
+
- config/locales/rucaptcha.de-DE.yml
|
52
|
+
- config/locales/rucaptcha.en.yml
|
53
|
+
- config/locales/rucaptcha.pt-BR.yml
|
54
|
+
- config/locales/rucaptcha.zh-CN.yml
|
55
|
+
- config/locales/rucaptcha.zh-TW.yml
|
56
|
+
- config/routes.rb
|
57
|
+
- ext/rucaptcha/Cargo.lock
|
58
|
+
- ext/rucaptcha/Cargo.toml
|
59
|
+
- ext/rucaptcha/extconf.rb
|
60
|
+
- ext/rucaptcha/fonts/FuzzyBubbles-Regular.ttf
|
61
|
+
- ext/rucaptcha/fonts/Handlee-Regular.ttf
|
62
|
+
- ext/rucaptcha/src/captcha.rs
|
63
|
+
- ext/rucaptcha/src/lib.rs
|
64
|
+
- ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/common.rs
|
65
|
+
- ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/dynamic.rs
|
66
|
+
- ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/macros.rs
|
67
|
+
- ext/rucaptcha/target/release/build/num-bigint-34c75daf72c2b049/out/radix_bases.rs
|
68
|
+
- ext/rucaptcha/target/release/build/rb-sys-6bdd5b2895b9570a/out/bindings-0.9.78-arm64-darwin22-3.2.2.rs
|
69
|
+
- ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/consts.rs
|
70
|
+
- ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/op.rs
|
71
|
+
- ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/tests.rs
|
72
|
+
- lib/rucaptcha.rb
|
73
|
+
- lib/rucaptcha/cache.rb
|
74
|
+
- lib/rucaptcha/configuration.rb
|
75
|
+
- lib/rucaptcha/controller_helpers.rb
|
76
|
+
- lib/rucaptcha/engine.rb
|
77
|
+
- lib/rucaptcha/errors/configuration.rb
|
78
|
+
- lib/rucaptcha/version.rb
|
79
|
+
- lib/rucaptcha/view_helpers.rb
|
80
|
+
homepage: https://github.com/daqing/rucaptcha
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 2.7.0
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubygems_version: 3.4.10
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Captcha Gem for Rails, which generates captcha image by Rust.
|
103
|
+
test_files: []
|