ae_declarative_authorization 1.7.0 → 2.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ef6198e116e9ca661b4799db0fb643b3ac2edfed4afecf87b44fd2f2dade3d8
|
4
|
+
data.tar.gz: 6231b714160be944286cb181b6c4f68dd49b8048688b38943bf078f84d666f02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5e1396443afc071a0818ceb4ee65adbd65e518aa47d451d44d200a8f927cd29a8e47223f22581d6e746bae66f2a092ce6de371ebed7e504b1605bd0407c041f
|
7
|
+
data.tar.gz: ac878748b8c0d6bff2696e8e6a47e59be771da115b378a1a28d2aa0f9056dd41301434ef2325471a9255c2416b2e892ddef7ddbeafce491aad5c0bb77443ffb3
|
@@ -23,6 +23,8 @@ module DeclarativeAuthorization
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def allowed(options)
|
26
|
+
return unless @test_class.run_assertion?(options)
|
27
|
+
|
26
28
|
role, privileges, actions, params_name = extract_options(options)
|
27
29
|
|
28
30
|
actions.each do |action|
|
@@ -38,6 +40,8 @@ module DeclarativeAuthorization
|
|
38
40
|
end
|
39
41
|
|
40
42
|
def denied(options)
|
43
|
+
return unless @test_class.run_assertion?(options)
|
44
|
+
|
41
45
|
role, privileges, actions, params_name = extract_options(options)
|
42
46
|
|
43
47
|
actions.each do |action|
|
@@ -89,6 +93,8 @@ module DeclarativeAuthorization
|
|
89
93
|
end
|
90
94
|
|
91
95
|
def allowed(options)
|
96
|
+
return unless @test_class.run_assertion?(options)
|
97
|
+
|
92
98
|
if options[:when]
|
93
99
|
privilege(options[:when]) { allowed(options) }
|
94
100
|
else
|
@@ -97,6 +103,8 @@ module DeclarativeAuthorization
|
|
97
103
|
end
|
98
104
|
|
99
105
|
def denied(options)
|
106
|
+
return unless @test_class.run_assertion?(options)
|
107
|
+
|
100
108
|
if options[:when]
|
101
109
|
privilege(options[:when]) { denied(options) }
|
102
110
|
else
|
@@ -119,21 +127,54 @@ module DeclarativeAuthorization
|
|
119
127
|
|
120
128
|
def role(role, &block)
|
121
129
|
raise "Role cannot be blank!" if role.blank?
|
122
|
-
|
130
|
+
|
131
|
+
Blockenspiel.invoke(block, RoleTestGenerator.new(@test_class, role)) if @test_class.run_role_test?(role)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
class AccessTestParser
|
136
|
+
include Blockenspiel::DSL
|
137
|
+
|
138
|
+
def initialize(test_class)
|
139
|
+
@test_class = test_class
|
140
|
+
end
|
141
|
+
|
142
|
+
def params(_name, &_block);end
|
143
|
+
|
144
|
+
def role(role, &block)
|
145
|
+
Blockenspiel.invoke(block, self) if @test_class.run_role_test?(role)
|
123
146
|
end
|
124
147
|
|
148
|
+
def privilege(_privilege, &block)
|
149
|
+
Blockenspiel.invoke(block, self)
|
150
|
+
end
|
151
|
+
|
152
|
+
def allowed(options)
|
153
|
+
if options[:only]
|
154
|
+
@test_class.run_all_assertions = false
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def denied(options)
|
159
|
+
if options[:only]
|
160
|
+
@test_class.run_all_assertions = false
|
161
|
+
end
|
162
|
+
end
|
125
163
|
end
|
126
164
|
|
127
165
|
module ClassMethods
|
128
|
-
attr_reader :access_tests_defined
|
166
|
+
attr_reader :access_tests_defined, :only_run_roles
|
167
|
+
attr_accessor :run_all_assertions
|
129
168
|
|
130
169
|
def skip_access_tests_for_actions(*actions)
|
131
170
|
@skipped_access_test_actions ||= []
|
132
171
|
@skipped_access_test_actions += actions.map(&:to_sym)
|
133
172
|
end
|
134
173
|
|
135
|
-
def access_tests(&block)
|
174
|
+
def access_tests(only_run_roles: nil, &block)
|
136
175
|
@access_tests_defined = true
|
176
|
+
@run_all_assertions = true
|
177
|
+
@only_run_roles = only_run_roles
|
137
178
|
file_output ||= [ Dir.tmpdir + '/test/profiles/access_checking', ENV['TEST_ENV_NUMBER'] ].compact.join('.')
|
138
179
|
unless File.exist?(file_output)
|
139
180
|
FileUtils.mkdir_p(File.dirname(file_output))
|
@@ -142,6 +183,7 @@ module DeclarativeAuthorization
|
|
142
183
|
file.puts self.controller_class.name
|
143
184
|
end
|
144
185
|
|
186
|
+
Blockenspiel.invoke(block, AccessTestParser.new(self))
|
145
187
|
Blockenspiel.invoke(block, AccessTestGenerator.new(self))
|
146
188
|
end
|
147
189
|
|
@@ -192,6 +234,14 @@ module DeclarativeAuthorization
|
|
192
234
|
define_method("access_test_params_for_#{name}", &block)
|
193
235
|
end
|
194
236
|
|
237
|
+
def run_role_test?(role)
|
238
|
+
@only_run_roles.nil? || @only_run_roles.include?(role)
|
239
|
+
end
|
240
|
+
|
241
|
+
def run_assertion?(assertion_options)
|
242
|
+
@run_all_assertions || assertion_options[:only]
|
243
|
+
end
|
244
|
+
|
195
245
|
end
|
196
246
|
|
197
247
|
protected
|
@@ -248,15 +298,27 @@ module DeclarativeAuthorization
|
|
248
298
|
errors_to_reraise << Mocha::ExpectationError if defined?(Mocha::ExpectationError)
|
249
299
|
|
250
300
|
begin
|
301
|
+
if options[:debug]
|
302
|
+
puts "Debug: Sending request - role: #{role}, action: #{action}, privilege: #{privilege}, params: #{params.inspect}, http_method: #{http_method}, xhr: #{xhr}"
|
303
|
+
end
|
251
304
|
send *send_args, **send_kwargs
|
305
|
+
if options[:debug]
|
306
|
+
puts "Debug: Response status: #{response.status}" if response.status
|
307
|
+
puts "Debug: flash[:error]: #{flash[:error]}" if flash[:error]
|
308
|
+
puts "Debug: flash[:alert]: #{flash[:alert]}" if flash[:alert]
|
309
|
+
end
|
252
310
|
return response_forbidden?
|
253
311
|
rescue *errors_to_reraise => e
|
254
312
|
raise e
|
255
313
|
rescue => e
|
256
|
-
|
257
|
-
|
258
|
-
puts
|
259
|
-
puts
|
314
|
+
# Exceptions are expected from controllers as complete requests are not always made in access tests
|
315
|
+
if options[:debug]
|
316
|
+
puts "Debug: Exception raised from controller, not considered as an error for access tests as response is not coming from the declarative authorization framework."
|
317
|
+
puts "Debug: Response status: #{response.status}" if response.status
|
318
|
+
puts "Debug: flash[:error]: #{flash[:error]}" if flash[:error]
|
319
|
+
puts "Debug: flash[:alert]: #{flash[:alert]}" if flash[:alert]
|
320
|
+
puts "Debug: Exception: #{e.class} - #{e.message}"
|
321
|
+
puts e.backtrace.join("\n") if e.backtrace
|
260
322
|
end
|
261
323
|
return false
|
262
324
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ae_declarative_authorization
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AppFolio
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-08-18 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: blockenspiel
|
@@ -77,7 +77,6 @@ files:
|
|
77
77
|
- lib/generators/authorization/install/install_generator.rb
|
78
78
|
- lib/generators/authorization/rules/rules_generator.rb
|
79
79
|
- lib/generators/authorization/rules/templates/authorization_rules.rb
|
80
|
-
- lib/rubocop/cop/decl_auth/before_actions_precede_access_filter.rb
|
81
80
|
- lib/tasks/authorization_tasks.rake
|
82
81
|
- rubocop-decl-auth.yml
|
83
82
|
homepage: https://github.com/appfolio/ae_declarative_authorization
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module DeclAuth
|
6
|
-
# Enforces placing all `before_action` statements prior to the first `filter_access_to` statement.
|
7
|
-
# This ensures that any data required by the access filters is available before the filter is applied.
|
8
|
-
# See the documentation above the `filter_access_to` method in Authorization::Controller::DSL for more information
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# before_action: :do_something
|
13
|
-
# filter_access_to :all
|
14
|
-
# before_action :find_object
|
15
|
-
#
|
16
|
-
# # good
|
17
|
-
# before_action: :do_something
|
18
|
-
# before_action :find_object
|
19
|
-
#
|
20
|
-
# filter_access_to :all
|
21
|
-
#
|
22
|
-
class BeforeActionsPrecedeAccessFilter < RuboCop::Cop::Base
|
23
|
-
def_node_search :before_actions, '(send nil? :before_action ...)'
|
24
|
-
def_node_search :access_filters, '(send nil? :filter_access_to ...)'
|
25
|
-
|
26
|
-
MSG = '`:filter_access_to` statements should be placed after all other `:before_action` statements.'
|
27
|
-
|
28
|
-
def on_class(node)
|
29
|
-
before_actions = before_actions(node)
|
30
|
-
access_filters = access_filters(node)
|
31
|
-
|
32
|
-
return if before_actions.count.zero? || access_filters.count.zero?
|
33
|
-
|
34
|
-
last_before_action = before_actions.to_a.last
|
35
|
-
first_access_filter = access_filters.to_a.first
|
36
|
-
|
37
|
-
return if last_before_action.sibling_index < first_access_filter.sibling_index
|
38
|
-
|
39
|
-
add_offense(access_filters.first, message: MSG)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|