rddd 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [rDDD@sniffer](https://sniffer.io/info/public-project-135230969156499600) - see the code quality on Sniffer.io
2
+
1
3
  rddd
2
4
  ====
3
5
 
@@ -0,0 +1,42 @@
1
+ module Rddd
2
+ #
3
+ # Authorize plugin stores all the authorization rules
4
+ # and answers the question if specific user is or is
5
+ # not authorized to perform the action considering the
6
+ # parameters as well.
7
+ #
8
+ module Authorization
9
+ class Authorize
10
+ #
11
+ # Initialize.
12
+ #
13
+ # @param {Array} List of Rddd::Authorization::Rule.
14
+ # @param {Object} User we are gonna authorize.
15
+ #
16
+ def initialize(rules, user)
17
+ @rules = rules
18
+ @user = user
19
+ end
20
+
21
+ #
22
+ # Authorize given action.
23
+ #
24
+ # @param {Symbol} Action to be authorized.
25
+ # @param {Hash} Auxiliary attributes to decide authorization.
26
+ #
27
+ def can?(action, params = {})
28
+ rule = find_rule(action)
29
+
30
+ return true unless rule
31
+
32
+ rule.can?(@user, params)
33
+ end
34
+
35
+ private
36
+
37
+ def find_rule(action)
38
+ @rules.find { |rule| rule.is_for?(action) }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,45 @@
1
+ module Rddd
2
+ module Authorization
3
+ #
4
+ # Representation of single authorization rule. It applies
5
+ # to a specific action and evaluates the given block to
6
+ # decide the outcome.
7
+ #
8
+ class Rule
9
+ InvalidEvaluationBlock = Class.new(RuntimeError)
10
+
11
+ #
12
+ # Initialize.
13
+ #
14
+ # @param {Symbol} Action to apply rule to.
15
+ # @param {Block} Block to be evaluated during authorization.
16
+ #
17
+ def initialize(action, &block)
18
+ # Block should take two arguments - user and params.
19
+ raise InvalidEvaluationBlock unless block.arity == 2
20
+
21
+ @action = action
22
+ @block = block
23
+ end
24
+
25
+ #
26
+ # Is the Rule for given action?
27
+ #
28
+ # @param {Symbol} Action to be matched.
29
+ #
30
+ def is_for?(action)
31
+ @action == action
32
+ end
33
+
34
+ #
35
+ # Evalute the rule for a given user and params.
36
+ #
37
+ # @param {Object} User we are gonna authorize.
38
+ # @param {Hash} Auxiliary attributes to decide authorization.
39
+ #
40
+ def can?(user, params)
41
+ @block.call(user, params)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ require 'rddd/authorization/rule'
2
+
3
+ module Rddd
4
+ module Authorization
5
+ #
6
+ # Helper module for building list of authorization rules.
7
+ #
8
+ # Usage:
9
+ #
10
+ # builder = Object.new
11
+ # builder.extends Rddd::Authorization::RulesBuilder
12
+ #
13
+ # builder.can :create_project do |user, params|
14
+ # user.owner? && params[:account_id] == user.account_id
15
+ # end
16
+ #
17
+ #
18
+ # # This part happens inside framework
19
+ # authorizer = Rddd::Authorization::Authorize.new(builder.rules, user)
20
+ # authorizer.can?(:create_project, {:account_id => 123})
21
+ #
22
+ #
23
+ # Call to can method define the rule for a given action. The block
24
+ # always takes the user instance and additional parameters which
25
+ # specify details for the performed action.
26
+ #
27
+ module RulesBuilder
28
+ attr_reader :rules
29
+
30
+ #
31
+ # Create new rule applied to specified action and perform the given
32
+ # block.
33
+ #
34
+ # @param {Symbol} Action the rule applies to.
35
+ # @param {Block} Block to be executed to evaluate authorization.
36
+ #
37
+ def can(action, &block)
38
+ @rules ||= []
39
+
40
+ @rules << Rule.new(action, &block)
41
+ end
42
+ end
43
+ end
44
+ end
data/lib/rddd/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rddd
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require 'rddd/authorization/authorize'
3
+
4
+ describe Rddd::Authorization::Authorize do
5
+ let(:authorize) do
6
+ Rddd::Authorization::Authorize.new(
7
+ rules, user
8
+ )
9
+ end
10
+
11
+ describe '#can?' do
12
+ subject { authorize.can?(action, params) }
13
+
14
+ let(:rule) { stub('rule') }
15
+ let(:rules) { [rule] }
16
+
17
+ let(:user) { stub('user') }
18
+
19
+ let(:params) { {:foo => 'bar'} }
20
+
21
+ let(:action) { :foo }
22
+
23
+ context 'has no rule' do
24
+ let(:rules) { [] }
25
+
26
+ it { should be_true }
27
+ end
28
+
29
+ context 'has aplicable rule which is positive' do
30
+ before do
31
+ rule.expects(:is_for?).with(:foo).returns(true)
32
+ rule.expects(:can?).with(user, params).returns(true)
33
+ end
34
+
35
+ it { should be_true }
36
+ end
37
+
38
+ context 'has applicable rule which is negative' do
39
+ before do
40
+ rule.expects(:is_for?).with(:foo).returns(true)
41
+ rule.expects(:can?).with(user, params).returns(false)
42
+ end
43
+
44
+ it { should be_false }
45
+ end
46
+
47
+ context 'has no applicable rule' do
48
+ before do
49
+ rule.expects(:is_for?).with(:foo).returns(false)
50
+ end
51
+
52
+ it { should be_true }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require 'rddd/authorization/authorize'
3
+ require 'rddd/authorization/rules_builder'
4
+
5
+ describe Rddd::Authorization::Authorize do
6
+ let(:builder) do
7
+ Object.new.tap do |object|
8
+ object.extend Rddd::Authorization::RulesBuilder
9
+
10
+ object.can :create_project do |user, params|
11
+ user.owner? && user.account_id == params[:account_id]
12
+ end
13
+ end
14
+ end
15
+
16
+ describe 'create_project' do
17
+ subject do
18
+ Rddd::Authorization::Authorize.new(builder.rules, user) \
19
+ .can?(:create_project, {:account_id => '1'})
20
+ end
21
+
22
+ context 'user is owner' do
23
+ let(:user) do
24
+ stub('user',
25
+ :owner? => true,
26
+ :account_id => '1'
27
+ )
28
+ end
29
+
30
+ it { should be_true }
31
+ end
32
+
33
+ context 'user is not owner' do
34
+ let(:user) do
35
+ stub('user',
36
+ :owner? => false,
37
+ :account_id => '1'
38
+ )
39
+ end
40
+
41
+ it { should be_false }
42
+ end
43
+
44
+ context 'user is not on same account' do
45
+ let(:user) do
46
+ stub('user',
47
+ :owner? => true,
48
+ :account_id => '2'
49
+ )
50
+ end
51
+
52
+ it { should be_false }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'rddd/authorization/rule'
3
+
4
+ describe Rddd::Authorization::Rule do
5
+
6
+ let(:action) { :foo }
7
+
8
+ let(:block) { lambda { |user, params| true } }
9
+
10
+ let(:authorize) do
11
+ Rddd::Authorization::Rule.new(
12
+ action, &block
13
+ )
14
+ end
15
+
16
+ describe 'should raise if rule block is invalid' do
17
+ let(:block) { lambda { |user| true } }
18
+
19
+ it { expect { authorize }.to raise_exception Rddd::Authorization::Rule::InvalidEvaluationBlock }
20
+ end
21
+
22
+ describe '#is_for?' do
23
+ subject { authorize.is_for?(questioned_action) }
24
+
25
+ context 'matching action' do
26
+ let(:questioned_action) { :foo }
27
+
28
+ it { should be_true }
29
+ end
30
+
31
+ context 'not matching action' do
32
+ let(:questioned_action) { :bar }
33
+
34
+ it { should be_false }
35
+ end
36
+ end
37
+
38
+ describe '#can?' do
39
+ let(:user) { stub('user, params') }
40
+
41
+ let(:params) { stub('user, params') }
42
+
43
+ subject { authorize.can?(user, params) }
44
+
45
+ describe 'passing right params to block' do
46
+ before do
47
+ block.expects(:call).with(user, params).returns(false)
48
+ end
49
+
50
+ it { should be_false }
51
+ end
52
+
53
+ it 'should return true as lambda does' do
54
+ should be_true
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'rddd/authorization/rules_builder'
3
+
4
+ describe Rddd::Authorization::RulesBuilder do
5
+ let(:builder) do
6
+ Object.new.tap do |object|
7
+ object.extend Rddd::Authorization::RulesBuilder
8
+ end
9
+ end
10
+
11
+ describe '#rules' do
12
+ subject { builder.rules }
13
+
14
+ let(:rule) { stub('rule') }
15
+
16
+ let(:action) { :foo }
17
+
18
+ let(:block) { lambda{|user, params| } }
19
+
20
+ before do
21
+ Rddd::Authorization::Rule.expects(:new).returns(rule)
22
+
23
+ builder.can(:foo, &block)
24
+ end
25
+
26
+ its(:first) { should be rule }
27
+ end
28
+
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rddd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -31,6 +31,9 @@ files:
31
31
  - lib/rddd.rb
32
32
  - lib/rddd/aggregate_root.rb
33
33
  - lib/rddd/aggregate_root_finders.rb
34
+ - lib/rddd/authorization/authorize.rb
35
+ - lib/rddd/authorization/rule.rb
36
+ - lib/rddd/authorization/rules_builder.rb
34
37
  - lib/rddd/configuration.rb
35
38
  - lib/rddd/entity.rb
36
39
  - lib/rddd/repository.rb
@@ -42,6 +45,10 @@ files:
42
45
  - rddd.gemspec
43
46
  - spec/integration_spec.rb
44
47
  - spec/lib/aggregate_root_spec.rb
48
+ - spec/lib/authorization/authorize_spec.rb
49
+ - spec/lib/authorization/integration_spec.rb
50
+ - spec/lib/authorization/rule_spec.rb
51
+ - spec/lib/authorization/rules_builder_spec.rb
45
52
  - spec/lib/entity_spec.rb
46
53
  - spec/lib/repository_factory_spec.rb
47
54
  - spec/lib/repository_spec.rb
@@ -78,6 +85,10 @@ summary: Intention of rddd is to provide basic skeleton for DDD ruby application
78
85
  test_files:
79
86
  - spec/integration_spec.rb
80
87
  - spec/lib/aggregate_root_spec.rb
88
+ - spec/lib/authorization/authorize_spec.rb
89
+ - spec/lib/authorization/integration_spec.rb
90
+ - spec/lib/authorization/rule_spec.rb
91
+ - spec/lib/authorization/rules_builder_spec.rb
81
92
  - spec/lib/entity_spec.rb
82
93
  - spec/lib/repository_factory_spec.rb
83
94
  - spec/lib/repository_spec.rb