restrict 0.0.9 → 0.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
- 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.