isomorfeus-policy 1.0.0.delta12
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +45 -0
- data/lib/isomorfeus/policy/config.rb +28 -0
- data/lib/isomorfeus/policy/helper.rb +21 -0
- data/lib/isomorfeus/policy/version.rb +5 -0
- data/lib/isomorfeus-policy.rb +24 -0
- data/lib/lucid_policy/base.rb +11 -0
- data/lib/lucid_policy/exception.rb +4 -0
- data/lib/lucid_policy/mixin.rb +156 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2a2fe7052bf8d2dde88e40dbaf7e84b4a346a2d76d50f388dcd921ec6c7e04f2
|
4
|
+
data.tar.gz: 5b548ae9f03dd1fa28cabc0d239e7b9c5aacb9c73282e1928767d28f18dacf13
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 23e95150876608e3da88a67cd2f25292d178f17379e033ba523b0ee3c1e146d86e11398eae9073d97abf09adc81cf07f592de7183be48fbb2efa59ccc7f625eb
|
7
|
+
data.tar.gz: 9b58c54270a731b88549cff14e4217290f64125b5ce2d623578c2a9c3a5358cc910373320830f413c625e708d106d506c5fa4990dc4e0b938bc6601871f2b655
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Jan Biedermann
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# isomorfeus-policy
|
2
|
+
Policy for Isomorfeus
|
3
|
+
|
4
|
+
Policy is enforced on the server, however, the same policy rules are also available on the client to allow for making consistent decisions everywhere.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
Everything that is not explicitly allowed somewhere is denied.
|
8
|
+
|
9
|
+
Place the policy file in your projects `isomorfeus/policies`.
|
10
|
+
|
11
|
+
Example Policy:
|
12
|
+
```ruby
|
13
|
+
class MySimplePolicy < LucidPolicy::Base
|
14
|
+
|
15
|
+
policy_for UserOrRoleClass
|
16
|
+
|
17
|
+
allow BlaBlaGraph, :load
|
18
|
+
|
19
|
+
deny BlaGraph, SuperOperation
|
20
|
+
|
21
|
+
deny others # or: allow others
|
22
|
+
|
23
|
+
with_condition do |user_or_role_instance, target_class, target_method, *props|
|
24
|
+
role.class == AdminRole
|
25
|
+
end
|
26
|
+
|
27
|
+
refine BlaGraph, :load, :count do |user_or_role_instance, target_class, target_method, *props|
|
28
|
+
allow if user_or_role_instance.verified?
|
29
|
+
deny
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
and then any of:
|
34
|
+
```ruby
|
35
|
+
user_or_role_instance.authorized?(target_class)
|
36
|
+
user_or_role_instance.authorized?(target_class, target_method)
|
37
|
+
user_or_role_instance.authorized?(target_class, target_method, *props)
|
38
|
+
```
|
39
|
+
or:
|
40
|
+
```ruby
|
41
|
+
user_or_role_instance.authorized!(target_class)
|
42
|
+
user_or_role_instance.authorized!(target_class, target_method)
|
43
|
+
user_or_role_instance.authorized!(target_class, target_method, *props)
|
44
|
+
```
|
45
|
+
which will raise a LucidPolicy::Exception unless authorized
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
class << self
|
3
|
+
def cached_policy_classes
|
4
|
+
@cached_array_classes ||= {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def cached_policy_class(class_name)
|
8
|
+
return cached_policy_classes[class_name] if cached_policy_classes.key?(class_name)
|
9
|
+
cached_policy_classes[class_name] = "::#{class_name}".constantize
|
10
|
+
end
|
11
|
+
|
12
|
+
if RUBY_ENGINE != 'opal'
|
13
|
+
def valid_policy_class_names
|
14
|
+
@valid_policy_class_names ||= Set.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid_policy_class_name?(class_name)
|
18
|
+
valid_policy_class_names.include?(class_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_valid_policy_class(klass)
|
22
|
+
class_name = klass.name
|
23
|
+
class_name = class_name.split('>::').last if class_name.start_with?('#<')
|
24
|
+
valid_policy_class_names << class_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Isomorfeus
|
2
|
+
module Policy
|
3
|
+
class Helper < BasicObject
|
4
|
+
attr_reader :result
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@result= nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def allow
|
11
|
+
@result = :allow if @result.nil?
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def deny
|
16
|
+
@result = :deny if @result.nil?
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'opal'
|
2
|
+
require 'isomorfeus-redux'
|
3
|
+
require 'isomorfeus-react'
|
4
|
+
require 'isomorfeus/policy/config'
|
5
|
+
require 'lucid_policy/exception'
|
6
|
+
require 'isomorfeus/policy/helper'
|
7
|
+
require 'lucid_policy/mixin'
|
8
|
+
require 'lucid_policy/base'
|
9
|
+
|
10
|
+
if RUBY_ENGINE == 'opal'
|
11
|
+
Opal::Autoloader.add_load_path('policies')
|
12
|
+
else
|
13
|
+
Opal.append_path(__dir__.untaint) unless Opal.paths.include?(__dir__.untaint)
|
14
|
+
|
15
|
+
require 'active_support/dependencies'
|
16
|
+
|
17
|
+
path = File.expand_path(File.join('isomorfeus', 'policies'))
|
18
|
+
|
19
|
+
ActiveSupport::Dependencies.autoload_paths << path
|
20
|
+
# we also need to require them all, so classes are registered accordingly
|
21
|
+
Dir.glob("#{path}/**/*.rb").each do |file|
|
22
|
+
require file
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module LucidPolicy
|
2
|
+
module Mixin
|
3
|
+
def self.included(base)
|
4
|
+
if RUBY_ENGINE != 'opal'
|
5
|
+
Isomorfeus.add_valid_policy_class(base) unless base == LucidPolicy::Base
|
6
|
+
end
|
7
|
+
|
8
|
+
# DSL
|
9
|
+
# class MySimplePolicy < LucidPolicy::Base
|
10
|
+
#
|
11
|
+
# policy_for UserOrRoleClass
|
12
|
+
#
|
13
|
+
# allow BlaBlaGraph, :load
|
14
|
+
#
|
15
|
+
# deny BlaGraph, SuperOperation
|
16
|
+
#
|
17
|
+
# deny others # or: allow others
|
18
|
+
#
|
19
|
+
# with_condition do |user_or_role_instance, target_class, target_method, *props|
|
20
|
+
# role.class == AdminRole
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# refine BlaGraph, :load, :count do |user_or_role_instance, target_class, target_method, *props|
|
24
|
+
# allow if role.verified?
|
25
|
+
# deny
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
base.instance_exec do
|
30
|
+
def policy_for(a_class)
|
31
|
+
raise LucidPolicy::Exception, "policy_for #{a_class} can only be used once within #{self}!" if @the_class
|
32
|
+
@the_class = a_class
|
33
|
+
unless a_class.methods.include?(:authorization_rules)
|
34
|
+
a_class.define_singleton_method(:authorization_rules) do
|
35
|
+
@authorization_rules ||= { classes: {}, conditions: [], others: nil, policy_classes: [] }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
unless a_class.method_defined?(:authorized?)
|
39
|
+
a_class.define_method(:authorized?) do |*class_method_props|
|
40
|
+
target_class = class_method_props[0]
|
41
|
+
raise "At least the class must be given!" unless target_class
|
42
|
+
target_method = class_method_props[1]
|
43
|
+
props = class_method_props[2..-1]
|
44
|
+
|
45
|
+
condition_result = true
|
46
|
+
self.class.authorization_rules[:conditions].each do |condition|
|
47
|
+
condition_result = condition.call(self, target_class, target_method, *props, &condition)
|
48
|
+
break unless condition_result == true
|
49
|
+
end
|
50
|
+
|
51
|
+
if condition_result
|
52
|
+
result = if self.class.authorization_rules[:classes].key?(target_class)
|
53
|
+
if target_method &&
|
54
|
+
self.class.authorization_rules[:classes][target_class].key?(:methods) &&
|
55
|
+
self.class.authorization_rules[:classes][target_class][:methods].key?(target_method)
|
56
|
+
self.class.authorization_rules[:classes][target_class][:methods][target_method]
|
57
|
+
else
|
58
|
+
self.class.authorization_rules[:classes][target_class][:default]
|
59
|
+
end
|
60
|
+
else
|
61
|
+
self.class.authorization_rules[:others]
|
62
|
+
end
|
63
|
+
|
64
|
+
if result.class == Proc
|
65
|
+
policy_helper = Isomorfeus::Policy::Helper.new
|
66
|
+
policy_helper.instance_exec(self, target_class, target_method, *props, &result)
|
67
|
+
result = policy_helper.result
|
68
|
+
end
|
69
|
+
|
70
|
+
result == :allow ? true : false
|
71
|
+
else
|
72
|
+
false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
unless a_class.method_defined?(:authorized!)
|
77
|
+
a_class.define_method(:authorized!) do |*class_method_props|
|
78
|
+
return true if authorized?(*class_method_props)
|
79
|
+
raise LucidPolicy::Exception, "#{self} not authorized to call #{class_method_props}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
@the_class.authorization_rules[:policy_classes] << self
|
83
|
+
end
|
84
|
+
|
85
|
+
def allow(*classes_and_methods)
|
86
|
+
_raise_allow_deny_first if @refine_used
|
87
|
+
_allow_or_deny(:allow, *classes_and_methods)
|
88
|
+
end
|
89
|
+
|
90
|
+
def deny(*classes_and_methods)
|
91
|
+
_raise_allow_deny_first if @refine_used
|
92
|
+
_allow_or_deny(:deny, *classes_and_methods)
|
93
|
+
end
|
94
|
+
|
95
|
+
def others
|
96
|
+
:others
|
97
|
+
end
|
98
|
+
|
99
|
+
def refine(*classes_and_methods, &block)
|
100
|
+
@refine_used = true
|
101
|
+
_allow_or_deny(nil, *classes_and_methods, &block)
|
102
|
+
end
|
103
|
+
|
104
|
+
def with_condition(&block)
|
105
|
+
_raise_policy_first unless @the_class
|
106
|
+
@the_class.authorization_rules[:conditions] << block
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def _raise_policy_first
|
112
|
+
raise LucidPolicy::Exception, "'allow' or 'deny' must appear before 'refine'"
|
113
|
+
end
|
114
|
+
|
115
|
+
def _raise_policy_first
|
116
|
+
raise LucidPolicy::Exception, "policy_for Class must be specified first"
|
117
|
+
end
|
118
|
+
|
119
|
+
def _allow_or_deny(allow_or_deny, *classes_and_methods, &block)
|
120
|
+
_raise_policy_first unless @the_class
|
121
|
+
|
122
|
+
allow_or_deny_or_block = block_given? ? block : allow_or_deny.to_sym
|
123
|
+
|
124
|
+
target_classes = []
|
125
|
+
target_methods = []
|
126
|
+
|
127
|
+
if classes_and_methods.first == :others
|
128
|
+
@the_class.authorization_rules[:others] = allow_or_deny_or_block
|
129
|
+
return
|
130
|
+
end
|
131
|
+
|
132
|
+
classes_and_methods.each do |class_or_method|
|
133
|
+
if (class_or_method.class == String || class_or_method.class == Symbol) && class_or_method.to_s[0].downcase == class_or_method.to_s[0]
|
134
|
+
target_methods << class_or_method.to_sym
|
135
|
+
else
|
136
|
+
target_classes << class_or_method
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
target_classes.each do |target_class|
|
141
|
+
@the_class.authorization_rules[:classes][target_class] = {} unless @the_class.authorization_rules[:classes].key?(target_class)
|
142
|
+
if allow_or_deny && target_methods.empty?
|
143
|
+
@the_class.authorization_rules[:classes][target_class][:default] = allow_or_deny_or_block
|
144
|
+
else
|
145
|
+
@the_class.authorization_rules[:classes][target_class][:default] = :deny unless @the_class.authorization_rules[:classes][target_class].key?(:default)
|
146
|
+
@the_class.authorization_rules[:classes][target_class][:methods] = {} unless @the_class.authorization_rules[:classes][target_class].key?(:methods)
|
147
|
+
target_methods.each do |target_method|
|
148
|
+
@the_class.authorization_rules[:classes][target_class][:methods][target_method] = allow_or_deny_or_block
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: isomorfeus-policy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.delta12
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jan Biedermann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: opal
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.11.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.11.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: opal-autoloader
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: isomorfeus-react
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 16.9.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 16.9.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: isomorfeus-redux
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.0.11
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.0.11
|
69
|
+
description: Policies for Isomorfeus.
|
70
|
+
email: jan@kursator.de
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- LICENSE
|
76
|
+
- README.md
|
77
|
+
- lib/isomorfeus-policy.rb
|
78
|
+
- lib/isomorfeus/policy/config.rb
|
79
|
+
- lib/isomorfeus/policy/helper.rb
|
80
|
+
- lib/isomorfeus/policy/version.rb
|
81
|
+
- lib/lucid_policy/base.rb
|
82
|
+
- lib/lucid_policy/exception.rb
|
83
|
+
- lib/lucid_policy/mixin.rb
|
84
|
+
homepage: http://isomorfeus.com
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.3.1
|
102
|
+
requirements: []
|
103
|
+
rubygems_version: 3.0.3
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Policies for Isomorfeus.
|
107
|
+
test_files: []
|