zero_authorization 1.0.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c71ff5e0e8ab8e104e78ba8c1c3c86528a552a5c
4
- data.tar.gz: 9d960e3adbe023f1bbcf1321642cbc2a5d1a54aa
3
+ metadata.gz: e1890303102d3d41dea0c99df76d07cc731bfc1c
4
+ data.tar.gz: 337d2c4103dc0a5c099c642394296b9b86ae5c70
5
5
  SHA512:
6
- metadata.gz: 6b88ea53e319c66c3d04c116563df6af81375217d4934f135668fca7839dccba1467fb9450c6177e5e52fd969f752ac8cf6fb0c79a0fc6bba82f7af4643b0aad
7
- data.tar.gz: a8d2a23fab3871be610f7296c2b3fae38a6e027d6c63caf667d4bfbfe957aa73b77371c76e5c7421aab4734f853603fd264c643262196a6b825cbe09d61ae9a3
6
+ metadata.gz: 6adf012cb827cb91b5da8e96d52e375d2c8b14b1ebaf7ec8ba77c39ca1dd66d14c0b6fd45f596b9df0ef4cb61a668b0ace078b22f0e6799e6519c5575f49af86
7
+ data.tar.gz: a1463d0d766c3597b6e7724a37926c048c069eea052bd680a35927582ffc66939f8436c39df2d65fbf30ecd53a0952ef33e1e20d7f592873cfda9dcfa3d605c5
data/README.md CHANGED
@@ -22,40 +22,37 @@ Or install it yourself as:
22
22
 
23
23
  :role_role_name_one:
24
24
  :can_do:
25
- :Account:
26
- - :create
27
- - :save
28
- - :update
25
+ :account:
26
+ - create
27
+ - save
28
+ - update
29
29
  :User:
30
- - :create
31
- - :save
32
- - :update
33
- :ModelCrudHistory: :anything
30
+ - :create
31
+ - :save
32
+ - :update
33
+ :model_crud_history: :nothing
34
34
  :Permission: :anything
35
35
  :cant_do:
36
36
  :Project:
37
37
  - :destroy
38
+ :model_crud_history: :anything
38
39
  :role_role_name_two:
39
40
  :can_do:
40
41
  :Project:
41
- - :create
42
- - :save:
43
- :if:
44
- :authorize?
45
- - :update:
46
- :if:
47
- :authorize?
48
- - :destroy:
49
- :if:
50
- :authorize?
42
+ - create
43
+ - save: is_authorized?
44
+ - :update: is_authorized?
45
+ - :destroy: is_authorized?
46
+ :user:
47
+ create: :create_authorized?
48
+ save: :update_authorized?
49
+ update: :update_authorized?
51
50
  :role_role_name_three:
52
51
  :can_do:
53
- :Plant:
54
- - :create
55
- - :save
56
- - :update
57
- - :destroy
58
- :cant_do: :anything
52
+ - :Project
53
+ - :Organization
54
+ :cant_do:
55
+ - :User
59
56
 
60
57
  2. Restrict models for activity and let rule-set(s) via zero-authorization take control of activity
61
58
 
@@ -75,6 +72,18 @@ Or install it yourself as:
75
72
 
76
73
  4. (Re-)boot application.
77
74
 
75
+ ## Rules for rule-sets execution (Precedence: from top to bottom)
76
+
77
+ 1. Rule 00: If no rule-sets are available for 'can do' and 'cant do' then is authorized true '(with warning message)'.
78
+ 2. Rule 01: If role can't do 'anything' or can do 'nothing' then is authorized false.
79
+ 3. Rule 02: If role can't do 'nothing' or can do 'anything' then is authorized true.
80
+ 4. Rule 03: If role can't do 'specified' method and given 'evaluate' method returns true then is authorized false.
81
+ 5. Rule 04: If role can't do 'specified' method and given 'evaluate' method returns false then is authorized true.
82
+ 6. Rule 05: If role can do 'specified' method and given 'evaluate' method returns true then is authorized true.
83
+ 7. Rule 06: If role can do 'specified' method and given 'evaluate' method returns false then is authorized false.
84
+ 8. Rule 07: If role can't do 'specified' method then is authorized false.
85
+ 9. Rule 08: If role can do 'specified' method then is authorized true.
86
+
78
87
  ## Contributing
79
88
 
80
89
  1. Fork it
@@ -26,13 +26,12 @@ module ZeroAuthorization
26
26
  # Authorization for authorization mode :strict
27
27
  def authorize_strictly(action)
28
28
  role = ZeroAuthorization::Role.role
29
- raise 'ZeroAuthorizationRoleNotAvailable' if role.nil?
29
+ raise ZeroAuthorization::Exceptions::RoleNotAvailable, 'Executing authorize_strictly but role not available' if role.nil?
30
30
 
31
31
  if zero_authorized_core(role, action)
32
32
  return true
33
33
  else
34
- logger.debug 'ZeroAuthorization: Not authorized to perform activity.'
35
- raise 'NotAuthorized'
34
+ raise ZeroAuthorization::Exceptions::NotAuthorized.new(role), "Not authorized to execute #{action} on #{self.class.name}."
36
35
  end
37
36
 
38
37
  false
@@ -41,7 +40,7 @@ module ZeroAuthorization
41
40
  # Authorization for authorization mode :warning
42
41
  def authorize_with_warning(action)
43
42
  role = ZeroAuthorization::Role.role
44
- raise 'ZeroAuthorizationRoleNotAvailable' if role.nil?
43
+ raise ZeroAuthorization::Exceptions::RoleNotAvailable, 'Executing authorize_with_warning but role not available' if role.nil?
45
44
 
46
45
  if zero_authorized_core(role, action)
47
46
  return true
@@ -68,48 +67,41 @@ module ZeroAuthorization
68
67
  elsif self.class.authorization_mode == :superficial
69
68
  return authorize_superficially(action)
70
69
  else
71
- raise 'InvalidAuthorizationMode'
70
+ raise ZeroAuthorization::Exceptions::InvalidAuthorizationMode
72
71
  end
73
72
  end
74
73
 
75
74
  # Core of authorization after reading/parsing rule set for current role
75
+ # Rules for rule-sets execution (Precedence: from top to bottom)
76
+ # Rule 00: If no rule-sets are available for 'can do' and 'cant do' then is authorized true '(with warning message)'.
77
+ # Rule 01: If role can't do 'anything' or can do 'nothing' then is authorized false.
78
+ # Rule 02: If role can't do 'nothing' or can do 'anything' then is authorized true.
79
+ # Rule 03: If role can't do 'specified' method and given 'evaluate' method returns true then is authorized false.
80
+ # Rule 04: If role can't do 'specified' method and given 'evaluate' method returns false then is authorized true.
81
+ # Rule 05: If role can do 'specified' method and given 'evaluate' method returns true then is authorized true.
82
+ # Rule 06: If role can do 'specified' method and given 'evaluate' method returns false then is authorized false.
83
+ # Rule 07: If role can't do 'specified' method then is authorized false.
84
+ # Rule 08: If role can do 'specified' method then is authorized true.
76
85
  def zero_authorized_core(role, action)
77
- _auth_flag = false
78
- unless role.rule_set[:can_do].nil?
79
- if role.rule_set[:can_do] == :anything
80
- _auth_flag = true
81
-
82
- elsif role.rule_set[:can_do].is_a?(Hash)
83
-
84
- if role.rule_set[:can_do][self.class.name.to_sym] == :anything
85
- _auth_flag = true
86
- else
87
- logger.debug "----------- self.class.name.to_sym: #{self.class.name.to_sym}"
88
- symbolized_actions = role.rule_set[:can_do][self.class.name.to_sym].collect { |x| x if x.is_a?(Symbol) }.compact
89
- _auth_flag = if symbolized_actions.include?(action)
90
- true
91
- else
92
- conditional_check =nil
93
- (role.rule_set[:can_do][self.class.name.to_sym]- symbolized_actions).each do |action_rule_hash|
94
- conditional_check = action_rule_hash[action] if action_rule_hash.keys.include? action
95
- end
96
- conditional_check ||= {}
97
- conditional_check= conditional_check[:if]
98
- return self.send(conditional_check) unless conditional_check.nil?
99
- false
100
- end
101
- #_auth_flag = true if (role.rule_set[:can_do][self.class.name.to_sym] || []).include?(action)
102
- end
103
- end
104
- end
105
- unless role.rule_set[:cant_do].nil?
106
- if role.rule_set[:cant_do] == :anything
107
- _auth_flag = false
108
- elsif role.rule_set[:cant_do].is_a?(Hash)
109
- _auth_flag = false if (role.rule_set[:cant_do][self.class.name.to_sym] || []).include?(action)
110
- end
86
+ can_rights = role.can_do_rights(self.class.name)
87
+ can_rights_names = can_rights.keys
88
+ cant_rights = role.cant_do_rights(self.class.name)
89
+ cant_rights_names = cant_rights.keys
90
+
91
+ if can_rights.empty? and cant_rights.empty? #Rule 00
92
+ _temp_i = "#{self.class.name} is exempted from ZeroAuthorization. To enable back, try adding rule-set(s) in role_n_privileges.yml"
93
+ puts _temp_i
94
+ Rails.logger.info _temp_i
95
+ return true
111
96
  end
112
- _auth_flag
97
+ return false if cant_rights_names.include?(:anything) or can_rights_names.include?(:nothing) #Rule 01
98
+ return true if cant_rights_names.include?(:nothing) or can_rights_names.include?(:anything) #Rule 02
99
+ return (self.send(cant_rights[action.to_sym]) ? false : true) unless cant_rights[action.to_sym].nil? # Rule 03 and Rule 04
100
+ return (self.send(can_rights[action.to_sym]) ? true : false) unless can_rights[action.to_sym].nil? # Rule 05 and Rule 06
101
+ return false if cant_rights_names.include?(action.to_sym) # Rule 07
102
+ return true if can_rights_names.include?(action.to_sym) # Rule 08
103
+
104
+ raise ZeroAuthorization::Exceptions::ExecutingUnreachableCode
113
105
  end
114
106
 
115
107
  def is_zero_authorized_4_save
@@ -132,25 +124,12 @@ module ZeroAuthorization
132
124
  module ClassMethods
133
125
  attr_accessor :authorization_mode
134
126
 
127
+ def declared_methods_to_restrict
128
+ Role.methods_marked_for(self.name).keys
129
+ end
130
+
135
131
  def list_of_methods_to_guard
136
- _model_methods_set = {}
137
- Role.roles_n_privileges_hash.each do |role_key, permission_value|
138
- unless permission_value[:can_do].nil?
139
- _model_methods_set = _model_methods_set.merge(permission_value[:can_do]) { |key, oval, nval| ([oval] << [nval]).flatten.compact.uniq } if permission_value[:can_do].is_a?(Hash)
140
- end
141
- unless permission_value[:cant_do].nil?
142
- _model_methods_set = _model_methods_set.merge(permission_value[:cant_do]) { |key, oval, nval| ([oval] << [nval]).flatten.compact.uniq } if permission_value[:cant_do].is_a?(Hash)
143
- end
144
- end
145
- if _model_methods_set[self.name.to_sym] == :anything
146
- _model_methods_set.delete(self.name.to_sym)
147
- end
148
- (_model_methods_set[self.name.to_sym] || []).clone.delete_if do |x|
149
- if x.is_a? Hash
150
- x= x.keys.first
151
- end
152
- [:create, :save, :update, :destroy, :anything].include?(x)
153
- end
132
+ declared_methods_to_restrict - [:create, :save, :update, :destroy, :anything, :nothing]
154
133
  end
155
134
 
156
135
  private
@@ -161,13 +140,18 @@ module ZeroAuthorization
161
140
  # applying restriction on methods
162
141
  def initialize_methods_restriction
163
142
  list_of_methods_to_guard.each do |method_name|
164
- if method_name.is_a? Hash
165
- method_name = method_name.keys.first
166
- end
167
- send(:alias_method, "za_#{method_name}", method_name)
168
- define_method "#{method_name}" do |*args|
169
- puts 'Restricted method call..'
170
- send("za_#{method_name}", *args) if zero_authorized_checker(method_name)
143
+ if self.instance_methods.include?(method_name)
144
+ send(:alias_method, "za_#{method_name}", method_name)
145
+ define_method "#{method_name}" do |*args|
146
+ _temp_i = "Restricted method call to #{self.class.name}#{method_name}.."
147
+ puts _temp_i
148
+ Rails.logger.debug(_temp_i)
149
+ send("za_#{method_name}", *args) if zero_authorized_checker(method_name)
150
+ end
151
+ else
152
+ _temp_i = "[WARNING] ZeroAuthorization: Method '#{method_name}' unavailable in #{self.name} for restriction application."
153
+ puts _temp_i
154
+ Rails.logger.debug(_temp_i)
171
155
  end
172
156
  end
173
157
  end
@@ -1,6 +1,35 @@
1
- module Exceptions
1
+ module ZeroAuthorization
2
+ module Exceptions
3
+ class ExecutingUnreachableCode < StandardError
4
+ def initialize(msg = 'It may be a bug. Please report to ZeroAuthorization\'s authors!')
5
+ super(msg)
6
+ end
7
+ end
2
8
 
3
- #class ActivatedAlreadyError < StandardError;
4
- #end
9
+ class RoleNotAvailable < StandardError
10
+ end
5
11
 
12
+ class NotAuthorized < StandardError
13
+ attr_reader :role
14
+
15
+ def initialize(role)
16
+ @role = role
17
+ end
18
+ end
19
+
20
+ class InvalidAuthorizationMode < StandardError
21
+ def initialize(msg = 'Invalid authorization mode in use it should be from :strict, :warning or :superficial')
22
+ super(msg)
23
+ end
24
+ end
25
+
26
+ class InvalidRolesNPrivilegesHash < StandardError
27
+ attr_reader :hash_in_use
28
+
29
+ def initialize(hash_in_use)
30
+ @hash_in_use = hash_in_use
31
+ end
32
+ end
33
+
34
+ end
6
35
  end
@@ -22,15 +22,114 @@ module ZeroAuthorization
22
22
  roles_n_privileges_hash.keys.collect { |key| key.to_s.gsub(/^role_/, '') }.include?(@@role) ? new(@@role) : nil
23
23
  end
24
24
 
25
+ def can_do_rights(for_classname)
26
+ self.class.methods_marked_for(for_classname, :can_do, rule_set)
27
+ end
28
+
29
+ def cant_do_rights(for_classname)
30
+ self.class.methods_marked_for(for_classname, :cant_do, rule_set)
31
+ end
32
+
33
+ def self.methods_marked_for(for_classname, specific_can_or_cant = nil, source_class_rule_sets = nil)
34
+ method_collection = {}
35
+ if source_class_rule_sets.nil?
36
+ validate_roles_n_privileges_hash.each do |role, class_rule_sets|
37
+ method_collection.merge!(extract_rule_hash(class_rule_sets, for_classname, specific_can_or_cant))
38
+ end
39
+ else
40
+ method_collection.merge!(extract_rule_hash(source_class_rule_sets, for_classname, specific_can_or_cant))
41
+ end
42
+ method_collection
43
+ end
44
+
45
+ def self.extract_rule_hash(class_rule_sets, for_classname, specific_can_or_cant)
46
+ method_collection = {}
47
+ basic_rule = class_rule_sets[for_classname.to_sym]
48
+ basic_rule.each do |can_or_cant, rule_hash|
49
+ (method_collection.merge!(rule_hash)) if (specific_can_or_cant.nil? ? true : (can_or_cant == specific_can_or_cant)) and rule_hash.is_a?(Hash)
50
+ end if basic_rule.is_a?(Hash)
51
+ method_collection
52
+ end
53
+
25
54
  # Cache read of config/roles_n_privileges.yml for role_privileges_hash
26
55
  def self.roles_n_privileges_hash
27
- @roles_n_privileges_hash ||= YAML::load_file(File.join(Rails.root, 'config', 'roles_n_privileges.yml'))
56
+ @roles_n_privileges_hash ||= validate_roles_n_privileges_hash
28
57
  @roles_n_privileges_hash
29
58
  end
30
59
 
31
60
  # Hard read of config/roles_n_privileges.yml for role_privileges_hash
32
61
  def self.roles_n_privileges_hash_reload
33
- @roles_n_privileges_hash = YAML::load_file(File.join(Rails.root, 'config', 'roles_n_privileges.yml'))
62
+ @roles_n_privileges_hash = validate_roles_n_privileges_hash
63
+ end
64
+
65
+ def self.validate_roles_n_privileges_hash
66
+ _result_hash = {}
67
+ YAML::load_file(File.join(Rails.root, 'config', 'roles_n_privileges.yml')).each do |role_name, role_permissions|
68
+ _result_hash[role_name.to_sym] ||= {}
69
+ _rh_with_role = _result_hash[role_name.to_sym]
70
+
71
+ role_permissions.symbolize_keys!
72
+ [:can_do, :cant_do].each do |_can|
73
+
74
+ if role_permissions[_can].is_a?(Array)
75
+
76
+ role_permissions[_can].each do |class_name|
77
+ if [Symbol, String].include?(class_name.class)
78
+ _class_name = class_name.to_s.classify.to_sym
79
+ ((_rh_with_role[_class_name] ||= {})[_can] ||={}).merge!({:anything => nil})
80
+ else
81
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new(class_name), 'It should only be a Symbol or String'
82
+ end
83
+ end
84
+
85
+ elsif role_permissions[_can].is_a?(Hash)
86
+
87
+ role_permissions[_can].each do |class_name, permission_set|
88
+ _class_name = class_name.to_s.classify.to_sym
89
+
90
+ if [Symbol, String].include?(class_name.class)
91
+ if [Symbol, String].include?(permission_set.class)
92
+ if [:anything, :nothing].include?(permission_set.to_sym)
93
+ ((_rh_with_role[_class_name] ||= {})[_can] ||={}).merge!({permission_set.to_sym => nil})
94
+ else
95
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new(permission_set.to_sym), 'It should only have :anything or :nothing'
96
+ end
97
+ elsif permission_set.is_a?(Array)
98
+ permission_set.each do |i_permission_set|
99
+ if [Symbol, String].include?(i_permission_set.class)
100
+ ((_rh_with_role[_class_name] ||= {})[_can] ||={}).merge!({i_permission_set.to_sym => nil})
101
+ elsif i_permission_set.is_a?(Hash)
102
+ i_permission_set.each do |_key, _value|
103
+ if [Symbol, String].include?(_key.class) and [Symbol, String].include?(_value.class)
104
+ ((_rh_with_role[_class_name] ||= {})[_can] ||={}).merge!({_key.to_sym => _value.to_sym})
105
+ else
106
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new({_key => _value}), 'Hash should only have key and value of type Symbol or String'
107
+ end
108
+ end
109
+ else
110
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new(i_permission_set), 'It should only be a Symbol, String or Hash'
111
+ end
112
+ end
113
+ elsif permission_set.is_a?(Hash)
114
+ permission_set.each do |i_permission_key, i_permission_value|
115
+ if [Symbol, String].include?(i_permission_key.class) and [Symbol, String].include?(i_permission_value.class)
116
+ ((_rh_with_role[_class_name] ||= {})[_can] ||={}).merge!({i_permission_key.to_sym => i_permission_value.to_sym})
117
+ else
118
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new({i_permission_key => i_permission_value}), 'Hash should only have key and value of type Symbol or String'
119
+ end
120
+ end
121
+ else
122
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new(permission_set), 'It should only be a Symbol, String, Hash or Array'
123
+ end
124
+ else
125
+ raise ZeroAuthorization::Exceptions::InvalidRolesNPrivilegesHash.new(class_name), 'It should only be a Symbol or String'
126
+ end
127
+ end
128
+
129
+ end
130
+ end
131
+ end
132
+ _result_hash
34
133
  end
35
134
 
36
135
  # Do any activity with any specific temporary role and then revert back to normal situation.
@@ -1,3 +1,3 @@
1
1
  module ZeroAuthorization
2
- VERSION = "1.0.0"
2
+ VERSION = "1.4.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zero_authorization
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rajeev Kannav Sharma
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-04 00:00:00.000000000 Z
12
+ date: 2014-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -95,9 +95,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  version: '0'
96
96
  requirements: []
97
97
  rubyforge_project:
98
- rubygems_version: 2.1.11
98
+ rubygems_version: 2.4.5
99
99
  signing_key:
100
100
  specification_version: 4
101
101
  summary: 'How to setup: Specify what any specific role of current root entity(logged_user)
102
102
  can do/can''t do in roles_n_privileges.yml and (re-)boot application.'
103
103
  test_files: []
104
+ has_rdoc: