rucaptcha 1.0.2 → 1.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a21e9918f323f2e1d72df0dec2186b77ca163f6
4
- data.tar.gz: f061a697f5ba7dc28fc6e01ff31e19b402fa436e
3
+ metadata.gz: f866a9984159daf5bfa88cc57e9a9f17f0ba4621
4
+ data.tar.gz: a085e7fbd93873d73144b0c812f9f59e73b1cc4f
5
5
  SHA512:
6
- metadata.gz: 646cbe8bbf5f2b9a6187cf3793d167085c5059099f118c84589abc097fe8160a56ad03dd83f34ad1c23eec252ccab9ee08a448b7aea30e22781a7dc45d6b3cd8
7
- data.tar.gz: 43d06670a614bfb467537c6cb3af87686eacdb72d9ff9c518da1d53e7b956bef16c3c4ff4b74b9441d9828d35ab1a92e27d29d9afc4d0ba8240869fc3fef70b8
6
+ metadata.gz: 64a044dc52179ba06b50e17dfcd926d36cf7da4c82c2bc553cab20098067e9bbb8d6065784985c3128afb3cddd139377c78972ee22445189c3bc56cf55088313
7
+ data.tar.gz: dd64400366f3ca5e458f2426b344d1f657790bd9dfff9de4efbdb4c80a0531e94c8095f7c7dd6dea55dc73bf43b18e2333461ea3794ffaf19b821c7a71fb4f9f
data/CHANGELOG.md CHANGED
@@ -1,17 +1,13 @@
1
- 1.0.2
2
-
3
- - Revert 1.0.1 changes, still store code in Session, `Rails.cache` not a not place in difference environments.
4
- for exampe: Not enable cache, File cache will have bug.
5
- - Give a warning when user use CookieStore.
6
-
7
- 1.0.1
1
+ 1.1.0
8
2
  -----
9
3
 
4
+ - Add `cache_store` config key to setup a cache store location for RuCaptcha.
5
+ - Store captcha in custom cache store.
6
+
10
7
  ## Security Notes
11
8
 
12
9
  - Fix Session replay secure issue that when Rails application use CookieStore.
13
10
 
14
-
15
11
  1.0.0
16
12
  -----
17
13
 
data/README.md CHANGED
@@ -45,20 +45,6 @@ brew install imagemagick ghostscript
45
45
 
46
46
  ## Usage
47
47
 
48
- **Security Notice!**
49
-
50
- You need change your application Session store from `CookieStore` (Rails default) to backend store location.
51
-
52
- - [:active_session_store](https://github.com/rails/activerecord-session_store)
53
- - [:memcached_store](http://api.rubyonrails.org/classes/ActionDispatch/Session/MemCacheStore.html)
54
- - [:redis_session_store](https://github.com/roidrage/redis-session-store)
55
-
56
- config/initializers/session_store.rb
57
-
58
- ```rb
59
- Rails.application.config.session_store :redis_session_store, { ... }
60
- ```
61
-
62
48
  Put rucaptcha in your `Gemfile`:
63
49
 
64
50
  ```
@@ -80,6 +66,11 @@ RuCaptcha.configure do
80
66
  # self.expires_in = 120
81
67
  # Color style, default: :colorful, allows: [:colorful, :black_white]
82
68
  # self.style = :colorful
69
+ # [Requirement]
70
+ # Store Captcha code where, this config more like Rails config.cache_store
71
+ # default: Rails application config.cache_store
72
+ # But RuCaptcha requirements cache_store not in [:null_store, :memory_store, :file_store]
73
+ self.cache_store = :mem_cache_store
83
74
  end
84
75
  ```
85
76
 
data/lib/rucaptcha.rb CHANGED
@@ -20,6 +20,7 @@ module RuCaptcha
20
20
  @config.cache_limit = 100
21
21
  @config.expires_in = 2.minutes
22
22
  @config.style = :colorful
23
+ @config.cache_store = Rails.application.config.cache_store
23
24
  @config
24
25
  end
25
26
 
@@ -1,6 +1,14 @@
1
1
  require 'fileutils'
2
2
 
3
3
  module RuCaptcha
4
+ class << self
5
+ def cache
6
+ return @cache if defined? @cache
7
+ @cache = ActiveSupport::Cache.lookup_store(RuCaptcha.config.cache_store)
8
+ @cache
9
+ end
10
+ end
11
+
4
12
  # File Cache
5
13
  module Cache
6
14
  def self.prepended(base)
@@ -11,7 +19,7 @@ module RuCaptcha
11
19
 
12
20
  module ClassMethods
13
21
  def create(code)
14
- cache.fetch(code, expires_in: 1.days) do
22
+ file_cache.fetch(code, expires_in: 1.days) do
15
23
  super(code)
16
24
  end
17
25
  end
@@ -26,15 +34,15 @@ module RuCaptcha
26
34
  code
27
35
  end
28
36
 
29
- def cache
30
- return @cache if defined?(@cache)
37
+ def file_cache
38
+ return @file_cache if defined?(@file_cache)
31
39
 
32
40
  cache_path = Rails.root.join('tmp', 'cache', 'rucaptcha')
33
41
  FileUtils.mkdir_p(cache_path) unless File.exist? cache_path
34
- @cache = ActiveSupport::Cache::FileStore.new(cache_path)
42
+ @file_cache = ActiveSupport::Cache::FileStore.new(cache_path)
35
43
  # clear expired captcha cache files on Process restart
36
- @cache.cleanup
37
- @cache
44
+ @file_cache.cleanup
45
+ @file_cache
38
46
  end
39
47
 
40
48
  def cached_codes
@@ -6,12 +6,15 @@ module RuCaptcha
6
6
  attr_accessor :len
7
7
  # implode, default 0.3
8
8
  attr_accessor :implode
9
+ # Store Captcha code where, this config more like Rails config.cache_store
10
+ # default: Rails application config.cache_store
11
+ attr_accessor :cache_store
9
12
  # Number of Captcha codes limit
10
13
  # set 0 to disable limit and file cache, default: 100
11
14
  attr_accessor :cache_limit
12
15
  # Color style, default: :colorful, allows: [:colorful, :black_white]
13
16
  attr_accessor :style
14
- # session[:_rucaptcha] expire time, default 2 minutes
17
+ # rucaptcha expire time, default 2 minutes
15
18
  attr_accessor :expires_in
16
19
  end
17
20
  end
@@ -6,28 +6,56 @@ module RuCaptcha
6
6
  helper_method :verify_rucaptcha?
7
7
  end
8
8
 
9
- def generate_rucaptcha
10
- session[:_rucaptcha] = RuCaptcha::Captcha.random_chars
11
- session[:_rucaptcha_at] = Time.now.to_i
9
+ def rucaptcha_sesion_key_key
10
+ ['rucaptcha-session', session.id].join(':')
11
+ end
12
12
 
13
- RuCaptcha::Captcha.create(session[:_rucaptcha])
13
+ def generate_rucaptcha
14
+ code = RuCaptcha::Captcha.random_chars
15
+ session_val = {
16
+ code: code,
17
+ time: Time.now.to_i
18
+ }
19
+ RuCaptcha.cache.write(rucaptcha_sesion_key_key, session_val, expires_in: RuCaptcha.config.expires_in)
20
+ RuCaptcha::Captcha.create(code)
14
21
  end
15
22
 
16
23
  def verify_rucaptcha?(resource = nil)
17
- rucaptcha_at = session[:_rucaptcha_at].to_i
18
- captcha = (params[:_rucaptcha] || '').downcase.strip
24
+ store_info = RuCaptcha.cache.read(rucaptcha_sesion_key_key)
25
+ # make sure move used key
26
+ RuCaptcha.cache.delete(rucaptcha_sesion_key_key)
19
27
 
20
- # Captcha chars in Session expire in 2 minutes
21
- valid = false
22
- if (Time.now.to_i - rucaptcha_at) <= RuCaptcha.config.expires_in
23
- valid = captcha.present? && captcha == session.delete(:_rucaptcha)
28
+ # Make sure session exist
29
+ if store_info.blank?
30
+ return add_rucaptcha_validation_error
24
31
  end
25
32
 
26
- if resource && resource.respond_to?(:errors)
27
- resource.errors.add(:base, t('rucaptcha.invalid')) unless valid
33
+ # Make sure not expire
34
+ puts "-------------- #{store_info.inspect}"
35
+ if (Time.now.to_i - store_info[:time]) > RuCaptcha.config.expires_in
36
+ return add_rucaptcha_validation_error
37
+ end
38
+
39
+ # Make sure parama have captcha
40
+ captcha = (params[:_rucaptcha] || '').downcase.strip
41
+ if captcha.blank?
42
+ return add_rucaptcha_validation_error
28
43
  end
29
44
 
30
- valid
45
+ if captcha != store_info[:code]
46
+ return add_rucaptcha_validation_error
47
+ end
48
+
49
+ true
50
+ end
51
+
52
+ private
53
+
54
+ def add_rucaptcha_validation_error
55
+ if defined?(resource) && resource && resource.respond_to?(:errors)
56
+ resource.errors.add(:base, t('rucaptcha.invalid'))
57
+ end
58
+ false
31
59
  end
32
60
  end
33
61
  end
@@ -8,13 +8,19 @@ module RuCaptcha
8
8
  RuCaptcha::Captcha.send(:prepend, RuCaptcha::Cache)
9
9
  end
10
10
 
11
- if Rails.application.config.session_store.name.match(/CookieStore/)
12
- puts %(
13
- [RuCaptcha] Your application session has use #{Rails.application.config.session_store}
14
- this may have Session [Replay Attacks] secure issue in RuCaptcha case.
15
- We suggest you change it to backend [:active_record_store, :redis_session_store]
16
- http://guides.rubyonrails.org/security.html#replay-attacks-for-cookiestore-sessions)
17
- puts ""
11
+ cache_store = RuCaptcha.config.cache_store
12
+ store_name = cache_store.is_a?(Array) ? cache_store.first : cache_store
13
+ if [:memory_store, :null_store, :file_store].include?(store_name)
14
+ raise "
15
+
16
+ RuCaptcha's cache_store requirements are stored across processes and machines,
17
+ such as :mem_cache_store, :redis_store, or other distributed storage.
18
+ But your current set is :#{store_name}.
19
+
20
+ Please make config file `config/initializes/rucaptcha.rb` to setup `cache_store`.
21
+ More infomation please read GitHub rucaptcha README file.
22
+
23
+ "
18
24
  end
19
25
  end
20
26
  end
@@ -1,3 +1,3 @@
1
1
  module RuCaptcha
2
- VERSION = '1.0.2'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rucaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-26 00:00:00.000000000 Z
11
+ date: 2016-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties