passpartu 0.6.0 → 1.0.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 +4 -4
- data/README.md +32 -1
- data/lib/passpartu.rb +15 -4
- data/lib/passpartu/block_verify.rb +2 -0
- data/lib/passpartu/check_waterfall.rb +33 -0
- data/lib/passpartu/patcher.rb +4 -0
- data/lib/passpartu/user.rb +2 -0
- data/lib/passpartu/validate_result.rb +2 -0
- data/lib/passpartu/verify.rb +26 -9
- data/lib/passpartu/version.rb +3 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 982e32959b5022a455e42d2c1de190c0851f358cfd34c699ece8394e6af0d951
|
4
|
+
data.tar.gz: 2e81288b0af25837d0d4d97b14562e33f2813ca0b8741adbce66451568a99487
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cebce1276892e0fd925be52bc3ed817b83b6aeb96d9b056b9d999d288b9cbe891189f36a8d6b904b1dac53bbd90eb10b2d6628e42f727d063bc300abbeb697d
|
7
|
+
data.tar.gz: 6caeffe92ffe0f8fe158c0d10c9d4eca18e88ac3acad3c14d7346673ca6740c7335564d53f10a9263f6ae2bcc533077fb18d84cfb25c68cac71717e7b4c01ff7
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Passpartu
|
1
|
+
# Passpartu v1.0.0 - [changelog](https://github.com/coaxsoft/passpartu/blob/master/CHANGELOG.md)
|
2
2
|
|
3
3
|
Passpartu makes policies great again (works awesome with [Pundit](https://rubygems.org/gems/pundit)).
|
4
4
|
|
@@ -132,6 +132,37 @@ Check user roles AND policy rule
|
|
132
132
|
user_agent.agent_can?(:orders, :edit, except: [:admin, :manager]) { user_agent.orders.include?(order) }
|
133
133
|
```
|
134
134
|
|
135
|
+
#### Waterfall check
|
136
|
+
Allow or restrict absolutely everything for particular role or/and particular domain.
|
137
|
+
```ruby
|
138
|
+
# ./config/initializers/passpartu.rb
|
139
|
+
|
140
|
+
Passpartu.configure do |config|
|
141
|
+
config.check_waterfall = true
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
```yml
|
146
|
+
# ./config/passpartu.yml
|
147
|
+
|
148
|
+
super_admin: true
|
149
|
+
super_looser: false
|
150
|
+
medium_looser:
|
151
|
+
orders:
|
152
|
+
create: true
|
153
|
+
delete: false
|
154
|
+
products: true
|
155
|
+
```
|
156
|
+
```ruby
|
157
|
+
user_super_admin.can?(:do, :whatever, :want) # true
|
158
|
+
user_super_loser.can?(:do, :whatever, :want) # false
|
159
|
+
user_medium_loser.can?(:orders, :create) # true
|
160
|
+
user_medium_loser.can?(:orders, :delete) # false
|
161
|
+
user_medium_loser.can?(:products, :create) # true
|
162
|
+
user_medium_loser.can?(:products, :create, :and_delete) # true
|
163
|
+
```
|
164
|
+
|
165
|
+
|
135
166
|
##### Real life example
|
136
167
|
You need to check custom rule for agent
|
137
168
|
```yml
|
data/lib/passpartu.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'passpartu/version'
|
2
4
|
require 'yaml'
|
3
5
|
require_relative 'passpartu/patcher'
|
4
6
|
require_relative 'passpartu/verify'
|
5
7
|
require_relative 'passpartu/block_verify'
|
6
8
|
require_relative 'passpartu/validate_result'
|
9
|
+
require_relative 'passpartu/check_waterfall'
|
7
10
|
require_relative 'passpartu/user' # for testing only
|
8
11
|
|
9
12
|
module Passpartu
|
10
13
|
class Error < StandardError; end
|
14
|
+
class PolicyYmlNotFoundError < StandardError; end
|
15
|
+
class WaterfallError < StandardError; end
|
11
16
|
|
12
17
|
def self.included(policy_class)
|
13
18
|
Passpartu::Patcher.call(policy_class)
|
@@ -27,17 +32,23 @@ module Passpartu
|
|
27
32
|
end
|
28
33
|
|
29
34
|
class Config
|
30
|
-
attr_accessor :policy, :raise_policy_missed_error
|
35
|
+
attr_accessor :policy, :raise_policy_missed_error, :check_waterfall
|
31
36
|
attr_reader :policy_file
|
32
37
|
|
38
|
+
DEFAULT_POLICY_FILE = './config/passpartu.yml'
|
39
|
+
|
33
40
|
def initialize
|
34
|
-
@policy_file =
|
35
|
-
@policy = YAML.load_file(policy_file)
|
41
|
+
@policy_file = DEFAULT_POLICY_FILE
|
42
|
+
@policy = YAML.load_file(policy_file) if File.exist?(policy_file)
|
36
43
|
@raise_policy_missed_error = true
|
44
|
+
@check_waterfall = false
|
37
45
|
end
|
38
46
|
|
39
47
|
def policy_file=(file = nil)
|
40
|
-
@policy_file = file ||
|
48
|
+
@policy_file = file || DEFAULT_POLICY_FILE
|
49
|
+
|
50
|
+
raise PolicyYmlNotFoundError unless File.exist?(policy_file)
|
51
|
+
|
41
52
|
@policy = YAML.load_file(policy_file)
|
42
53
|
end
|
43
54
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Passpartu
|
4
|
+
class CheckWaterfall
|
5
|
+
attr_reader :waterfall, :policy_hash
|
6
|
+
def initialize(role, keys)
|
7
|
+
@waterfall = [role] + keys
|
8
|
+
@policy_hash = Passpartu.policy
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.call(role, keys)
|
12
|
+
new(role, keys).call
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
patch_boolean_classes
|
17
|
+
@result = policy_hash.dig(*waterfall)
|
18
|
+
reset_boolean_classes
|
19
|
+
|
20
|
+
@result
|
21
|
+
end
|
22
|
+
|
23
|
+
def patch_boolean_classes
|
24
|
+
TrueClass.define_method(:dig) { |*_keys| true }
|
25
|
+
FalseClass.define_method(:dig) { |*_keys| false }
|
26
|
+
end
|
27
|
+
|
28
|
+
def reset_boolean_classes
|
29
|
+
TrueClass.undef_method(:dig)
|
30
|
+
FalseClass.undef_method(:dig)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/passpartu/patcher.rb
CHANGED
data/lib/passpartu/user.rb
CHANGED
data/lib/passpartu/verify.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Passpartu
|
2
4
|
class Verify
|
3
|
-
CRUD_KEY = 'crud'
|
5
|
+
CRUD_KEY = 'crud'
|
4
6
|
|
5
7
|
attr_reader :role, :keys, :result, :only, :except, :block
|
6
8
|
|
@@ -12,6 +14,8 @@ module Passpartu
|
|
12
14
|
@only = Array(only).map(&:to_s) if present?(only)
|
13
15
|
@except = Array(exclusion).map(&:to_s) if present?(exclusion) && !@only
|
14
16
|
@block = block
|
17
|
+
|
18
|
+
raise PolicyYmlNotFoundError if Passpartu.policy.nil?
|
15
19
|
end
|
16
20
|
|
17
21
|
def self.call(role, keys, only: nil, except: nil, skip: nil, &block)
|
@@ -21,10 +25,17 @@ module Passpartu
|
|
21
25
|
def call
|
22
26
|
return false if role_ignore?
|
23
27
|
|
24
|
-
|
25
|
-
|
28
|
+
check_waterfall_if
|
29
|
+
default_check
|
30
|
+
check_crud_if
|
26
31
|
|
27
32
|
validate_result
|
33
|
+
rescue StandardError => e
|
34
|
+
if ['TrueClass does not have #dig method', 'FalseClass does not have #dig method'].include?(e.message)
|
35
|
+
raise WaterfallError.new "Looks like you want to use check_waterfall feature, but it's set to 'false'. Otherwise check your #{Passpartu.config.policy_file} for validness"
|
36
|
+
else
|
37
|
+
raise e
|
38
|
+
end
|
28
39
|
end
|
29
40
|
|
30
41
|
private
|
@@ -36,17 +47,17 @@ module Passpartu
|
|
36
47
|
false
|
37
48
|
end
|
38
49
|
|
39
|
-
def
|
50
|
+
def default_check
|
51
|
+
return unless policy_missed?
|
52
|
+
|
40
53
|
@result = Passpartu.policy.dig(role, *keys)
|
41
54
|
end
|
42
55
|
|
43
|
-
def
|
44
|
-
|
45
|
-
check_policy
|
46
|
-
end
|
56
|
+
def check_crud_if
|
57
|
+
return unless policy_missed? && last_key_crud?
|
47
58
|
|
48
|
-
def change_crud_key
|
49
59
|
@keys[-1] = CRUD_KEY
|
60
|
+
default_check
|
50
61
|
end
|
51
62
|
|
52
63
|
def policy_missed?
|
@@ -61,6 +72,12 @@ module Passpartu
|
|
61
72
|
%w[create read update delete].include?(keys[-1])
|
62
73
|
end
|
63
74
|
|
75
|
+
def check_waterfall_if
|
76
|
+
return unless Passpartu.config.check_waterfall && policy_missed?
|
77
|
+
|
78
|
+
@result = Passpartu::CheckWaterfall.call(role, keys)
|
79
|
+
end
|
80
|
+
|
64
81
|
def blank?(item)
|
65
82
|
item.respond_to?(:empty?) ? !!item.empty? : !item
|
66
83
|
end
|
data/lib/passpartu/version.rb
CHANGED
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.
|
4
|
+
version: 1.0.0
|
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: 2020-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- README.md
|
65
65
|
- lib/passpartu.rb
|
66
66
|
- lib/passpartu/block_verify.rb
|
67
|
+
- lib/passpartu/check_waterfall.rb
|
67
68
|
- lib/passpartu/patcher.rb
|
68
69
|
- lib/passpartu/user.rb
|
69
70
|
- lib/passpartu/validate_result.rb
|
@@ -89,7 +90,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
90
|
- !ruby/object:Gem::Version
|
90
91
|
version: '0'
|
91
92
|
requirements: []
|
92
|
-
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.7.7
|
93
95
|
signing_key:
|
94
96
|
specification_version: 4
|
95
97
|
summary: Passpartu makes policies great again
|