restrict 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c93762926e3f4b9df38b5ef6a4727a2137722b91
4
- data.tar.gz: 9e40544b25b8bcf811a4de23cfa5ed3c26fce8d4
2
+ SHA256:
3
+ metadata.gz: 40ecfe0fc4a56dfb106d72c936831d92ce4331d0082ead530c5eeaa47762dfcc
4
+ data.tar.gz: 6ae9d487ae24a4c36fb7a8483e04acb1b0ec249cd5d86039638d4279e5d79dd3
5
5
  SHA512:
6
- metadata.gz: a5d3aebcad7634ed0e4f58b61feccbc2435499f5ba9dedfe38f9dbcc697f975d9b46abcf362e3cea32c78627c133a03744499903210533e03f066be903ebd72c
7
- data.tar.gz: 48d33bb786b2bc5d62daa54d680bb373be4dfb8bcbbc9fff957e813b874c32da1157150898ad77ac03c9f6fe298236e3fee4a2bf36bb32082f86bf0f6298b1ce
6
+ metadata.gz: 5c7acadb64232f1b850265207d9288ab4c49bf7481cdf04a033dab7658983a8abfd463cb7c4a15a0d956b6d601dbf279930a0c137908431383d4c75c7a1f97ba
7
+ data.tar.gz: 3e518e19c2fa5a9eaf3ba0239baa0288b6904cc6082077cba046e36b5953ee8631586e58cdbd33cd2779a40c45fbfc8ab9c9c91a60b7d08b98ee9eff2d507c25
@@ -1,3 +1,6 @@
1
+ [0.1.0] - 2019-11-25
2
+ * Support controller inheritance
3
+
1
4
  [0.0.7] - 2014-08-25
2
5
  * Breaking change part 2: restrict without action names will now implicitly restrict all actions
3
6
  * :all_actions modifier is gone
data/README.md CHANGED
@@ -58,6 +58,15 @@ Restrict.config.authentication_validation_method = :admin_session_exists?
58
58
 
59
59
  You may set the method that is used to figure out whether a user is signed in or not to whatever you like, however it's default is `:user_signed_in?` which is the most common (devise) method in use.
60
60
 
61
+ ### Inheritance
62
+
63
+ A controller will respect all restrictions that are applied to its ancestors.
64
+
65
+ You may implement a set of rules in a `BaseController` and refine them in subclasses later on.
66
+
67
+ Please note: it is not possible yet to revert previously added restrictions, that means
68
+ if a restriction on `show` is added in a class and another one in the subclass **BOTH** apply.
69
+
61
70
  ## Contributing
62
71
 
63
72
  You know how this works and bonus points for feature branches!
@@ -0,0 +1,4 @@
1
+ module Restrict
2
+ class AlreadyRestrictedError < Error
3
+ end
4
+ end
@@ -3,24 +3,43 @@ module Restrict
3
3
  module Controller
4
4
  extend ActiveSupport::Concern
5
5
 
6
- included do
7
- class_attribute :restrictions
6
+ def restrictions
7
+ inherited_restrictions + self.class.__send__(:restrict_restrictions)
8
+ end
9
+
10
+ def inherited_restrictions
11
+ self.class.ancestors.map do |ancestor|
12
+ if ancestor.instance_variable_get(:@restrict_gatekeeper_installed)
13
+ ancestor.__send__(:restrict_restrictions)
14
+ end
15
+ end.compact.flatten
8
16
  end
9
17
 
10
18
  module ClassMethods
11
19
  def restrict(*args)
12
20
  install_gatekeeper
13
- self.restrictions ||= []
14
- restrictions << Restrict::Restriction.new(*args)
21
+ restrict_restrictions << Restrict::Restriction.new(*args)
22
+ end
23
+
24
+ # Access the class instance variable. Do not mistake this method with
25
+ # the instance method `#restrictions` which is actually used to determine
26
+ # access and that respects inherited restrictions.
27
+ # Hence the `__` name.
28
+ private def restrict_restrictions
29
+ @restrictions ||= []
30
+ end
31
+
32
+ def inherited(subclass)
33
+ subclass.include Restrict::Rails::Controller
15
34
  end
16
35
 
17
36
  # This could happen in included block as well, but often you need
18
37
  # other before filters to happen before you actually check the
19
38
  # restrictions, so lets set it where it is used in the code as well.
20
39
  def install_gatekeeper
21
- return if @gatekeeper_installed
40
+ return if @restrict_gatekeeper_installed
22
41
  before_action :invoke_gatekeeper
23
- @gatekeeper_installed = true
42
+ @restrict_gatekeeper_installed = true
24
43
  end
25
44
  end
26
45
 
@@ -4,24 +4,23 @@ RSpec::Matchers.define :have_restriction_on do |given_action_name|
4
4
  @given_controller = given_controller
5
5
 
6
6
  @restriction = given_controller.restrictions.find do |restriction|
7
- restriction.applies_to?(given_action_name)
8
- end
9
-
10
- if @restriction
11
- if @given_unless
12
- @restriction.unless == @given_unless
13
- else
14
- true
7
+ if restriction.applies_to?(given_action_name) && matching_unless(restriction, @given_unless)
8
+ restriction
15
9
  end
16
- else
17
- false
18
10
  end
11
+
12
+ !!@restriction
19
13
  end
20
14
 
21
15
  chain :unless do |given_unless|
22
16
  @given_unless = given_unless
23
17
  end
24
18
 
19
+ def matching_unless(restriction, given_unless)
20
+ given_unless or return true
21
+ restriction.unless == given_unless
22
+ end
23
+
25
24
  failure_message do |actual|
26
25
  if @restriction && @given_unless
27
26
  "Expected restriction to call #{@given_unless.inspect}, but calls #{@restriction.unless.inspect}"
@@ -38,7 +37,6 @@ RSpec::Matchers.define :have_restriction_on do |given_action_name|
38
37
  end
39
38
  end
40
39
 
41
- # :nocov:
42
40
  def description
43
41
  "Checks if a restriction for a given action is defined on the controller"
44
42
  end
@@ -4,25 +4,24 @@ RSpec::Matchers.define :have_restriction_on do |given_action_name|
4
4
  @given_controller = given_controller
5
5
 
6
6
  @restriction = given_controller.restrictions.find do |restriction|
7
- restriction.applies_to?(given_action_name)
8
- end
9
-
10
- if @restriction
11
- if @given_unless
12
- @restriction.unless == @given_unless
13
- else
14
- true
7
+ if restriction.applies_to?(given_action_name) && matching_unless(restriction, @given_unless)
8
+ restriction
15
9
  end
16
- else
17
- false
18
10
  end
11
+
12
+ !!@restriction
19
13
  end
20
14
 
21
15
  chain :unless do |given_unless|
22
16
  @given_unless = given_unless
23
17
  end
24
18
 
25
- failure_message_for_should do |actual|
19
+ def matching_unless(restriction, given_unless)
20
+ given_unless or return true
21
+ restriction.unless == given_unless
22
+ end
23
+
24
+ failure_message do |actual|
26
25
  if @restriction && @given_unless
27
26
  "Expected restriction to call #{@given_unless.inspect}, but calls #{@restriction.unless.inspect}"
28
27
  else
@@ -30,7 +29,7 @@ RSpec::Matchers.define :have_restriction_on do |given_action_name|
30
29
  end
31
30
  end
32
31
 
33
- failure_message_for_should_not do |actual|
32
+ failure_message_when_negated do |actual|
34
33
  if @given_unless
35
34
  "Expected restriction not to call #{@given_unless.inspect}, but calls #{@restriction.unless.inspect}"
36
35
  else
@@ -1,3 +1,3 @@
1
1
  module Restrict
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Restrict::Rails::Controller do
4
-
5
4
  let(:controller) { ExampleController.new }
6
5
 
7
6
  before do
@@ -34,4 +33,29 @@ describe Restrict::Rails::Controller do
34
33
  end
35
34
  end
36
35
 
36
+ describe 'in inherited mode' do
37
+ let(:base) { ExampleController.new }
38
+ let(:controller) { InheritingController.new }
39
+ let(:child) { BottomLineController.new }
40
+
41
+ before do
42
+ base.class.restrict :show, unless: :level1?
43
+ controller.class.restrict :show, unless: :level2?
44
+ child.class.restrict :show, unless: :level3?
45
+ end
46
+
47
+ it 'does not leak restrictions into superclass' do
48
+ expect(base).to have_restriction_on(:show).unless(:level1?)
49
+ expect(base).not_to have_restriction_on(:show).unless(:level2?)
50
+ expect(base).not_to have_restriction_on(:show).unless(:level3?)
51
+
52
+ expect(controller).to have_restriction_on(:show).unless(:level1?)
53
+ expect(controller).to have_restriction_on(:show).unless(:level2?)
54
+ expect(controller).not_to have_restriction_on(:show).unless(:level3?)
55
+
56
+ expect(child).to have_restriction_on(:show).unless(:level1?)
57
+ expect(child).to have_restriction_on(:show).unless(:level2?)
58
+ expect(child).to have_restriction_on(:show).unless(:level3?)
59
+ end
60
+ end
37
61
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Restrict do
4
-
5
4
  describe '#config' do
6
5
  it 'returns a configuration' do
7
6
  expect(Restrict.config).to be_a Restrict::Configuration
@@ -17,5 +16,4 @@ describe Restrict do
17
16
  expect(Restrict.config).to eq Restrict.config
18
17
  end
19
18
  end
20
-
21
19
  end
@@ -14,7 +14,9 @@ require 'restrict/rspec/shared_example'
14
14
 
15
15
  RSpec.configure do |config|
16
16
  config.after do
17
- ExampleController.restrictions = []
17
+ ExampleController.__send__(:restrict_restrictions).clear
18
+ InheritingController.__send__(:restrict_restrictions).clear
19
+ BottomLineController.__send__(:restrict_restrictions).clear
18
20
  end
19
21
  end
20
22
 
@@ -45,3 +47,11 @@ class ExampleController < FakeController
45
47
  true
46
48
  end
47
49
  end
50
+
51
+ class InheritingController < ExampleController
52
+ include Restrict::Rails::Controller
53
+ end
54
+
55
+ class BottomLineController < InheritingController
56
+ include Restrict::Rails::Controller
57
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restrict
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johannes Opper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-13 00:00:00.000000000 Z
11
+ date: 2019-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -112,6 +112,7 @@ files:
112
112
  - Rakefile
113
113
  - lib/restrict.rb
114
114
  - lib/restrict/access_denied.rb
115
+ - lib/restrict/already_restricted_error.rb
115
116
  - lib/restrict/configuration.rb
116
117
  - lib/restrict/error.rb
117
118
  - lib/restrict/gatekeeper.rb
@@ -150,8 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
151
  - !ruby/object:Gem::Version
151
152
  version: '0'
152
153
  requirements: []
153
- rubyforge_project:
154
- rubygems_version: 2.6.11
154
+ rubygems_version: 3.0.6
155
155
  signing_key:
156
156
  specification_version: 4
157
157
  summary: Simple access control dsl for controllers.