daqing_rucaptcha 3.2.1
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/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: []
|