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 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,5 @@
1
+ module Isomorfeus
2
+ module Policy
3
+ VERSION = '1.0.0.delta12'
4
+ end
5
+ 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,11 @@
1
+ module LucidPolicy
2
+ class Base
3
+ include LucidPolicy::Mixin
4
+
5
+ if RUBY_ENGINE != 'opal'
6
+ def self.inherited(base)
7
+ Isomorfeus.add_valid_policy_class(base)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module LucidPolicy
2
+ class Exception < Exception
3
+ end
4
+ 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: []