toni 0.0.2 → 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
2
  SHA1:
3
- metadata.gz: 7ac2b196171e40bf0d69e5c191c4a9435ce3855a
4
- data.tar.gz: 587bbdcb7dd9a86db28551388a8efe786b6ceaa6
3
+ metadata.gz: 14722f9cb78336b60a87caf4ab45e8b7d17c37d1
4
+ data.tar.gz: dd9abb810b120478e41d070d04efe88dc1bd3b80
5
5
  SHA512:
6
- metadata.gz: bdadf5d1db3e86f10963fda52f7b810d2f1ad87c071a0959d871f3f28a9bbac9dae2e28838eeaa7bfb3e4eb9f60ecf7fe88476cb2bff28e00de6415fd940b177
7
- data.tar.gz: aa782e08c89471234beb82c2690f29c6ed0f8a10dc9e597e2ef8cd159784bf86d59278daf56e318301d43d6b83324d4c00e5fb6331618e64e2abca87c3752902
6
+ metadata.gz: 6ba6677c52e0da7577d75865e2f4484b1b353809dfa0b96b081e32ba9faf877fbe70447d05a85e936863275287ff74b1ee0dce03da490b4d55a4f8d9a4507fb2
7
+ data.tar.gz: 267549c89b11bd2c3a9c2a9364c318fdc5e2df5294bb3cb50b6c813224e409677ba74b6c3f23f49b7c90f53bf07485dd5f3cb87087ff9aa4a13868ddad00acbb
@@ -1,5 +1,6 @@
1
1
  require "toni/version"
2
2
  require "toni/anonymous_user"
3
+ require "toni/permission_filter"
3
4
  require "toni/builder"
4
5
 
5
6
  module Toni
@@ -10,6 +11,7 @@ module Toni
10
11
  class NoMethodForMatcherError < StandardError; end
11
12
  class NotAuthorizedError < StandardError; end
12
13
  class MissingMatcherError < StandardError; end
14
+ class MissingPermissionFilterError < StandardError; end
13
15
 
14
16
  class << self
15
17
  def current_user
@@ -40,6 +42,12 @@ module Toni
40
42
  roles.select { |role_symbol, r| current_user.role_symbols.include?(role_symbol) }.values
41
43
  end
42
44
 
45
+ def current_permissions_for(activity, resource_or_name)
46
+ current_roles.map do |r|
47
+ r.permissions_for(activity, resource_or_name)
48
+ end.flatten
49
+ end
50
+
43
51
  def without_authorization(&block)
44
52
  @without_authorization = true
45
53
  result = block_given? ? yield : nil
@@ -0,0 +1,50 @@
1
+ module Toni
2
+ module InModel
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+
6
+ [:create, :update, :destroy].each do |action|
7
+ base.send(:"before_#{action}") do |object|
8
+ activity = action == :destroy ? :delete : action
9
+ Toni.permitted_to?(activity, object, bang: true)
10
+ end
11
+ end
12
+
13
+ base.send(:after_find) do |object|
14
+ Toni.permitted_to?(:read, object, bang: true)
15
+ end
16
+
17
+ # TODO: Should be active record only
18
+ base.scope :permitted_to, -> {
19
+ base.send(:filter_by_permissions)
20
+ }
21
+ end
22
+
23
+ module ClassMethods
24
+
25
+ private
26
+
27
+ def filter_by_permissions
28
+ where(*scope_for_filter_permissions)
29
+ end
30
+
31
+ def scope_for_filter_permissions
32
+ permissions = Toni.current_permissions_for(:read, authorization_context)
33
+ return ["0 = 1"] if permissions.empty?
34
+ permissions.inject([""]) do |cond, p|
35
+ conditions = p.matchers.map(&:filter_condition).compact.inject([""]) do |cond2, filter_cond|
36
+ concat_filters(cond2, filter_cond)
37
+ end
38
+ concat_filters(cond, conditions, " OR ")
39
+ end
40
+ end
41
+
42
+ def concat_filters(cond, conditions, separator=" AND ")
43
+ return cond if conditions[0] == ""
44
+ cond[0] = "#{cond[0]}#{separator unless cond[0].empty?}(#{conditions[0]})"
45
+ cond.push(*conditions[1..-1])
46
+ cond
47
+ end
48
+ end
49
+ end
50
+ end
@@ -12,12 +12,16 @@ module Toni
12
12
  end
13
13
 
14
14
  def add_matcher(method_name, matcher, is_attr = false)
15
- @matchers << PermissionMatcher.new(method_name, matcher, is_attr)
15
+ @matchers << PermissionMatcher::Base.new(method_name, matcher, is_attr)
16
16
  end
17
17
 
18
- def permitted_to?(activity, res, options={})
18
+ def permission_for?(activity, res)
19
19
  resource_name == (res.is_a?(Symbol) ? res : res.class.authorization_context) &&
20
- activities.include?(activity) && matches?(res)
20
+ activities.include?(activity)
21
+ end
22
+
23
+ def permitted_to?(activity, res, options={})
24
+ permission_for?(activity, res) && matches?(res)
21
25
  end
22
26
 
23
27
  private
@@ -0,0 +1,81 @@
1
+ module Toni
2
+ class PermissionFilter
3
+ attr_reader :permission_matcher
4
+
5
+ def self.permission_filters
6
+ @filterable_matchers ||= constants.select do |c|
7
+ const_get(c).is_a?(Class)
8
+ end
9
+ end
10
+
11
+ def initialize(permission_matcher)
12
+ @permission_matcher = permission_matcher
13
+ end
14
+
15
+ def filter_condition
16
+ raise "implement me"
17
+ end
18
+
19
+ def matcher
20
+ permission_matcher.matcher
21
+ end
22
+
23
+ def attr_name
24
+ permission_matcher.method_name
25
+ end
26
+
27
+ class Eq < PermissionFilter
28
+ def filter_condition
29
+ ["#{attr_name} = ?", matcher.expected]
30
+ end
31
+
32
+ def filter_condition_inverse
33
+ ["#{attr_name} != ?", matcher.expected]
34
+ end
35
+ end
36
+
37
+ class BeNil < PermissionFilter
38
+ def filter_condition
39
+ ["#{attr_name} IS NULL"]
40
+ end
41
+
42
+ def filter_condition_inverse
43
+ ["#{attr_name} IS NOT NULL"]
44
+ end
45
+ end
46
+
47
+ class BeTruthy < PermissionFilter
48
+ def filter_condition
49
+ ["#{attr_name} IS NOT NULL AND #{attr_name} != ''"]
50
+ end
51
+
52
+ def filter_condition_inverse
53
+ BeFalsey.new(permission_matcher).filter_condition
54
+ end
55
+ end
56
+
57
+ class BeFalsey < PermissionFilter
58
+ def filter_condition
59
+ ["#{attr_name} = '' OR #{attr_name} IS NULL"]
60
+ end
61
+
62
+ def filter_condition_inverse
63
+ BeTruthy.new(permission_matcher).filter_condition
64
+ end
65
+ end
66
+
67
+ class BeBetween < PermissionFilter
68
+ def filter_condition
69
+ ["#{attr_name} >= ? AND #{attr_name} <= ?",
70
+ matcher.instance_variable_get(:@min),
71
+ matcher.instance_variable_get(:@max)]
72
+ end
73
+
74
+ def filter_condition_inverse
75
+ ["#{attr_name} < ? OR #{attr_name} > ?",
76
+ matcher.instance_variable_get(:@min),
77
+ matcher.instance_variable_get(:@max)]
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,54 +1,4 @@
1
- module Toni
2
- class PermissionMatcher
3
-
4
- attr_reader :method_name, :matcher, :is_attr
5
-
6
- def initialize(method_name, matcher, is_attr = false)
7
- @method_name = method_name
8
- @matcher = matcher
9
- @is_attr = is_attr
10
- end
11
-
12
- def matches?(object)
13
- unless object.respond_to?(method_name)
14
- raise Toni::NoMethodForMatcherError.new("#{method_name} is not defined for #{object.inspect}")
15
- end
16
- matcher.matches?(object.send(method_name))
17
- end
18
-
19
- class NotMatcher
20
- attr_reader :matcher
21
-
22
- def initialize
23
- @matcher = nil
24
- end
25
-
26
- def method_missing(method_name, *args)
27
- builder = Toni::Builder::ExpectationBuilder.new
28
- if builder.respond_to?(method_name)
29
- @matcher = builder.send(method_name, *args)
30
- else
31
- super
32
- end
33
- end
34
-
35
- def matches?(object)
36
- raise Toni::MissingMatcherError if @matcher.nil?
37
- !@matcher.matches?(object)
38
- end
39
- end
40
-
41
- class PermittedToMatcher
42
-
43
- def initialize(activity)
44
- @activity = activity
45
- end
46
-
47
- def matches?(object)
48
- Toni.permitted_to?(@activity, object)
49
- end
50
-
51
- end
52
-
53
- end
54
- end
1
+ require 'toni/permission_matcher/has_matcher'
2
+ require 'toni/permission_matcher/base'
3
+ require 'toni/permission_matcher/not_matcher'
4
+ require 'toni/permission_matcher/permitted_to_matcher'
@@ -0,0 +1,31 @@
1
+ module Toni
2
+ module PermissionMatcher
3
+
4
+ class Base
5
+
6
+ include HasMatcher
7
+
8
+ attr_reader :method_name, :is_attr
9
+
10
+ def initialize(method_name, matcher, is_attr = false)
11
+ @method_name = method_name
12
+ @matcher = matcher
13
+ @is_attr = is_attr
14
+ end
15
+
16
+ def matches?(object)
17
+ unless object.respond_to?(method_name)
18
+ raise Toni::NoMethodForMatcherError.new("#{method_name} is not defined for #{object.inspect}")
19
+ end
20
+ matcher.matches?(object.send(method_name))
21
+ end
22
+
23
+ def filter_condition
24
+ return nil unless is_attr
25
+ super
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ module Toni
2
+ module PermissionMatcher
3
+
4
+ module HasMatcher
5
+
6
+ def self.included(base)
7
+ base.send(:attr_reader, :matcher)
8
+ end
9
+
10
+ def matches?(object)
11
+ raise "implement me"
12
+ end
13
+
14
+ def filter_condition
15
+ return matcher.filter_condition if matcher.respond_to?(:filter_condition)
16
+
17
+ filter = permission_filter
18
+ if filter.nil?
19
+ raise Toni::MissingPermissionFilterError.new("No permission matcher for #{matcher.class.inspect}")
20
+ end
21
+
22
+ filter.filter_condition
23
+ end
24
+
25
+ private
26
+
27
+ def permission_filter
28
+ if permission_filter_class
29
+ Toni::PermissionFilter.const_get(permission_filter_class).new(self)
30
+ end
31
+ end
32
+
33
+ def permission_filter_class
34
+ @permission_filter ||= Toni::PermissionFilter.permission_filters.detect do |c|
35
+ !matcher.class.name.nil? && c.to_s.split('::').last == matcher.class.name.split('::').last
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ module Toni
2
+ module PermissionMatcher
3
+
4
+ class NotMatcher
5
+
6
+ include HasMatcher
7
+
8
+ def initialize
9
+ @matcher = nil
10
+ end
11
+
12
+ def method_missing(method_name, *args)
13
+ builder = Toni::Builder::ExpectationBuilder.new
14
+ if builder.respond_to?(method_name)
15
+ @matcher = builder.send(method_name, *args)
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ def matches?(object)
22
+ raise Toni::MissingMatcherError if @matcher.nil?
23
+ !@matcher.matches?(object)
24
+ end
25
+
26
+ def filter_condition
27
+ filter = permission_filter
28
+ unless filter && filter.respond_to?(:filter_condition_inverse)
29
+ raise Toni::MissingPermissionFilterError.new("No permission matcher for #{matcher.class.inspect}")
30
+ end
31
+
32
+ filter.filter_condition_inverse
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ module Toni
2
+ module PermissionMatcher
3
+ class PermittedToMatcher
4
+
5
+ def initialize(activity)
6
+ @activity = activity
7
+ end
8
+
9
+ def matches?(object)
10
+ Toni.permitted_to?(@activity, object)
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -26,6 +26,14 @@ module Toni
26
26
  end
27
27
  end
28
28
 
29
+ def permissions_for(activity, res)
30
+ unless res.is_a?(Symbol) || res.class.respond_to?(:authorization_context)
31
+ raise Toni::NoAuthorizationContextProvidedError
32
+ end
33
+ res = res.class.authorization_context unless res.is_a?(Symbol)
34
+ current_permissions.select { |p| p.permission_for?(activity, res) }
35
+ end
36
+
29
37
  private
30
38
 
31
39
  def current_permissions
@@ -1,3 +1,3 @@
1
1
  module Toni
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,135 @@
1
+ require "toni"
2
+ require "toni/in_model"
3
+ require "active_record"
4
+ require "spec_helper"
5
+
6
+ describe Toni::InModel do
7
+ let(:record_class) do
8
+ Class.new(ActiveRecord::Base) do
9
+ def self.table_name
10
+ :test
11
+ end
12
+ def self.authorization_context
13
+ :resource_name
14
+ end
15
+ end
16
+ end
17
+
18
+ let(:record) { record_class.new }
19
+
20
+ before do
21
+ record_class.destroy_all
22
+ allow(Toni).to receive(:current_roles) { [] }
23
+ end
24
+
25
+ context :before_filter do
26
+ it "adds before filter on include" do
27
+ expect(record_class).to receive(:before_destroy)
28
+ expect(record_class).to receive(:before_create)
29
+ expect(record_class).to receive(:before_update)
30
+ expect(record_class).to receive(:after_find)
31
+ record_class.send(:include, Toni::InModel)
32
+ end
33
+
34
+ it "calls permitted_to? if records gets found" do
35
+ record_class.send(:include, Toni::InModel)
36
+ Toni.without_authorization { record.save }
37
+ allow(Toni).to receive(:permitted_to?) { true }
38
+ expect(Toni).to receive(:permitted_to?).with(:read, record_class, bang: true)
39
+ record_class.find(record.id)
40
+ end
41
+
42
+ it "calls permitted_to? if records gets created" do
43
+ record_class.send(:include, Toni::InModel)
44
+ allow(Toni).to receive(:permitted_to?) { true }
45
+ expect(Toni).to receive(:permitted_to?).with(:create, record_class, bang: true)
46
+ record.save
47
+ end
48
+
49
+ it "calls permitted_to? if records gets updated" do
50
+ record_class.send(:include, Toni::InModel)
51
+ allow(Toni).to receive(:permitted_to?) { true }
52
+ record.save
53
+ record.foo = :x
54
+ expect(Toni).to receive(:permitted_to?).with(:update, record_class, bang: true)
55
+ record.save
56
+ end
57
+
58
+ it "calls permitted_to? if records gets destroyes" do
59
+ record_class.send(:include, Toni::InModel)
60
+ allow(Toni).to receive(:permitted_to?) { true }
61
+ record.save
62
+ expect(Toni).to receive(:permitted_to?).with(:delete, record_class, bang: true)
63
+ record.destroy
64
+ end
65
+
66
+ it "does not create record if permitted_to bangs" do
67
+ record_class.send(:include, Toni::InModel)
68
+ allow(Toni).to receive(:permitted_to?) { raise Toni::NotAuthorizedError }
69
+ expect { record.save }.to raise_error(Toni::NotAuthorizedError)
70
+ expect(record_class.count).to eq(0)
71
+ end
72
+
73
+ it "does not update record if permitted_to bangs" do
74
+ record_class.send(:include, Toni::InModel)
75
+ Toni.without_authorization { record.save }
76
+ allow(Toni).to receive(:permitted_to?) { raise Toni::NotAuthorizedError }
77
+ record.foo = :x
78
+ expect { record.save }.to raise_error(Toni::NotAuthorizedError)
79
+ expect(record_class.count).to eq(1)
80
+ allow(Toni).to receive(:permitted_to?) { true }
81
+ expect(record_class.first.foo).to be_nil
82
+ end
83
+
84
+ it "does not destroy record if permitted_to bangs" do
85
+ record_class.send(:include, Toni::InModel)
86
+ Toni.without_authorization { record.save }
87
+ allow(Toni).to receive(:permitted_to?) { raise Toni::NotAuthorizedError }
88
+ expect { record.destroy }.to raise_error(Toni::NotAuthorizedError)
89
+ expect(record_class.count).to eq(1)
90
+ end
91
+ end
92
+
93
+ context :scope do
94
+
95
+ let(:matcher) { RSpec::Matchers::BuiltIn::BeNil.new }
96
+ let(:matcher2) { RSpec::Matchers::BuiltIn::Eq.new("x") }
97
+ let(:matcher3) { RSpec::Matchers::BuiltIn::Eq.new("y") }
98
+ let(:permission) do
99
+ p = Toni::Permission.new(:resource_name, [:read, :create])
100
+ p.add_matcher(:foo, matcher, true)
101
+ p.add_matcher(:bar, matcher2, true)
102
+ p
103
+ end
104
+ let(:permission2) do
105
+ p = Toni::Permission.new(:resource_name, [:read])
106
+ p.add_matcher(:foo, matcher3, true)
107
+ p
108
+ end
109
+
110
+ it "creates a scope" do
111
+ expect(record_class).to receive(:scope).with(:permitted_to, anything)
112
+ record_class.send(:include, Toni::InModel)
113
+ end
114
+
115
+ it "creates a useful scope" do
116
+ record_class.send(:include, Toni::InModel)
117
+ allow(Toni).to receive(:current_permissions_for).with(:read, :resource_name) do
118
+ [permission, permission2]
119
+ end
120
+ expect(record_class.send(:scope_for_filter_permissions)).to eq(["((foo IS NULL) AND (bar = ?)) OR ((foo = ?))", "x", "y"])
121
+ end
122
+
123
+ it "scopes permitted_to" do
124
+ allow(Toni).to receive(:current_permissions_for).with(:read, :resource_name) do
125
+ [permission, permission2]
126
+ end
127
+ record_class.send(:include, Toni::InModel)
128
+ allow(Toni).to receive(:permitted_to?) { true }
129
+ r1 = record_class.create(foo: "x", bar: "y")
130
+ r2 = record_class.create(foo: nil, bar: "x")
131
+ r3 = record_class.create(foo: "y", bar: "something")
132
+ expect(record_class.permitted_to.map(&:id)).to eq([r2.id, r3.id])
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+ require "toni"
3
+ require "ostruct"
4
+
5
+ describe Toni::PermissionFilter do
6
+
7
+ let(:expectation_builder) { Toni::Builder::ExpectationBuilder.new }
8
+ let(:matcher) { expectation_builder.eq("test") }
9
+ let(:permission_matcher) { Toni::PermissionMatcher::Base.new(:foo, matcher, true) }
10
+
11
+ let(:permission_filter) do
12
+ described_class.new(permission_matcher)
13
+ end
14
+
15
+ describe ".permission_filters" do
16
+ it "returns constants of available permission filters" do
17
+ expect(Toni::PermissionFilter.permission_filters).to match_array([
18
+ :Eq, :BeNil, :BeTruthy, :BeFalsey, :BeBetween
19
+ ])
20
+ end
21
+ end
22
+
23
+ describe Toni::PermissionFilter::Eq do
24
+ it "creates condition" do
25
+ expect(permission_filter.filter_condition).to eq(["foo = ?", "test"])
26
+ end
27
+ it "creates opposite condition" do
28
+ expect(permission_filter.filter_condition_inverse).to eq(["foo != ?", "test"])
29
+ end
30
+ end
31
+
32
+ describe Toni::PermissionFilter::BeNil do
33
+ it "creates condition" do
34
+ expect(permission_filter.filter_condition).to eq(["foo IS NULL"])
35
+ end
36
+ it "creates opposite condition" do
37
+ expect(permission_filter.filter_condition_inverse).to eq(["foo IS NOT NULL"])
38
+ end
39
+ end
40
+
41
+ describe Toni::PermissionFilter::BeTruthy do
42
+ it "creates condition" do
43
+ expect(permission_filter.filter_condition).to eq(["foo IS NOT NULL AND foo != ''"])
44
+ end
45
+ it "creates opposite condition" do
46
+ expect(permission_filter.filter_condition_inverse).to eq(["foo = '' OR foo IS NULL"])
47
+ end
48
+ end
49
+
50
+ describe Toni::PermissionFilter::BeFalsey do
51
+ it "creates condition" do
52
+ expect(permission_filter.filter_condition).to eq(["foo = '' OR foo IS NULL"])
53
+ end
54
+ it "creates opposite condition" do
55
+ expect(permission_filter.filter_condition_inverse).to eq(["foo IS NOT NULL AND foo != ''"])
56
+ end
57
+ end
58
+
59
+ describe Toni::PermissionFilter::BeBetween do
60
+ let(:matcher) { expectation_builder.be_between(5, 10) }
61
+ it "creates condition" do
62
+ expect(permission_filter.filter_condition).to eq(["foo >= ? AND foo <= ?", 5, 10])
63
+ end
64
+ it "creates opposite condition" do
65
+ expect(permission_filter.filter_condition_inverse).to eq(["foo < ? OR foo > ?", 5, 10])
66
+ end
67
+ end
68
+
69
+ end
@@ -12,11 +12,11 @@ describe Toni::PermissionMatcher do
12
12
  end
13
13
  end.new
14
14
  end
15
- let(:permission_matcher) { Toni::PermissionMatcher.new(:foo, matcher) }
15
+ let(:permission_matcher) { Toni::PermissionMatcher::Base.new(:foo, matcher) }
16
16
 
17
17
  describe :method_name do
18
18
  it "sets the method_name on initialize" do
19
- expect(Toni::PermissionMatcher.new(:method_name, nil).method_name).to eq(:method_name)
19
+ expect(Toni::PermissionMatcher::Base.new(:method_name, nil).method_name).to eq(:method_name)
20
20
  end
21
21
  end
22
22
 
@@ -32,6 +32,33 @@ describe Toni::PermissionMatcher do
32
32
  end
33
33
  end
34
34
 
35
+ describe :filter_condition do
36
+ let(:expectation_builder) { Toni::Builder::ExpectationBuilder.new }
37
+ let(:matcher2) { expectation_builder.eq("test") }
38
+ let(:permission_matcher) { Toni::PermissionMatcher::Base.new(:foo, matcher2, true) }
39
+
40
+ it "return nil if is_attr is false" do
41
+ permission_matcher = Toni::PermissionMatcher::Base.new(:foo, matcher2, false)
42
+ expect(permission_matcher.filter_condition).to eq(nil)
43
+ end
44
+
45
+ it "gets filter condition from filterable permission matcher if it exist" do
46
+ expect_any_instance_of(Toni::PermissionFilter::Eq).to receive(:filter_condition)
47
+ permission_matcher.filter_condition
48
+ end
49
+
50
+ it "raises error when permission matcher is not available" do
51
+ allow(permission_matcher).to receive(:permission_filter) { nil }
52
+ expect { permission_matcher.filter_condition }.to raise_error(Toni::MissingPermissionFilterError)
53
+ end
54
+
55
+ it "uses filter_condition method of matcher if matcher responds" do
56
+ allow(matcher2).to receive(:respond_to?) { true }
57
+ expect(matcher2).to receive(:filter_condition) { "condition" }
58
+ expect(permission_matcher.filter_condition).to eq("condition")
59
+ end
60
+ end
61
+
35
62
  describe :matches? do
36
63
  let(:object) do
37
64
  Class.new do
@@ -66,14 +93,14 @@ describe Toni::PermissionMatcher do
66
93
 
67
94
  it "returns true if matcher is rspec nil matcher and value is nil" do
68
95
  matcher = RSpec::Matchers::BuiltIn::BeNil.new
69
- permission_matcher = Toni::PermissionMatcher.new(:foo, matcher)
96
+ permission_matcher = Toni::PermissionMatcher::Base.new(:foo, matcher)
70
97
  expect(permission_matcher.matches?(object)).to eq(true)
71
98
  end
72
99
 
73
100
  it "returns false if matcher is rspec nil matcher and value is not nil" do
74
101
  allow(object).to receive(:foo) { "a string" }
75
102
  matcher = RSpec::Matchers::BuiltIn::BeNil.new
76
- permission_matcher = Toni::PermissionMatcher.new(:foo, matcher)
103
+ permission_matcher = Toni::PermissionMatcher::Base.new(:foo, matcher)
77
104
  expect(permission_matcher.matches?(object)).to eq(false)
78
105
  end
79
106
  end
@@ -103,6 +130,20 @@ describe Toni::PermissionMatcher::NotMatcher do
103
130
  end
104
131
  end
105
132
 
133
+ describe :filter_condition do
134
+ it "gets filter condition from child matcher if it responds to filter_condition_inverse" do
135
+ not_matcher.be_truthy
136
+ expect_any_instance_of(Toni::PermissionFilter::BeTruthy).to receive(:filter_condition_inverse)
137
+ not_matcher.filter_condition
138
+ end
139
+
140
+ it "raises error when child matcher does not respond to filter_condition_inverse" do
141
+ not_matcher.be_truthy
142
+ allow_any_instance_of(Toni::PermissionFilter::BeTruthy).to receive(:respond_to?) { false }
143
+ expect { not_matcher.filter_condition }.to raise_error(Toni::MissingPermissionFilterError)
144
+ end
145
+ end
146
+
106
147
  end
107
148
 
108
149
  describe Toni::PermissionMatcher::PermittedToMatcher do
@@ -21,7 +21,22 @@ describe Toni::Permission do
21
21
  describe :add_matcher do
22
22
  it "adds the matcher" do
23
23
  permission.add_matcher(:foo, nil)
24
- expect(permission.matchers.first).to be_instance_of(Toni::PermissionMatcher)
24
+ expect(permission.matchers.first).to be_instance_of(Toni::PermissionMatcher::Base)
25
+ end
26
+ end
27
+
28
+ describe :permission_for? do
29
+ let(:permission) do
30
+ Toni::Permission.new(:resource_name, [:read, :create])
31
+ end
32
+ it "should be allowed to read resource_name" do
33
+ expect(permission.permission_for?(:read, :resource_name)).to eq(true)
34
+ end
35
+ it "should be allowed to delete resource_name" do
36
+ expect(permission.permission_for?(:delete, :resource_name)).to eq(false)
37
+ end
38
+ it "should be allowed to read xxx" do
39
+ expect(permission.permission_for?(:read, :xxx)).to eq(false)
25
40
  end
26
41
  end
27
42
 
@@ -31,16 +46,9 @@ describe Toni::Permission do
31
46
  Toni::Permission.new(:resource_name, [:read, :create])
32
47
  end
33
48
 
34
- context "with resource_name" do
35
- it "should be allowed to read resource_name" do
36
- expect(permission.permitted_to?(:read, :resource_name)).to eq(true)
37
- end
38
- it "should be allowed to delete resource_name" do
39
- expect(permission.permitted_to?(:delete, :resource_name)).to eq(false)
40
- end
41
- it "should be allowed to read xxx" do
42
- expect(permission.permitted_to?(:read, :xxx)).to eq(false)
43
- end
49
+ it "calls permission_for?" do
50
+ expect(permission).to receive(:permission_for?).with(:read, :resource_name) { true }
51
+ expect(permission.permitted_to?(:read, :resource_name)).to eq(true)
44
52
  end
45
53
 
46
54
  context "with matchers" do
@@ -34,6 +34,26 @@ describe Toni::Role do
34
34
  end
35
35
  end
36
36
 
37
+ describe :permissions_for do
38
+
39
+ let(:permission) { Toni::Permission.new(:resource_name, [:read, :create]) }
40
+ let(:permission2) { Toni::Permission.new(:other_resource, [:read, :create]) }
41
+
42
+ let(:role) do
43
+ role = Toni::Role.new(:user)
44
+ role.add_permission(permission)
45
+ role.add_permission(permission2)
46
+ role
47
+ end
48
+
49
+ it "returns all permissions that are belonging to resource and activity" do
50
+ allow(permission).to receive(:permission_for?).with(:read, :resource_name) { true }
51
+ allow(permission2).to receive(:permission_for?).with(:read, :resource_name) { false }
52
+ expect(role.permissions_for(:read, :resource_name)).to eq([permission])
53
+ end
54
+
55
+ end
56
+
37
57
  describe :permitted_to? do
38
58
 
39
59
  let(:permission) do
@@ -56,6 +56,19 @@ describe Toni do
56
56
  end
57
57
  end
58
58
 
59
+ describe ".current_permissions_for" do
60
+ let(:user_role) { Toni::Role.new(:user) }
61
+ let(:seller_role) { Toni::Role.new(:seller) }
62
+ let(:permission1) { Toni::Permission.new(:books, [:read]) }
63
+ let(:permission2) { Toni::Permission.new(:books, [:read]) }
64
+ it "gets the permissions that are assigned to current roles for a specific resource" do
65
+ allow(Toni).to receive(:current_roles) { [user_role, seller_role] }
66
+ expect(user_role).to receive(:permissions_for).with(:read, :books) { [permission1] }
67
+ expect(seller_role).to receive(:permissions_for).with(:read, :books) { [permission2] }
68
+ expect(Toni.current_permissions_for(:read, :books)).to eq([permission1, permission2])
69
+ end
70
+ end
71
+
59
72
  describe ".without_authorization" do
60
73
  it "executes block without authorization and returns result of the given block" do
61
74
  with_authorization = Toni.permitted_to?(:something, :test)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toni
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jalyna
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-10 00:00:00.000000000 Z
11
+ date: 2014-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-expectations
@@ -131,8 +131,14 @@ files:
131
131
  - lib/toni.rb
132
132
  - lib/toni/anonymous_user.rb
133
133
  - lib/toni/builder.rb
134
+ - lib/toni/in_model.rb
134
135
  - lib/toni/permission.rb
136
+ - lib/toni/permission_filter.rb
135
137
  - lib/toni/permission_matcher.rb
138
+ - lib/toni/permission_matcher/base.rb
139
+ - lib/toni/permission_matcher/has_matcher.rb
140
+ - lib/toni/permission_matcher/not_matcher.rb
141
+ - lib/toni/permission_matcher/permitted_to_matcher.rb
136
142
  - lib/toni/role.rb
137
143
  - lib/toni/rspec_helper.rb
138
144
  - lib/toni/sinatra.rb
@@ -140,6 +146,8 @@ files:
140
146
  - spec/spec_helper.rb
141
147
  - spec/toni/anonymous_user_spec.rb
142
148
  - spec/toni/builder_spec.rb
149
+ - spec/toni/in_model_spec.rb
150
+ - spec/toni/permission_filter_spec.rb
143
151
  - spec/toni/permission_matcher_spec.rb
144
152
  - spec/toni/permission_spec.rb
145
153
  - spec/toni/role_spec.rb
@@ -177,6 +185,8 @@ test_files:
177
185
  - spec/spec_helper.rb
178
186
  - spec/toni/anonymous_user_spec.rb
179
187
  - spec/toni/builder_spec.rb
188
+ - spec/toni/in_model_spec.rb
189
+ - spec/toni/permission_filter_spec.rb
180
190
  - spec/toni/permission_matcher_spec.rb
181
191
  - spec/toni/permission_spec.rb
182
192
  - spec/toni/role_spec.rb