daqing_rucaptcha 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +188 -0
  3. data/Rakefile +71 -0
  4. data/app/controllers/ru_captcha/captcha_controller.rb +14 -0
  5. data/config/locales/rucaptcha.de-DE.yml +3 -0
  6. data/config/locales/rucaptcha.en.yml +3 -0
  7. data/config/locales/rucaptcha.pt-BR.yml +3 -0
  8. data/config/locales/rucaptcha.zh-CN.yml +3 -0
  9. data/config/locales/rucaptcha.zh-TW.yml +3 -0
  10. data/config/routes.rb +3 -0
  11. data/ext/rucaptcha/Cargo.lock +1226 -0
  12. data/ext/rucaptcha/Cargo.toml +14 -0
  13. data/ext/rucaptcha/extconf.rb +4 -0
  14. data/ext/rucaptcha/fonts/FuzzyBubbles-Regular.ttf +0 -0
  15. data/ext/rucaptcha/fonts/Handlee-Regular.ttf +0 -0
  16. data/ext/rucaptcha/src/captcha.rs +341 -0
  17. data/ext/rucaptcha/src/lib.rs +30 -0
  18. data/ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/common.rs +355 -0
  19. data/ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/dynamic.rs +257 -0
  20. data/ext/rucaptcha/target/release/build/clang-sys-f87b799a4d35af4b/out/macros.rs +38 -0
  21. data/ext/rucaptcha/target/release/build/num-bigint-34c75daf72c2b049/out/radix_bases.rs +780 -0
  22. data/ext/rucaptcha/target/release/build/rb-sys-6bdd5b2895b9570a/out/bindings-0.9.78-arm64-darwin22-3.2.2.rs +19775 -0
  23. data/ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/consts.rs +2248 -0
  24. data/ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/op.rs +1030 -0
  25. data/ext/rucaptcha/target/release/build/typenum-f3872660002fb991/out/tests.rs +20565 -0
  26. data/lib/rucaptcha/cache.rb +12 -0
  27. data/lib/rucaptcha/configuration.rb +21 -0
  28. data/lib/rucaptcha/controller_helpers.rb +90 -0
  29. data/lib/rucaptcha/engine.rb +15 -0
  30. data/lib/rucaptcha/errors/configuration.rb +5 -0
  31. data/lib/rucaptcha/version.rb +3 -0
  32. data/lib/rucaptcha/view_helpers.rb +22 -0
  33. data/lib/rucaptcha.rb +86 -0
  34. metadata +103 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e2b719f287469ecff61b9845fb21e08569ac0681120edf027f4d90a7f18b4da4
4
+ data.tar.gz: c8dde4c9dc2d489a4ef528355821f83a42872d46cfe3910e2bb72deea9268822
5
+ SHA512:
6
+ metadata.gz: 0e26b2885cdc74f804fd84656a4856de80f589e882073226fd5c833195222284b8eea24d906cde2c8898bc8cdb15469ff885e175de45113d7c41405287758518
7
+ data.tar.gz: a76c9929abd65c502748cd62dbcc44a61c37840d8ea0445abdbc1c5dd5b87bd4d2ff0f28c3e1492343f70678614ae8a0143f85cc975143ecbbde90787b6f536f
data/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # RuCaptcha
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rucaptcha.svg)](https://badge.fury.io/rb/rucaptcha)
4
+ [![build](https://github.com/huacnlee/rucaptcha/workflows/build/badge.svg)](https://github.com/huacnlee/rucaptcha/actions?query=workflow%3Abuild)
5
+
6
+ Captcha Gem for Rails, which generates captcha image by Rust.
7
+
8
+ > NOTE: According to the use of Ruby China, the verification code looks like has a lower than 5% probability of being parsed by OCR and the verification code is cracked (All Image Captcha libs are has same problem). It is recommended that you use the IP rate limit to enhance the protection.
9
+ > NOTE: 以 Ruby China 的使用来看,验证码似乎有低于 5% 的概率被 OCR 读取解析 (图片验证码都有这个问题) 导致验证码被破解(我们从日志分析绝大多数是成功的,但偶尔一个成功,配合大量机器攻击,导致注册了很多的垃圾账号),建议你额外配合 IP 频率限制的功能来加强保护。
10
+
11
+ > 如果你需要更高强度的验证,建议选择商用服务。
12
+
13
+ [中文介绍和使用说明](https://ruby-china.org/topics/27832)
14
+
15
+ ## Example
16
+
17
+ <img src="https://user-images.githubusercontent.com/5518/196329734-fee49f62-050b-44c8-a5a8-7ffdd3c5a3f6.png" height="50" alt="0"> <img src="https://user-images.githubusercontent.com/5518/196329738-64b264a1-e3fb-4804-ac46-0df18fb31d1e.png" height="50" alt="1"> <img src="https://user-images.githubusercontent.com/5518/196329740-e10ded26-ba46-4e9b-93b8-ce30c198f880.png" height="50" alt="2"> <img src="https://user-images.githubusercontent.com/5518/196329743-c7b055b8-b309-4554-8c95-66c5caf4437d.png" height="50" alt="3"> <img src="https://user-images.githubusercontent.com/5518/196329745-eb68f0c3-ccac-4fa3-aa7a-cc4c2caeb41e.png" height="50" alt="4"> <img src="https://user-images.githubusercontent.com/5518/196329746-b15a9f71-262e-4699-87c7-a5561c6caf2c.png" height="50" alt="5"> <img src="https://user-images.githubusercontent.com/5518/196329747-d111a5d3-89a1-487b-989e-5be8059488c2.png" height="50" alt="6"> <img src="https://user-images.githubusercontent.com/5518/196329749-2cb44aa3-8b59-427c-91f3-59566d6de8a5.png" height="50" alt="7"> <img src="https://user-images.githubusercontent.com/5518/196329754-ae64374b-f2e5-44b8-a7f4-3aee1405c193.png" height="50" alt="8"> <img src="https://user-images.githubusercontent.com/5518/196329755-26b88705-bf34-4d32-a4dc-076530582a90.png" height="50" alt="9">
18
+
19
+ ## Feature
20
+
21
+ - Native Gem base on Rust.
22
+ - For Rails Application;
23
+ - Simple, Easy to use;
24
+ - High performance.
25
+
26
+ ## Usage
27
+
28
+ Put rucaptcha in your `Gemfile`:
29
+
30
+ ```
31
+ gem 'rucaptcha'
32
+ ```
33
+
34
+ Create `config/initializers/rucaptcha.rb`
35
+
36
+ ```rb
37
+ RuCaptcha.configure do
38
+ # Custom captcha code expire time if you need, default: 2 minutes
39
+ # self.expires_in = 120
40
+
41
+  # [Requirement / 重要]
42
+ # Store Captcha code where, this config more like Rails config.cache_store
43
+ # default: Read config info from `Rails.application.config.cache_store`
44
+ # But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]
45
+  # 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,并尝试用可以运行的方式,用于存储验证码字符
46
+  # 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
47
+  self.cache_store = :mem_cache_store
48
+
49
+ # If you wants disable `cache_store` check warning, you can do it, default: false
50
+ # 如果想要 disable cache_store 的 warning,就设置为 true,default false
51
+ # self.skip_cache_store_check = true
52
+
53
+ # Chars length, default: 5, allows: [3 - 7]
54
+ # self.length = 5
55
+
56
+ # Enable or disable Strikethrough, default: true
57
+ # self.line = true
58
+
59
+ # Enable or disable noise, default: false
60
+ # self.noise = false
61
+
62
+ # Set the image format, default: png, allows: [jpeg, png, webp]
63
+ # self.format = 'png'
64
+ end
65
+ ```
66
+
67
+ RuCaptcha 没有使用 Rails Session 来存储验证码信息,因为 Rails 的默认 Session 是存储在 Cookie 里面,如果验证码存在里面会存在 [Replay attack](https://en.wikipedia.org/wiki/Replay_attack) 漏洞,导致验证码关卡被攻破。
68
+
69
+ 所以我在设计上要求 RuCaptcha 得配置一个可以支持分布式的后端存储方案例如:Memcached 或 Redis 以及其他可以支持分布式的 cache_store 方案。
70
+
71
+ 同时,为了保障易用性,默认会尝试使用 `:file_store` 的方式,将验证码存在应用程序的 `tmp/cache/rucaptcha/session` 目录(但请注意,多机器部署这样是无法正常运作的)。
72
+
73
+ 所以,我建议大家使用的时候,配置上 `cache_store` (详见 [Rails Guides 缓存配置部分](https://ruby-china.github.io/rails-guides/caching_with_rails.html#%E9%85%8D%E7%BD%AE)的文档)到一个 Memcached 或 Redis,这才是最佳实践。
74
+
75
+ #
76
+
77
+ (RuCaptha do not use Rails Session to store captcha information. As the default session is stored in Cookie in Rails, there's a [Replay attack](https://en.wikipedia.org/wiki/Replay_attack) bug which may causes capthcha being destroyed if we store captcha in Rails Session.
78
+
79
+ So in my design I require RuCaptcha to configure a distributed backend storage scheme, such as Memcached, Redis or other cache_store schemes which support distribution.
80
+
81
+ Meanwhile, for the ease of use, RuCapthca would try to use `:file_store` by default and store the capthca in `tmp/cache/rucaptcha/session` directory (kindly note that it's not working if deploy on multiple machine).
82
+
83
+ For recommendation, configure the `cache_store`(more details on [Rails Guides Configuration of Cache Stores](http://guides.rubyonrails.org/caching_with_rails.html#configuration)) to Memcached or Redis, that would be the best practice.)
84
+
85
+ #
86
+
87
+ Controller `app/controller/account_controller.rb`
88
+
89
+ When you called `verify_rucaptcha?`, it uses value from `params[:_rucaptcha]` to validate.
90
+
91
+ ```rb
92
+ class AccountController < ApplicationController
93
+ def create
94
+ @user = User.new(params[:user])
95
+ if verify_rucaptcha?(@user) && @user.save
96
+ redirect_to root_path, notice: 'Sign up successed.'
97
+ else
98
+ render 'account/new'
99
+ end
100
+ end
101
+ end
102
+
103
+ class ForgotPasswordController < ApplicationController
104
+ def create
105
+ # without any args
106
+ if verify_rucaptcha?
107
+ to_send_email
108
+ else
109
+ redirect_to '/forgot-password', alert: 'Invalid captcha code.'
110
+ end
111
+ end
112
+ end
113
+ ```
114
+
115
+ > TIP: Sometimes you may need to keep last verified captcha code in session on `verify_rucaptcha?` method call, you can use `keep_session: true`. For example: `verify_rucaptcha? @user, keep_session: true`.
116
+
117
+ View `app/views/account/new.html.erb`
118
+
119
+ ```erb
120
+ <form method="POST">
121
+ ...
122
+ <div class="form-group">
123
+ <%= rucaptcha_input_tag(class: 'form-control', placeholder: 'Input Captcha') %>
124
+ <%= rucaptcha_image_tag(alt: 'Captcha') %>
125
+ </div>
126
+ ...
127
+
128
+ <div class="form-group">
129
+ <button type="submit" class="btn btn-primary">Submit</button>
130
+ </div>
131
+ </form>
132
+ ```
133
+
134
+ And if you are using [Devise](https://github.com/plataformatec/devise), you can read this reference to add validation: [RuCaptcha with Devise](https://github.com/huacnlee/rucaptcha/wiki/Working-with-Devise).
135
+
136
+ ### Write your test skip captcha validation
137
+
138
+ for RSpec
139
+
140
+ ```rb
141
+ describe 'sign up and login', type: :feature do
142
+ before do
143
+ allow_any_instance_of(ActionController::Base).to receive(:verify_rucaptcha?).and_return(true)
144
+ end
145
+
146
+ it { ... }
147
+ end
148
+ ```
149
+
150
+ for MiniTest
151
+
152
+ ```rb
153
+ class ActionDispatch::IntegrationTest
154
+ def sign_in(user)
155
+ ActionController::Base.any_instance.stubs(:verify_rucaptcha?).returns(true)
156
+ post user_session_path \
157
+ 'user[email]' => user.email,
158
+ 'user[password]' => user.password
159
+ end
160
+ end
161
+ ```
162
+
163
+ ### Invalid message without Devise
164
+
165
+ When you are using this gem without Devise, you may find out that the invalid message is missing.
166
+ For this case, use the trick below to add your i18n invalid message manually.
167
+
168
+ ```rb
169
+ if verify_rucaptcha?(@user) && @user.save
170
+ do_whatever_you_want
171
+ redirect_to someplace_you_want
172
+ else
173
+ # this is the trick
174
+ @user.errors.add(:base, t('rucaptcha.invalid'))
175
+ render :new
176
+ end
177
+ ```
178
+
179
+ ## Performance
180
+
181
+ `rake benchmark` to run benchmark test.
182
+
183
+ ```
184
+ Warming up --------------------------------------
185
+ Generate image 51.000 i/100ms
186
+ Calculating -------------------------------------
187
+ Generate image 526.350 (± 2.5%) i/s - 2.652k in 5.041681s
188
+ ```
data/Rakefile ADDED
@@ -0,0 +1,71 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rake/extensiontask"
4
+ require "rubygems/package_task"
5
+ require "bundler"
6
+
7
+ CROSS_PLATFORMS = %w[
8
+ aarch64-linux
9
+ arm64-darwin
10
+ x64-mingw32
11
+ x86_64-darwin
12
+ x86_64-linux
13
+ x86_64-linux-musl
14
+ ]
15
+
16
+ spec = Bundler.load_gemspec("rucaptcha.gemspec")
17
+
18
+ Gem::PackageTask.new(spec).define
19
+
20
+ Rake::ExtensionTask.new("rucaptcha", spec) do |ext|
21
+ ext.lib_dir = "lib/rucaptcha"
22
+ ext.source_pattern = "*.{rs,toml}"
23
+ ext.cross_compile = true
24
+ ext.cross_platform = CROSS_PLATFORMS
25
+ end
26
+
27
+ RSpec::Core::RakeTask.new(:spec)
28
+ task default: :spec
29
+
30
+ def create_captcha(length = 5, difficulty = 5)
31
+ require "rucaptcha"
32
+ RuCaptchaCore.create(length, difficulty, false, false, "png")
33
+ end
34
+
35
+ task :preview do
36
+ require "rucaptcha"
37
+ res = create_captcha()
38
+ warn "-------------------------\n#{res[0]}"
39
+ puts res[1].pack("c*")
40
+ end
41
+
42
+ task :memory do
43
+ require "rucaptcha"
44
+ require "memory_profiler"
45
+
46
+ create_captcha()
47
+
48
+ report = MemoryProfiler.report do
49
+ 1000.times do
50
+ create_captcha()
51
+ end
52
+ end
53
+
54
+ GC.start
55
+ report.pretty_print
56
+
57
+ puts "------------------------- Result Guide -------------------------"
58
+ puts "If [Total retained] have any bytes, there will have memory leak."
59
+ end
60
+
61
+ task :benchmark do
62
+ require "rucaptcha"
63
+ require "benchmark/ips"
64
+
65
+ RuCaptchaCore.create(5, 5, true, true, "png")
66
+
67
+ Benchmark.ips do |x|
68
+ x.report("Generate image") { RuCaptchaCore.create(5, 5, true, true, "png") }
69
+ x.compare!
70
+ end
71
+ end
@@ -0,0 +1,14 @@
1
+ module RuCaptcha
2
+ class CaptchaController < ActionController::Base
3
+ def index
4
+ return head :ok if request.head?
5
+
6
+ headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
7
+ headers["Pragma"] = "no-cache"
8
+ data = generate_rucaptcha
9
+
10
+ opts = { disposition: "inline", type: "image/jpeg" }
11
+ send_data data, opts
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ 'de-DE':
2
+ rucaptcha:
3
+ invalid: "Falsches Captcha (Wenn es nicht erkannt wird, klicken Sie darauf , um das Captcha zu aktualisieren)"
@@ -0,0 +1,3 @@
1
+ en:
2
+ rucaptcha:
3
+ invalid: "The captcha code is incorrect (if you can't read, you can click image to refresh it)"
@@ -0,0 +1,3 @@
1
+ 'pt-BR':
2
+ rucaptcha:
3
+ invalid: "Código inválido!"
@@ -0,0 +1,3 @@
1
+ 'zh-CN':
2
+ rucaptcha:
3
+ invalid: "验证码不正确(如无法识别,可以点击刷新验证码)"
@@ -0,0 +1,3 @@
1
+ 'zh-TW':
2
+ rucaptcha:
3
+ invalid: "驗證碼不正確(如無法識別,可以點擊刷新驗證碼)"
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ RuCaptcha::Engine.routes.draw do
2
+ root to: "captcha#index"
3
+ end