frikandel 2.1.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +16 -7
- data/{Gemfile.rails-3.2.x → Gemfile.rails-5.2.x} +1 -1
- data/{Gemfile.rails-4.0.x → Gemfile.rails-6.0.x} +1 -1
- data/README.md +9 -4
- data/frikandel.gemspec +7 -3
- data/lib/frikandel/bind_session_to_ip_address.rb +6 -1
- data/lib/frikandel/limit_session_lifetime.rb +5 -1
- data/lib/frikandel/version.rb +1 -1
- data/spec/controllers/bind_session_to_ip_address_controller_spec.rb +36 -28
- data/spec/controllers/combined_controller_spec.rb +43 -35
- data/spec/controllers/customized_on_invalid_session_controller_spec.rb +3 -2
- data/spec/controllers/limit_session_lifetime_controller_spec.rb +78 -70
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/environments/test.rb +7 -2
- data/spec/dummy/log/test.log +1948 -2180
- data/spec/lib/frikandel/configuration_spec.rb +17 -17
- data/spec/rails_helper.rb +76 -0
- data/spec/spec_helper.rb +88 -24
- data/spec/support/application_controller.rb +6 -1
- metadata +59 -49
- data/Gemfile.rails-4.1.x +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a857451a8180dae2842702e657035f3ca0d832fe79ba4846bbafc634ee6c542a
|
4
|
+
data.tar.gz: ef1f626c20166d465e63b4ca36563c4bc6dc2eec54b7be4140adcb7b3fc04d05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1a0eb96d67790766871a4615e31d7c40c4181ce643d9fd1a4cb92ac43c28ca07700a8ef6d44a739e477d973377dabcceeec05182204d0dda4c79a5aaba167e7
|
7
|
+
data.tar.gz: b0d089434e1f9910bdd1ac8f14c83e3599f020d4a881d47ee19a4b06dc3e5e8def9f4fd475f7a0d6de0688d794e089bbb342fa140071fdca466eb4458030475f
|
data/.travis.yml
CHANGED
@@ -1,16 +1,25 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
4
|
-
-
|
5
|
-
-
|
3
|
+
- 2.4
|
4
|
+
- 2.5
|
5
|
+
- 2.6
|
6
|
+
- 2.7
|
6
7
|
- ruby-head
|
7
|
-
- jruby
|
8
|
+
- jruby
|
9
|
+
- truffleruby
|
8
10
|
gemfile:
|
9
|
-
- Gemfile.rails-
|
10
|
-
- Gemfile.rails-
|
11
|
-
- Gemfile.rails-4.1.x
|
11
|
+
- Gemfile.rails-5.2.x
|
12
|
+
- Gemfile.rails-6.0.x
|
12
13
|
- Gemfile.rails-head
|
14
|
+
before_install:
|
15
|
+
- gem update --system
|
16
|
+
- gem install bundler
|
13
17
|
matrix:
|
14
18
|
allow_failures:
|
15
19
|
- rvm: ruby-head
|
16
20
|
- gemfile: Gemfile.rails-head
|
21
|
+
exclude:
|
22
|
+
- rvm: 2.4
|
23
|
+
gemfile: Gemfile.rails-6.0.x
|
24
|
+
- rvm: 2.4
|
25
|
+
gemfile: Gemfile.rails-head
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Frikandel
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/frikandel.png)](http://badge.fury.io/rb/frikandel)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/frikandel.png)](http://badge.fury.io/rb/frikandel)
|
3
3
|
[![Build Status](https://api.travis-ci.org/taktsoft/frikandel.png)](https://travis-ci.org/taktsoft/frikandel)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/taktsoft/frikandel.png)](https://codeclimate.com/github/taktsoft/frikandel)
|
5
|
+
[![Dependency Status](https://gemnasium.com/taktsoft/frikandel.svg)](https://gemnasium.com/taktsoft/frikandel)
|
5
6
|
|
6
7
|
This gem aims to improve the security of your rails application. It allows you to add a TTL (Time To Live) to the session cookie and allows you to bind the session to an IP address.
|
7
8
|
|
@@ -99,9 +100,13 @@ end
|
|
99
100
|
|
100
101
|
To run the test suite with different rails version by selecting the corresponding gemfile. You can use this one liners:
|
101
102
|
|
102
|
-
$ BUNDLE_GEMFILE=Gemfile.rails-3.2.x bundle update && bundle exec rake spec
|
103
|
-
$ BUNDLE_GEMFILE=Gemfile.rails-4.0.x bundle update && bundle exec rake spec
|
104
|
-
$ BUNDLE_GEMFILE=Gemfile.rails-4.1.x bundle update && bundle exec rake spec
|
103
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-3.2.x && bundle update && bundle exec rake spec
|
104
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-4.0.x && bundle update && bundle exec rake spec
|
105
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-4.1.x && bundle update && bundle exec rake spec
|
106
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-4.2.x && bundle update && bundle exec rake spec
|
107
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-5.0.x && bundle update && bundle exec rake spec
|
108
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-5.1.x && bundle update && bundle exec rake spec
|
109
|
+
$ export BUNDLE_GEMFILE=Gemfile.rails-5.2.x && bundle update && bundle exec rake spec
|
105
110
|
|
106
111
|
## Contributing
|
107
112
|
1. Fork it
|
data/frikandel.gemspec
CHANGED
@@ -18,14 +18,18 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = Dir["spec/**/*"]
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.
|
21
|
+
spec.required_ruby_version = '>= 1.9.3'
|
22
|
+
spec.required_rubygems_version = ">= 1.3.6"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler"
|
22
25
|
spec.add_development_dependency "rake"
|
23
26
|
spec.add_development_dependency "sqlite3" unless RUBY_PLATFORM == 'java'
|
24
27
|
spec.add_development_dependency "jdbc-sqlite3" if RUBY_PLATFORM == 'java'
|
25
28
|
spec.add_development_dependency "activerecord-jdbcsqlite3-adapter" if RUBY_PLATFORM == 'java'
|
26
|
-
spec.add_development_dependency "rspec-rails"
|
29
|
+
spec.add_development_dependency "rspec-rails", "> 3.0"
|
27
30
|
spec.add_development_dependency "guard-rspec"
|
28
31
|
spec.add_development_dependency "pry"
|
32
|
+
spec.add_development_dependency "test-unit"
|
29
33
|
|
30
|
-
spec.add_dependency "rails",
|
34
|
+
spec.add_dependency "rails", ">= 3.2.0"
|
31
35
|
end
|
@@ -1,9 +1,14 @@
|
|
1
1
|
module Frikandel
|
2
2
|
module BindSessionToIpAddress
|
3
3
|
extend ActiveSupport::Concern
|
4
|
+
include SessionInvalidation
|
4
5
|
|
5
6
|
included do
|
6
|
-
|
7
|
+
if respond_to?(:before_action)
|
8
|
+
append_before_action :validate_session_ip_address
|
9
|
+
else
|
10
|
+
append_before_filter :validate_session_ip_address
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
private
|
@@ -4,7 +4,11 @@ module Frikandel
|
|
4
4
|
include SessionInvalidation
|
5
5
|
|
6
6
|
included do
|
7
|
-
|
7
|
+
if respond_to?(:before_action)
|
8
|
+
append_before_action :validate_session_timestamp
|
9
|
+
else
|
10
|
+
append_before_filter :validate_session_timestamp
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
private
|
data/lib/frikandel/version.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
-
require "
|
1
|
+
require "rails_helper"
|
2
2
|
require "support/application_controller"
|
3
3
|
|
4
4
|
|
5
5
|
class BindSessionToIpAddressController < ApplicationController
|
6
6
|
include Frikandel::BindSessionToIpAddress
|
7
7
|
|
8
|
-
|
8
|
+
if respond_to?(:before_action)
|
9
|
+
before_action :flash_alert_and_redirect_home, only: [:redirect_home]
|
10
|
+
else
|
11
|
+
before_filter :flash_alert_and_redirect_home, only: [:redirect_home]
|
12
|
+
end
|
9
13
|
|
10
14
|
def home
|
11
|
-
|
15
|
+
if Rails::VERSION::MAJOR >= 5
|
16
|
+
render plain: "bind test"
|
17
|
+
else
|
18
|
+
render text: "bind test"
|
19
|
+
end
|
12
20
|
end
|
13
21
|
|
14
22
|
def redirect_home
|
@@ -23,7 +31,7 @@ protected
|
|
23
31
|
end
|
24
32
|
|
25
33
|
|
26
|
-
describe BindSessionToIpAddressController do
|
34
|
+
RSpec.describe BindSessionToIpAddressController do
|
27
35
|
context "requests" do
|
28
36
|
it "writes current ip address to session" do
|
29
37
|
expect(session[:ip_address]).to be_nil
|
@@ -40,13 +48,13 @@ describe BindSessionToIpAddressController do
|
|
40
48
|
|
41
49
|
expect(session[:ip_address]).to eql("0.0.0.0")
|
42
50
|
|
43
|
-
flash.
|
44
|
-
flash[:alert].
|
51
|
+
expect(flash).not_to be_empty
|
52
|
+
expect(flash[:alert]).to eql("alert test")
|
45
53
|
end
|
46
54
|
|
47
55
|
it "raises an exception if session address and current ip address don't match" do
|
48
56
|
session[:ip_address] = "1.2.3.4"
|
49
|
-
controller.
|
57
|
+
expect(controller).to receive(:on_invalid_session)
|
50
58
|
|
51
59
|
get :home
|
52
60
|
end
|
@@ -59,21 +67,21 @@ describe BindSessionToIpAddressController do
|
|
59
67
|
session[:ttl] = "SomeTTL"
|
60
68
|
session[:max_ttl] = "SomeMaxTTL"
|
61
69
|
|
62
|
-
controller.
|
63
|
-
controller.
|
70
|
+
expect(controller).to receive(:reset_session).and_call_original
|
71
|
+
expect(controller).to receive(:persist_session_ip_address).and_call_original
|
64
72
|
get :home
|
65
73
|
|
66
|
-
session[:user_id].
|
67
|
-
session[:ip_address].
|
68
|
-
session[:ip_address].
|
69
|
-
session[:ttl].
|
70
|
-
session[:max_ttl].
|
74
|
+
expect(session[:user_id]).to be_blank
|
75
|
+
expect(session[:ip_address]).to be_present
|
76
|
+
expect(session[:ip_address]).to eql("0.0.0.0")
|
77
|
+
expect(session[:ttl]).to be_blank
|
78
|
+
expect(session[:max_ttl]).to be_blank
|
71
79
|
end
|
72
80
|
|
73
81
|
it "allows the request to be rendered as normal" do
|
74
82
|
get :home
|
75
83
|
|
76
|
-
response.body.
|
84
|
+
expect(response.body).to eql("bind test")
|
77
85
|
end
|
78
86
|
end
|
79
87
|
end
|
@@ -83,8 +91,8 @@ describe BindSessionToIpAddressController do
|
|
83
91
|
it "calls on_invalid_session if ip address doesn't match with current" do
|
84
92
|
session[:ip_address] = "1.3.3.7"
|
85
93
|
|
86
|
-
controller.
|
87
|
-
controller.
|
94
|
+
expect(controller).to receive(:ip_address_match_with_current?).and_return(false)
|
95
|
+
expect(controller).to receive(:on_invalid_session)
|
88
96
|
|
89
97
|
controller.send(:validate_session_ip_address)
|
90
98
|
end
|
@@ -92,8 +100,8 @@ describe BindSessionToIpAddressController do
|
|
92
100
|
it "calls reset_session if ip address isn't persisted in session" do
|
93
101
|
session.delete(:ip_address)
|
94
102
|
|
95
|
-
controller.
|
96
|
-
controller.
|
103
|
+
expect(controller).not_to receive(:ip_address_match_with_current?)
|
104
|
+
expect(controller).to receive(:reset_session)
|
97
105
|
|
98
106
|
controller.send(:validate_session_ip_address)
|
99
107
|
end
|
@@ -101,8 +109,8 @@ describe BindSessionToIpAddressController do
|
|
101
109
|
it "calls persist_session_ip_address if validation passes" do
|
102
110
|
session[:ip_address] = "1.3.3.7"
|
103
111
|
|
104
|
-
controller.
|
105
|
-
controller.
|
112
|
+
expect(controller).to receive(:ip_address_match_with_current?).and_return(true)
|
113
|
+
expect(controller).to receive(:persist_session_ip_address)
|
106
114
|
|
107
115
|
controller.send(:validate_session_ip_address)
|
108
116
|
end
|
@@ -112,7 +120,7 @@ describe BindSessionToIpAddressController do
|
|
112
120
|
context ".persist_session_ip_address" do
|
113
121
|
it "sets the current ip address in session on key ip_address" do
|
114
122
|
expect {
|
115
|
-
controller.
|
123
|
+
expect(controller).to receive(:current_ip_address).and_return("1.3.3.7")
|
116
124
|
controller.send(:persist_session_ip_address)
|
117
125
|
}.to change {
|
118
126
|
session[:ip_address]
|
@@ -123,31 +131,31 @@ describe BindSessionToIpAddressController do
|
|
123
131
|
|
124
132
|
context ".current_ip_address" do
|
125
133
|
it "returns the remote_ip from request" do
|
126
|
-
request.
|
134
|
+
expect(request).to receive(:remote_ip).and_return(:request_remote_ip)
|
127
135
|
|
128
|
-
controller.send(:current_ip_address).
|
136
|
+
expect(controller.send(:current_ip_address)).to eql(:request_remote_ip)
|
129
137
|
end
|
130
138
|
end
|
131
139
|
|
132
140
|
|
133
141
|
context ".ip_address_match_with_current?" do
|
134
142
|
it "compares ip address from session with the current ip address" do
|
135
|
-
controller.
|
143
|
+
allow(controller).to receive(:current_ip_address).and_return("1.3.3.7")
|
136
144
|
|
137
145
|
session[:ip_address] = "1.3.3.7"
|
138
146
|
|
139
|
-
controller.send(:ip_address_match_with_current?).
|
147
|
+
expect(controller.send(:ip_address_match_with_current?)).to be_truthy
|
140
148
|
|
141
149
|
session[:ip_address] = "7.3.3.1"
|
142
150
|
|
143
|
-
controller.send(:ip_address_match_with_current?).
|
151
|
+
expect(controller.send(:ip_address_match_with_current?)).to be_falsey
|
144
152
|
end
|
145
153
|
end
|
146
154
|
|
147
155
|
|
148
156
|
context ".reset_session" do
|
149
157
|
it "calls persist_session_ip_address" do
|
150
|
-
controller.
|
158
|
+
expect(controller).to receive(:persist_session_ip_address).and_call_original
|
151
159
|
controller.send(:reset_session)
|
152
160
|
end
|
153
161
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "
|
1
|
+
require "rails_helper"
|
2
2
|
require "support/application_controller"
|
3
3
|
|
4
4
|
|
@@ -6,10 +6,18 @@ class CombinedController < ApplicationController
|
|
6
6
|
include Frikandel::LimitSessionLifetime
|
7
7
|
include Frikandel::BindSessionToIpAddress
|
8
8
|
|
9
|
-
|
9
|
+
if respond_to?(:before_action)
|
10
|
+
before_action :flash_alert_and_redirect_home, only: [:redirect_home]
|
11
|
+
else
|
12
|
+
before_filter :flash_alert_and_redirect_home, only: [:redirect_home]
|
13
|
+
end
|
10
14
|
|
11
15
|
def home
|
12
|
-
|
16
|
+
if Rails::VERSION::MAJOR >= 5
|
17
|
+
render plain: "combined test"
|
18
|
+
else
|
19
|
+
render text: "combined test"
|
20
|
+
end
|
13
21
|
end
|
14
22
|
|
15
23
|
def redirect_home
|
@@ -24,38 +32,38 @@ protected
|
|
24
32
|
end
|
25
33
|
|
26
34
|
|
27
|
-
describe CombinedController do
|
35
|
+
RSpec.describe CombinedController do
|
28
36
|
context "ttl nor ip isn't present in session" do
|
29
37
|
it "resets the session and persists ip address, ttl & max_ttl" do
|
30
38
|
session[:user_id] = 4337
|
31
39
|
|
32
40
|
get :home
|
33
41
|
|
34
|
-
session[:user_id].
|
35
|
-
session[:ip_address].
|
36
|
-
session[:ttl].
|
37
|
-
session[:max_ttl].
|
42
|
+
expect(session[:user_id]).to be_blank
|
43
|
+
expect(session[:ip_address]).to be_present
|
44
|
+
expect(session[:ttl]).to be_present
|
45
|
+
expect(session[:max_ttl]).to be_present
|
38
46
|
end
|
39
47
|
|
40
48
|
it "allows the request to be rendered as normal" do
|
41
49
|
get :home
|
42
50
|
|
43
|
-
response.body.
|
51
|
+
expect(response.body).to eql("combined test")
|
44
52
|
end
|
45
53
|
|
46
54
|
it "persists ttl, max_ttl and ip even on redirect in another before filter" do
|
47
|
-
session[:ip_address].
|
48
|
-
session[:ttl].
|
49
|
-
session[:max_ttl].
|
55
|
+
expect(session[:ip_address]).to be_nil
|
56
|
+
expect(session[:ttl]).to be_nil
|
57
|
+
expect(session[:max_ttl]).to be_nil
|
50
58
|
|
51
59
|
simulate_redirect!(:redirect_home, :home)
|
52
60
|
|
53
|
-
session[:ip_address].
|
54
|
-
session[:ttl].
|
55
|
-
session[:max_ttl].
|
61
|
+
expect(session[:ip_address]).to be_present
|
62
|
+
expect(session[:ttl]).to be_present
|
63
|
+
expect(session[:max_ttl]).to be_present
|
56
64
|
|
57
|
-
flash.
|
58
|
-
flash[:alert].
|
65
|
+
expect(flash).not_to be_empty
|
66
|
+
expect(flash[:alert]).to eql("alert test")
|
59
67
|
end
|
60
68
|
end
|
61
69
|
|
@@ -68,12 +76,12 @@ describe CombinedController do
|
|
68
76
|
|
69
77
|
get :home
|
70
78
|
|
71
|
-
session[:user_id].
|
72
|
-
session[:ip_address].
|
73
|
-
session[:ttl].
|
74
|
-
session[:ttl].
|
75
|
-
session[:max_ttl].
|
76
|
-
session[:max_ttl].
|
79
|
+
expect(session[:user_id]).to be_blank
|
80
|
+
expect(session[:ip_address]).to be_present
|
81
|
+
expect(session[:ttl]).to be_present
|
82
|
+
expect(session[:ttl]).not_to eql(last_ttl)
|
83
|
+
expect(session[:max_ttl]).to be_present
|
84
|
+
expect(session[:max_ttl]).not_to eql(last_max_ttl)
|
77
85
|
end
|
78
86
|
|
79
87
|
it "resets the session and persists ip address, ttl & max_ttl if ttl is missing" do
|
@@ -83,12 +91,12 @@ describe CombinedController do
|
|
83
91
|
|
84
92
|
get :home
|
85
93
|
|
86
|
-
session[:user_id].
|
87
|
-
session[:ip_address].
|
88
|
-
session[:ip_address].
|
89
|
-
session[:ttl].
|
90
|
-
session[:max_ttl].
|
91
|
-
session[:max_ttl].
|
94
|
+
expect(session[:user_id]).to be_blank
|
95
|
+
expect(session[:ip_address]).to be_present
|
96
|
+
expect(session[:ip_address]).to eql("0.0.0.0")
|
97
|
+
expect(session[:ttl]).to be_present
|
98
|
+
expect(session[:max_ttl]).to be_present
|
99
|
+
expect(session[:max_ttl]).not_to eql(last_max_ttl)
|
92
100
|
end
|
93
101
|
|
94
102
|
it "resets the session and persists ip address, ttl & max_ttl if max_ttl is missing" do
|
@@ -98,12 +106,12 @@ describe CombinedController do
|
|
98
106
|
|
99
107
|
get :home
|
100
108
|
|
101
|
-
session[:user_id].
|
102
|
-
session[:ip_address].
|
103
|
-
session[:ip_address].
|
104
|
-
session[:ttl].
|
105
|
-
session[:ttl].
|
106
|
-
session[:max_ttl].
|
109
|
+
expect(session[:user_id]).to be_blank
|
110
|
+
expect(session[:ip_address]).to be_present
|
111
|
+
expect(session[:ip_address]).to eql("0.0.0.0")
|
112
|
+
expect(session[:ttl]).to be_present
|
113
|
+
expect(session[:ttl]).not_to eql(last_ttl)
|
114
|
+
expect(session[:max_ttl]).to be_present
|
107
115
|
end
|
108
116
|
end
|
109
117
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
require "
|
1
|
+
require "rails_helper"
|
2
2
|
require "support/application_controller"
|
3
3
|
|
4
|
+
|
4
5
|
class SessionInvalidError < StandardError; end
|
5
6
|
|
6
7
|
class CustomizedOnInvalidSessionController < ApplicationController
|
@@ -12,8 +13,8 @@ class CustomizedOnInvalidSessionController < ApplicationController
|
|
12
13
|
alias my_on_invalid_session on_invalid_session
|
13
14
|
end
|
14
15
|
|
15
|
-
describe CustomizedOnInvalidSessionController do
|
16
16
|
|
17
|
+
RSpec.describe CustomizedOnInvalidSessionController do
|
17
18
|
it "uses the overwritten on_invalid_cookie function" do
|
18
19
|
get :home
|
19
20
|
request.session[:max_ttl] = 1.minute.ago
|