ae_declarative_authorization 2.2.0 → 2.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a7b71e8b588137b1b2b96bc7e214cb6ab58ca778b9bdbafd34d6887897d7537
4
- data.tar.gz: 98662f0d7b0d3ef4fcbec3bae6b71bb3ab8f97051e7fe3c9042c55f1f9c5391b
3
+ metadata.gz: d48feceb3557edc83090bde5cc134402ccd1aa879482e126cc38c0bc32618773
4
+ data.tar.gz: db4fea2e76369d625965842d4b47c5f4a192023de3530e3abe5880e573e20c37
5
5
  SHA512:
6
- metadata.gz: f7c3fe0957edf2aebac772624e17ba87157a0c99181ec7e64794cec22865acd1d74ab2f051b5429fe2a25abbee2665a4cef7b63235b6e26999df5c998bf51ad5
7
- data.tar.gz: cc90c97438fc87fef2a014296abed704e56f37a810d8e858327caaec39cf71d3a46201a82cd4640106d7b70ffe3708163f8db0b9a72ed9612580f9c4d2d23944
6
+ metadata.gz: f58364fc40bd34c86a41dd42179520e4be8fdd275915e20f1d96b7a101424048c348a2b6f86d6b2fe7cfb52d267a0504b06b6afcdd3980d98784d8d31f916858
7
+ data.tar.gz: 5856fbb3162520b104e21e4aaa0c582f9a86b3f6f5299b0c1831c3038b5c27231eb6dc7db25a541c3e5f6883b5cbc5386e7109dbf4e7afd124e189fecf79ca0a
@@ -27,8 +27,13 @@ module Authorization
27
27
  # - event details (hash)
28
28
  attr_accessor :authorization_denied_callback
29
29
 
30
+ # Optional callback to wrap authorization check execution.
31
+ # Must return the result of executing the authorization check block.
32
+ attr_accessor :trace_authorization
33
+
30
34
  def initialize
31
35
  @authorization_denied_callback = nil
36
+ @trace_authorization = nil
32
37
  end
33
38
  end
34
39
 
@@ -1,6 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../authorization.rb'
2
2
  require File.dirname(__FILE__) + '/dsl.rb'
3
3
  require File.dirname(__FILE__) + '/runtime.rb'
4
+ require File.dirname(__FILE__) + '/observability.rb'
4
5
 
5
6
  #
6
7
  # This mixin can be used to add declarative authorization support to APIs built using Grape
@@ -31,6 +32,7 @@ module Authorization
31
32
 
32
33
  base.helpers do
33
34
  include ::Authorization::Controller::Runtime
35
+ include ::Authorization::Controller::Observability
34
36
 
35
37
  def authorization_engine
36
38
  ::Authorization::Engine.instance
@@ -43,7 +45,14 @@ module Authorization
43
45
  # Acceessing route raises an exception when the response is a 405 MethodNotAllowed
44
46
  return
45
47
  end
46
- unless allowed?("#{request.request_method} #{route.origin}")
48
+
49
+ action = "#{request.request_method} #{route.origin}"
50
+
51
+ allowed = trace_authorization(api: api_class&.name, action: action) do
52
+ allowed?(action)
53
+ end
54
+
55
+ unless allowed
47
56
  if respond_to?(:permission_denied, true)
48
57
  # permission_denied needs to render or redirect
49
58
  send(:permission_denied)
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Observability support for declarative authorization
5
+ #
6
+ module Authorization
7
+ module Controller
8
+ module Observability
9
+ def trace_authorization(*args, &block)
10
+ if ::Authorization.config.trace_authorization
11
+ ::Authorization.config.trace_authorization.call(*args, &block)
12
+ else
13
+ yield
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../authorization.rb'
2
2
  require File.dirname(__FILE__) + '/dsl.rb'
3
3
  require File.dirname(__FILE__) + '/runtime.rb'
4
+ require File.dirname(__FILE__) + '/observability.rb'
4
5
 
5
6
  #
6
7
  # Mixin to be added to rails controllers
@@ -18,6 +19,7 @@ module Authorization
18
19
  end
19
20
 
20
21
  base.include Runtime
22
+ base.include Observability
21
23
  end
22
24
 
23
25
  module ClassMethods
@@ -280,7 +282,11 @@ module Authorization
280
282
  protected
281
283
 
282
284
  def filter_access_filter # :nodoc:
283
- unless allowed?(action_name)
285
+ allowed = trace_authorization(controller: self.class.name, action: action_name) do
286
+ allowed?(action_name)
287
+ end
288
+
289
+ unless allowed
284
290
  if respond_to?(:permission_denied, true)
285
291
  # permission_denied needs to render or redirect
286
292
  send(:permission_denied)
@@ -14,6 +14,7 @@ module Authorization
14
14
  def self.failed_auto_loading_is_not_found?
15
15
  @@failed_auto_loading_is_not_found
16
16
  end
17
+
17
18
  def self.failed_auto_loading_is_not_found=(new_value)
18
19
  @@failed_auto_loading_is_not_found = new_value
19
20
  end
@@ -28,11 +29,27 @@ module Authorization
28
29
  # in the authorization rules are only evaluated if an object is given
29
30
  # for context.
30
31
  #
31
- # See examples for Authorization::AuthorizationHelper #permitted_to?
32
- #
33
32
  # If no object or context is specified, the controller_name is used as
34
33
  # context.
35
34
  #
35
+ # Examples:
36
+ # <% permitted_to? :create, :users do %>
37
+ # <%= link_to 'New', new_user_path %>
38
+ # <% end %>
39
+ # ...
40
+ # <% if permitted_to? :create, :users %>
41
+ # <%= link_to 'New', new_user_path %>
42
+ # <% else %>
43
+ # You are not allowed to create new users!
44
+ # <% end %>
45
+ # ...
46
+ # <% for user in @users %>
47
+ # <%= link_to 'Edit', edit_user_path(user) if permitted_to? :update, user %>
48
+ # <% end %>
49
+ #
50
+ # To pass in an object and override the context, you can use the optional
51
+ # options:
52
+ # permitted_to? :update, user, :context => :account
36
53
  def permitted_to?(privilege, object_or_sym = nil, options = {})
37
54
  if authorization_engine.permit!(privilege, options_for_permit(object_or_sym, options, false))
38
55
  yield if block_given?
@@ -48,16 +65,27 @@ module Authorization
48
65
  authorization_engine.permit!(privilege, options_for_permit(object_or_sym, options, true))
49
66
  end
50
67
 
51
- # While permitted_to? is used for authorization, in some cases
68
+ # While permitted_to? is used for authorization in views, in some cases
52
69
  # content should only be shown to some users without being concerned
53
70
  # with authorization. E.g. to only show the most relevant menu options
54
71
  # to a certain group of users. That is what has_role? should be used for.
72
+ #
73
+ # Examples:
74
+ # <% has_role?(:sales) do %>
75
+ # <%= link_to 'All contacts', contacts_path %>
76
+ # <% end %>
77
+ # ...
78
+ # <% if has_role?(:sales) %>
79
+ # <%= link_to 'Customer contacts', contacts_path %>
80
+ # <% else %>
81
+ # ...
82
+ # <% end %>
55
83
  def has_role?(*roles)
56
84
  user_roles = authorization_engine.roles_for(current_user)
57
85
  result = roles.all? do |role|
58
86
  user_roles.include?(role)
59
87
  end
60
- yield if result and block_given?
88
+ yield if result && block_given?
61
89
  result
62
90
  end
63
91
 
@@ -68,7 +96,7 @@ module Authorization
68
96
  result = roles.any? do |role|
69
97
  user_roles.include?(role)
70
98
  end
71
- yield if result and block_given?
99
+ yield if result && block_given?
72
100
  result
73
101
  end
74
102
 
@@ -78,7 +106,7 @@ module Authorization
78
106
  result = roles.all? do |role|
79
107
  user_roles.include?(role)
80
108
  end
81
- yield if result and block_given?
109
+ yield if result && block_given?
82
110
  result
83
111
  end
84
112
 
@@ -88,7 +116,7 @@ module Authorization
88
116
  result = roles.any? do |role|
89
117
  user_roles.include?(role)
90
118
  end
91
- yield if result and block_given?
119
+ yield if result && block_given?
92
120
  result
93
121
  end
94
122
 
@@ -96,16 +124,18 @@ module Authorization
96
124
  context = object = nil
97
125
  if object_or_sym.nil?
98
126
  context = decl_auth_context
99
- elsif !Authorization.is_a_association_proxy?(object_or_sym) and object_or_sym.is_a?(Symbol)
127
+ elsif !Authorization.is_a_association_proxy?(object_or_sym) && object_or_sym.is_a?(Symbol)
100
128
  context = object_or_sym
101
129
  else
102
130
  object = object_or_sym
103
131
  end
104
132
 
105
- result = {:object => object,
106
- :context => context,
107
- :skip_attribute_test => object.nil?,
108
- :bang => bang}.merge(options)
133
+ result = {
134
+ object: object,
135
+ context: context,
136
+ skip_attribute_test: object.nil?,
137
+ bang: bang
138
+ }.merge(options)
109
139
  result[:user] = current_user unless result.key?(:user)
110
140
  result
111
141
  end
@@ -120,12 +150,12 @@ module Authorization
120
150
 
121
151
  begin
122
152
  allowed = if matching_permissions.any?
123
- matching_permissions.all? { |p| p.permit!(self, action_name) }
124
- elsif all_permissions.any?
125
- all_permissions.all? { |p| p.permit!(self, action_name) }
126
- else
127
- !DEFAULT_DENY
128
- end
153
+ matching_permissions.all? { |p| p.permit!(self, action_name) }
154
+ elsif all_permissions.any?
155
+ all_permissions.all? { |p| p.permit!(self, action_name) }
156
+ else
157
+ !DEFAULT_DENY
158
+ end
129
159
  rescue ::Authorization::NotAuthorized => e
130
160
  auth_exception = e
131
161
  end
@@ -1,78 +1,12 @@
1
1
  # Authorization::AuthorizationHelper
2
- require File.dirname(__FILE__) + '/authorization.rb'
2
+ require "#{File.dirname(__FILE__)}/authorization.rb"
3
3
 
4
4
  module Authorization
5
+ # Include this module in your views
5
6
  module AuthorizationHelper
6
-
7
- # If the current user meets the given privilege, permitted_to? returns true
8
- # and yields to the optional block. The attribute checks that are defined
9
- # in the authorization rules are only evaluated if an object is given
10
- # for context.
11
- #
12
- # Examples:
13
- # <% permitted_to? :create, :users do %>
14
- # <%= link_to 'New', new_user_path %>
15
- # <% end %>
16
- # ...
17
- # <% if permitted_to? :create, :users %>
18
- # <%= link_to 'New', new_user_path %>
19
- # <% else %>
20
- # You are not allowed to create new users!
21
- # <% end %>
22
- # ...
23
- # <% for user in @users %>
24
- # <%= link_to 'Edit', edit_user_path(user) if permitted_to? :update, user %>
25
- # <% end %>
26
- #
27
- # To pass in an object and override the context, you can use the optional
28
- # options:
29
- # permitted_to? :update, user, :context => :account
30
- #
31
- def permitted_to?(privilege, object_or_sym = nil, options = {})
32
- controller.permitted_to?(privilege, object_or_sym, options) do
33
- yield if block_given?
34
- end
35
- end
36
-
37
- # While permitted_to? is used for authorization in views, in some cases
38
- # content should only be shown to some users without being concerned
39
- # with authorization. E.g. to only show the most relevant menu options
40
- # to a certain group of users. That is what has_role? should be used for.
41
- #
42
- # Examples:
43
- # <% has_role?(:sales) do %>
44
- # <%= link_to 'All contacts', contacts_path %>
45
- # <% end %>
46
- # ...
47
- # <% if has_role?(:sales) %>
48
- # <%= link_to 'Customer contacts', contacts_path %>
49
- # <% else %>
50
- # ...
51
- # <% end %>
52
- #
53
- def has_role?(*roles)
54
- controller.has_role?(*roles) do
55
- yield if block_given?
56
- end
57
- end
58
-
59
- # As has_role? except checks all roles included in the role hierarchy
60
- def has_role_with_hierarchy?(*roles)
61
- controller.has_role_with_hierarchy?(*roles) do
62
- yield if block_given?
63
- end
64
- end
65
-
66
- def has_any_role?(*roles)
67
- controller.has_any_role?(*roles) do
68
- yield if block_given?
69
- end
70
- end
71
-
72
- def has_any_role_with_hierarchy?(*roles)
73
- controller.has_any_role_with_hierarchy?(*roles) do
74
- yield if block_given?
75
- end
76
- end
7
+ delegate :has_role?, :has_role_with_hierarchy?,
8
+ :has_any_role?, :has_any_role_with_hierarchy?,
9
+ :permitted_to?,
10
+ to: :controller
77
11
  end
78
12
  end
@@ -1,3 +1,3 @@
1
1
  module DeclarativeAuthorization
2
- VERSION = '2.2.0'.freeze
2
+ VERSION = '2.3.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ae_declarative_authorization
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - AppFolio
@@ -63,6 +63,7 @@ files:
63
63
  - lib/declarative_authorization/authorization.rb
64
64
  - lib/declarative_authorization/controller/dsl.rb
65
65
  - lib/declarative_authorization/controller/grape.rb
66
+ - lib/declarative_authorization/controller/observability.rb
66
67
  - lib/declarative_authorization/controller/rails.rb
67
68
  - lib/declarative_authorization/controller/runtime.rb
68
69
  - lib/declarative_authorization/controller_permission.rb