passpartu 1.0.3 → 1.1.1
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 +4 -4
- data/README.md +13 -10
- data/lib/passpartu/patcher.rb +23 -7
- data/lib/passpartu/{user.rb → test_user.rb} +10 -2
- data/lib/passpartu/verify.rb +12 -7
- data/lib/passpartu/version.rb +1 -1
- data/lib/passpartu.rb +3 -2
- data/passpartu.gemspec +1 -0
- metadata +18 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10de14cce11b5f7b38f3ff759c2d24b5a7044744f137b5f2e46ab65975b5b6c2
|
|
4
|
+
data.tar.gz: 7731b1ad92a9f96da5f54c1d2f018f0925297464c15fdfc5aa7bdc464da637a6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b5072898c8144f59252a1b74fd10c671a84b328d9920344eaf7ceca7ace5c642faea0a782cc114ec240db3552cf14549cd094a555c545566a5df5c0a46eba31
|
|
7
|
+
data.tar.gz: 4424887961ea98e0b405c4f0768a9c0a7a6e3280a4e131c805d0b7b5ba3aa18fa52fb826f8f0fca55e80ee10b9acdce97639b71c595a259a6b09d9486b2b8811
|
data/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
# Passpartu
|
|
1
|
+
# Passpartu - [changelog](https://github.com/coaxsoft/passpartu/blob/master/CHANGELOG.md)
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/passpartu)
|
|
2
4
|
|
|
3
5
|
Passpartu makes policies great again (works awesome with [Pundit](https://rubygems.org/gems/pundit)).
|
|
4
6
|
|
|
5
7
|
### Tested with ruby:
|
|
6
|
-
- 2.7.3
|
|
7
|
-
- 3.0.0
|
|
8
8
|
- 3.1.1
|
|
9
|
+
- 3.0.0
|
|
10
|
+
- 2.7.3
|
|
9
11
|
|
|
10
12
|
Instead of this:
|
|
11
13
|
|
|
@@ -78,7 +80,7 @@ admin:
|
|
|
78
80
|
|
|
79
81
|
## Features
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
### CRUD
|
|
82
84
|
|
|
83
85
|
It's possible to use `crud` key to set values for `create`, `read`, `update`, `delete` at once.
|
|
84
86
|
`create`, `read`, `update`, `delete` has higher priority than `crud`
|
|
@@ -86,7 +88,7 @@ It's possible to use `crud` key to set values for `create`, `read`, `update`, `d
|
|
|
86
88
|
In case `crud: true` and `delete: false` - result `false`
|
|
87
89
|
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
### Only
|
|
90
92
|
|
|
91
93
|
It's possible to include specific roles to checks
|
|
92
94
|
|
|
@@ -109,7 +111,7 @@ Note: `only` has higher priority than `except/skip`. Do not use both.
|
|
|
109
111
|
user_admin.can?(:orders, :edit, only: :admin, except: :admin) # returns true
|
|
110
112
|
```
|
|
111
113
|
|
|
112
|
-
|
|
114
|
+
### Skip (except)
|
|
113
115
|
|
|
114
116
|
It's possible to exclude roles from checks
|
|
115
117
|
|
|
@@ -136,7 +138,7 @@ Note: `expect` has higher priority than `skip`. Do not use both.
|
|
|
136
138
|
user_agent.can?(:orders, :edit, skip: [:admin, :manager]) { user_agent.orders.include?(order) }
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
|
|
141
|
+
### Per role methods
|
|
140
142
|
|
|
141
143
|
Check user roles AND policy rule
|
|
142
144
|
|
|
@@ -148,7 +150,7 @@ Check user roles AND policy rule
|
|
|
148
150
|
user_admin.manager_can?(:orders, :edit) # false
|
|
149
151
|
```
|
|
150
152
|
|
|
151
|
-
|
|
153
|
+
### Code blocks
|
|
152
154
|
|
|
153
155
|
```ruby
|
|
154
156
|
# check rules as usual AND code in the block
|
|
@@ -158,7 +160,7 @@ Check user roles AND policy rule
|
|
|
158
160
|
user_agent.agent_can?(:orders, :edit, except: [:admin, :manager]) { user_agent.orders.include?(order) }
|
|
159
161
|
```
|
|
160
162
|
|
|
161
|
-
|
|
163
|
+
### Waterfall check
|
|
162
164
|
|
|
163
165
|
Allow or restrict absolutely everything for particular role or/and particular domain.
|
|
164
166
|
|
|
@@ -190,7 +192,7 @@ user_medium_loser.can?(:orders, :delete) # false
|
|
|
190
192
|
user_medium_loser.can?(:products, :create) # true
|
|
191
193
|
user_medium_loser.can?(:products, :create, :and_delete) # true
|
|
192
194
|
```
|
|
193
|
-
|
|
195
|
+
#### Real life example
|
|
194
196
|
|
|
195
197
|
You need to check custom rule for agent
|
|
196
198
|
|
|
@@ -232,6 +234,7 @@ Passpartu.configure do |config|
|
|
|
232
234
|
config.policy_file = './config/passpartu.yml'
|
|
233
235
|
config.raise_policy_missed_error = true
|
|
234
236
|
config.check_waterfall = false
|
|
237
|
+
config.role_access_method = :role
|
|
235
238
|
end
|
|
236
239
|
|
|
237
240
|
```
|
data/lib/passpartu/patcher.rb
CHANGED
|
@@ -15,18 +15,34 @@ module Passpartu
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def call
|
|
18
|
+
phash = respond_to?(:policy_hash) ? {} : Passpartu.policy
|
|
19
|
+
role_method = Passpartu.config.role_access_method
|
|
20
|
+
|
|
18
21
|
klass.class_eval do
|
|
19
22
|
define_method(:can?) do |*keys, only: nil, except: nil, skip: nil, &block|
|
|
20
|
-
Passpartu::BlockVerify.call(
|
|
23
|
+
Passpartu::BlockVerify.call(
|
|
24
|
+
send(role_method),
|
|
25
|
+
keys,
|
|
26
|
+
only: only,
|
|
27
|
+
except: except,
|
|
28
|
+
skip: skip,
|
|
29
|
+
policy_hash: phash,
|
|
30
|
+
&block
|
|
31
|
+
)
|
|
21
32
|
end
|
|
22
33
|
|
|
23
|
-
|
|
34
|
+
phash.each_key do |policy_role|
|
|
24
35
|
define_method("#{policy_role}_can?") do |*keys, only: nil, except: nil, skip: nil, &block|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
send(role_method).to_s == policy_role &&
|
|
37
|
+
Passpartu::BlockVerify.call(
|
|
38
|
+
send(role_method),
|
|
39
|
+
keys,
|
|
40
|
+
only: only,
|
|
41
|
+
except: except,
|
|
42
|
+
skip: skip,
|
|
43
|
+
policy_hash: phash,
|
|
44
|
+
&block
|
|
45
|
+
)
|
|
30
46
|
end
|
|
31
47
|
end
|
|
32
48
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# for testing only
|
|
4
4
|
|
|
5
5
|
module Passpartu
|
|
6
|
-
class
|
|
6
|
+
class TestUser
|
|
7
7
|
attr_reader :role
|
|
8
8
|
|
|
9
9
|
def initialize(role)
|
|
@@ -11,11 +11,19 @@ module Passpartu
|
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
class
|
|
14
|
+
class TestPerson
|
|
15
15
|
attr_reader :role
|
|
16
16
|
|
|
17
17
|
def initialize(role)
|
|
18
18
|
@role = role
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
+
|
|
22
|
+
class TestUserWithOtherRoleMethod
|
|
23
|
+
attr_reader :other_role_method
|
|
24
|
+
|
|
25
|
+
def initialize(role)
|
|
26
|
+
@other_role_method = role
|
|
27
|
+
end
|
|
28
|
+
end
|
|
21
29
|
end
|
data/lib/passpartu/verify.rb
CHANGED
|
@@ -4,9 +4,9 @@ module Passpartu
|
|
|
4
4
|
class Verify
|
|
5
5
|
CRUD_KEY = 'crud'
|
|
6
6
|
|
|
7
|
-
attr_reader :role, :keys, :result, :only, :except, :block
|
|
7
|
+
attr_reader :role, :keys, :result, :only, :except, :block, :policy_hash
|
|
8
8
|
|
|
9
|
-
def initialize(role, keys, only, except, skip, block)
|
|
9
|
+
def initialize(role, keys, only, except, skip, policy_hash, &block)
|
|
10
10
|
exclusion = except || skip # alias
|
|
11
11
|
|
|
12
12
|
@role = role.to_s
|
|
@@ -14,12 +14,13 @@ module Passpartu
|
|
|
14
14
|
@only = Array(only).map(&:to_s) if present?(only)
|
|
15
15
|
@except = Array(exclusion).map(&:to_s) if present?(exclusion) && !@only
|
|
16
16
|
@block = block
|
|
17
|
+
@policy_hash = deep_stringify_keys(policy_hash)
|
|
17
18
|
|
|
18
19
|
raise PolicyYmlNotFoundError if Passpartu.policy.nil?
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def self.call(role, keys, only: nil, except: nil, skip: nil, &block)
|
|
22
|
-
new(role, keys, only, except, skip, block).call
|
|
22
|
+
def self.call(role, keys, only: nil, except: nil, skip: nil, policy_hash: Passpartu.policy, &block)
|
|
23
|
+
new(role, keys, only, except, skip, policy_hash, &block).call
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def call
|
|
@@ -48,9 +49,7 @@ module Passpartu
|
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
def default_check
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@result = Passpartu.policy.dig(role, *keys)
|
|
52
|
+
@result = policy_hash.dig(role, *keys)
|
|
54
53
|
end
|
|
55
54
|
|
|
56
55
|
def check_crud_if
|
|
@@ -79,5 +78,11 @@ module Passpartu
|
|
|
79
78
|
def present?(item)
|
|
80
79
|
!blank?(item)
|
|
81
80
|
end
|
|
81
|
+
|
|
82
|
+
def deep_stringify_keys(hash)
|
|
83
|
+
return hash.deep_stringify_keys if hash.respond_to?(:deep_stringify_keys)
|
|
84
|
+
|
|
85
|
+
JSON.parse(JSON.dump(hash))
|
|
86
|
+
end
|
|
82
87
|
end
|
|
83
88
|
end
|
data/lib/passpartu/version.rb
CHANGED
data/lib/passpartu.rb
CHANGED
|
@@ -6,7 +6,7 @@ require_relative 'passpartu/patcher'
|
|
|
6
6
|
require_relative 'passpartu/verify'
|
|
7
7
|
require_relative 'passpartu/block_verify'
|
|
8
8
|
require_relative 'passpartu/validate_result'
|
|
9
|
-
require_relative 'passpartu/
|
|
9
|
+
require_relative 'passpartu/test_user' # for testing only
|
|
10
10
|
|
|
11
11
|
module Passpartu
|
|
12
12
|
class Error < StandardError; end
|
|
@@ -31,7 +31,7 @@ module Passpartu
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
class Config
|
|
34
|
-
attr_accessor :raise_policy_missed_error
|
|
34
|
+
attr_accessor :raise_policy_missed_error, :role_access_method
|
|
35
35
|
attr_reader :policy_file, :check_waterfall, :policy
|
|
36
36
|
|
|
37
37
|
DEFAULT_POLICY_FILE = './config/passpartu.yml'
|
|
@@ -41,6 +41,7 @@ module Passpartu
|
|
|
41
41
|
self.policy = load_policy_file(policy_file) if File.exist?(policy_file)
|
|
42
42
|
@raise_policy_missed_error = true
|
|
43
43
|
@check_waterfall = false
|
|
44
|
+
@role_access_method = :role
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
def policy_file=(file = nil)
|
data/passpartu.gemspec
CHANGED
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
|
|
|
39
39
|
spec.files = Dir['README.md', 'lib/**/*', 'lib/*', 'passpartu.gemspec']
|
|
40
40
|
|
|
41
41
|
spec.add_development_dependency 'bundler', '~> 2.3'
|
|
42
|
+
spec.add_development_dependency 'byebug'
|
|
42
43
|
spec.add_development_dependency 'rake', '~> 13.0'
|
|
43
44
|
spec.add_development_dependency 'rspec', '~> 3.11'
|
|
44
45
|
spec.add_development_dependency 'codecov', '~> 0.6'
|
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: 1.
|
|
4
|
+
version: 1.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OrestF
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-03-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '2.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: byebug
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: rake
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,7 +121,7 @@ files:
|
|
|
107
121
|
- lib/passpartu.rb
|
|
108
122
|
- lib/passpartu/block_verify.rb
|
|
109
123
|
- lib/passpartu/patcher.rb
|
|
110
|
-
- lib/passpartu/
|
|
124
|
+
- lib/passpartu/test_user.rb
|
|
111
125
|
- lib/passpartu/validate_result.rb
|
|
112
126
|
- lib/passpartu/verify.rb
|
|
113
127
|
- lib/passpartu/version.rb
|
|
@@ -131,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
131
145
|
- !ruby/object:Gem::Version
|
|
132
146
|
version: '0'
|
|
133
147
|
requirements: []
|
|
134
|
-
rubygems_version: 3.
|
|
148
|
+
rubygems_version: 3.4.6
|
|
135
149
|
signing_key:
|
|
136
150
|
specification_version: 4
|
|
137
151
|
summary: Passpartu makes policies great again
|