passpartu 0.3.1 → 0.5.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
  SHA256:
3
- metadata.gz: 0fdefd549a1c4e1cc70e938cfd9e14d1b39ee0686ee011796dd59abf1a3710a3
4
- data.tar.gz: 65579c55e57bdbb8a4de830f2819aaede0aea5c195ad951808a91a88f30263c3
3
+ metadata.gz: cd628d50b6e52acefe4f503c5ada9cec0b224b70be8791fa07f8c5586f93def4
4
+ data.tar.gz: 5314cf52de8c7cf581768ed8842edb1164b3a57c9aa56456a5ed8e5f0dbfd1e9
5
5
  SHA512:
6
- metadata.gz: fd3b87dc5660861a05ac0d76f9bfa87bb6b16cf108e4784ec8a99680030fe3e8631350a901fdc15e87853acb42a4faba971b9cf7b142eafb3536e8b911da0424
7
- data.tar.gz: 2ff8ee8f80752d51fc0fbc332d77bb3441072bdd2df67a1f3e83507160734ff800a5d6c28f529d53317045b8c3f7e9e16279c9dbae2270c32dbc07e91cadf821
6
+ metadata.gz: 7ddafd099269680b9f05dbe140fdd9ebae94eff8072e81073cd5db3840bc8d87d4a8171db637de242df0f19c16043123972f9a8b518228d2e2712aab6559385c
7
+ data.tar.gz: 3f3cab407da0abde8da14764df233c625020d12f8c0d631912d6d009c90bc6fb69d23024aa7d272dc3247009824160df64b816561ec05be43d0fc630b5687d7d
data/README.md CHANGED
@@ -67,6 +67,69 @@ It's possible to use `crud` key to set values for `create`, `read`, `update`, `d
67
67
  `create`, `read`, `update`, `delete` has higher priority than `crud`
68
68
  In case `crud: true` and `delete: false` - result `false`
69
69
 
70
+
71
+ #### Except
72
+ It's possible to exclude role from checks
73
+ ```ruby
74
+ user_admin.can?(:orders, :edit) # check policy for admin and returns true if policy true
75
+ user_admin.can?(:orders, :edit, except: :admin) # returns false because user is admin and we excluded admin
76
+
77
+ ```
78
+ It's possible to give an array as except attribute
79
+
80
+ ```ruby
81
+ user_admin.can?(:orders, :edit, except: [:admin, :manager]) # returns false
82
+ user_manager.can?(:orders, :edit, except: [:admin, :manager]) # returns false
83
+ ```
84
+
85
+ #### Per role methods
86
+ Check user roles AND policy rule
87
+ ```ruby
88
+ # check if user admin AND returns true if policy true
89
+ user_admin.admin_can?(:orders, :edit) # true
90
+
91
+ # check if user manager AND returns true if policy true
92
+ user_admin.manager_can?(:orders, :edit) # false
93
+ ```
94
+
95
+ #### Code blocks
96
+ ```ruby
97
+ # check rules as usual AND code in the block
98
+ user_agent.can?(:orders, :edit, except: [:admin, :manager]) { user_agent.orders.include?(order) }
99
+
100
+ # OR
101
+ user_agent.agent_can?(:orders, :edit, except: [:admin, :manager]) { user_agent.orders.include?(order) }
102
+ ```
103
+
104
+ ##### Real life example
105
+ You need to check custom rule for agent
106
+ ```yml
107
+ # ./config/passpartu.yml
108
+
109
+ admin:
110
+ order:
111
+ create: true
112
+ edit: true
113
+ delete: true
114
+ manager:
115
+ order:
116
+ create: true
117
+ edit: true
118
+ delete: false
119
+ agent:
120
+ order:
121
+ create: true
122
+ edit: true
123
+ delete: false
124
+ ```
125
+
126
+ ```ruby
127
+ user.can?(:order, :edit, except: :agent) || user.agent_can?(:order, :edit) { user.orders.include?(order) }
128
+ ```
129
+
130
+ 1. This code returns `true` if user is `admin` or `manager`
131
+ 1. This code returns `true` if user is `agent` AND if agent policy set to `true` AND if given block returns true
132
+
70
133
  ## Configuration
71
134
 
72
135
  You can configure Passpartu by creating `./config/initializers/passpartu.rb`.
@@ -2,6 +2,7 @@ require 'passpartu/version'
2
2
  require 'yaml'
3
3
  require_relative 'passpartu/patcher'
4
4
  require_relative 'passpartu/verify'
5
+ require_relative 'passpartu/block_verify'
5
6
  require_relative 'passpartu/validate_result'
6
7
  require_relative 'passpartu/user' # for testing only
7
8
 
@@ -0,0 +1,10 @@
1
+ module Passpartu
2
+ class BlockVerify < ::Passpartu::Verify
3
+ def call
4
+ policy_result = super
5
+ return policy_result if block.nil?
6
+
7
+ policy_result && block.call
8
+ end
9
+ end
10
+ end
@@ -11,8 +11,14 @@ module Passpartu
11
11
 
12
12
  def call
13
13
  klass.class_eval do
14
- define_method('can?') do |*keys|
15
- Passpartu::Verify.call(role, keys)
14
+ define_method('can?') do |*keys, except: nil, &block|
15
+ Passpartu::BlockVerify.call(role, keys, except: except, &block)
16
+ end
17
+
18
+ Passpartu.policy.keys.each do |policy_role|
19
+ define_method("#{policy_role}_can?") do |*keys, except: nil, &block|
20
+ role.to_s == policy_role && Passpartu::BlockVerify.call(role, keys, except: except, &block)
21
+ end
16
22
  end
17
23
  end
18
24
  end
@@ -2,18 +2,22 @@ module Passpartu
2
2
  class Verify
3
3
  CRUD_KEY = 'crud'.freeze
4
4
 
5
- attr_reader :role, :keys, :result
6
- def initialize(role, keys)
7
- @role = role
5
+ attr_reader :role, :keys, :result, :except, :block
6
+ def initialize(role, keys, except, block)
7
+ @role = role.to_s
8
8
  @keys = keys.map(&:to_s)
9
+ @except = Array(except).map(&:to_s) if present?(except)
10
+ @block = block
9
11
  end
10
12
 
11
- def self.call(role, keys)
12
- new(role, keys).call
13
+ def self.call(role, keys, except: nil, &block)
14
+ new(role, keys, except, block).call
13
15
  end
14
16
 
15
17
  def call
16
- check
18
+ return false if role_excepted?
19
+
20
+ check_policy
17
21
  check_crud if policy_missed? && last_key_crud?
18
22
 
19
23
  validate_result
@@ -21,13 +25,19 @@ module Passpartu
21
25
 
22
26
  private
23
27
 
24
- def check
25
- @result = Passpartu.policy.dig(role.to_s, *keys)
28
+ def role_excepted?
29
+ return false if blank?(except)
30
+
31
+ except.include?(role)
32
+ end
33
+
34
+ def check_policy
35
+ @result = Passpartu.policy.dig(role, *keys)
26
36
  end
27
37
 
28
38
  def check_crud
29
39
  change_crud_key
30
- check
40
+ check_policy
31
41
  end
32
42
 
33
43
  def change_crud_key
@@ -45,5 +55,13 @@ module Passpartu
45
55
  def last_key_crud?
46
56
  %w[create read update delete].include?(keys[-1])
47
57
  end
58
+
59
+ def blank?(item)
60
+ item.respond_to?(:empty?) ? !!item.empty? : !item
61
+ end
62
+
63
+ def present?(item)
64
+ !blank?(item)
65
+ end
48
66
  end
49
67
  end
@@ -1,3 +1,3 @@
1
1
  module Passpartu
2
- VERSION = '0.3.1'.freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passpartu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OrestF
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-15 00:00:00.000000000 Z
11
+ date: 2019-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -63,6 +63,7 @@ extra_rdoc_files: []
63
63
  files:
64
64
  - README.md
65
65
  - lib/passpartu.rb
66
+ - lib/passpartu/block_verify.rb
66
67
  - lib/passpartu/patcher.rb
67
68
  - lib/passpartu/user.rb
68
69
  - lib/passpartu/validate_result.rb