action_policy 0.6.5 → 0.6.7

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: df1a880286222813e707251f1bc1a71960beba873add57ac2e02ee0bb2ed091b
4
- data.tar.gz: 812e8ac32298907ff10377d6bfa5622283c4ce7061cc41eb7f08049f2b3c7f41
3
+ metadata.gz: df57cf926c648dc59ed1a1afc44b352eb998f5bf03a9405127105611e641ffdb
4
+ data.tar.gz: 51a8e81c6479bf06894da3a2f8fa83c98ed25da678e73bf2462f029a75c55ec4
5
5
  SHA512:
6
- metadata.gz: 85b1471722b869ca0a486efd293d28edc5e5852f4c98c0c9ba1413d83d6c088933032c61d4f15562ed3321593e06a8d7251bc4481cc9476cd11c01ccda8c9c64
7
- data.tar.gz: c8fa5920657c5d7cc1101dd79efd63cc8c80095464de912c768b78b0a2676b247bf715e05f0484d28ac6ee6b8158da1b1cb9423eaca251f2fa17119f79a0088a
6
+ metadata.gz: 6c55e23ffeff3a1d9800512759105e509abb6b51dabee1a984c56f04daa04e661ef37e056e2fee64b86a17bff8fab8167b557d8f5fe6bd9118febf0b116f7b3a
7
+ data.tar.gz: 8c1459872bb8daa8bca216c1ee342b9c8c4b4b6fb5654301765ec4d2c7f8ff6612ab784269a89920c29f575ee9ecd79b2a470a415f92246db70c0b9d7a3631b1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.6.7 (2023-09-13)
6
+
7
+ - Fix loading Rails extensions during eager load. ([@palkan][])
8
+
9
+ ## 0.6.6 (2023-09-11)
10
+
11
+ - Fix loading Active Record and Action Controller scope matchers. ([@palkan][])
12
+
13
+ - Add `--parent` option for policy generator ([@matsales28][])
14
+
15
+ Example:
16
+
17
+ `bin/rails g action_policy:policy user --parent=base_policy` generates:
18
+
19
+ ```ruby
20
+ class UserPolicy < BasePolicy
21
+ # ...
22
+ end
23
+ ```
24
+
5
25
  ## 0.6.5 (2023-02-16)
6
26
 
7
27
  - Fix generated policies' outdated Ruby API (to work with Ruby 3.2).
data/README.md CHANGED
@@ -2,9 +2,13 @@
2
2
  ![Build](https://github.com/palkan/action_policy/workflows/Build/badge.svg)
3
3
  ![JRuby Build](https://github.com/palkan/action_policy/workflows/JRuby%20Build/badge.svg)
4
4
  [![Documentation](https://img.shields.io/badge/docs-link-brightgreen.svg)](https://actionpolicy.evilmartians.io)
5
+ [![Coverage Status](https://coveralls.io/repos/github/palkan/action_policy/badge.svg)](https://coveralls.io/github/palkan/action_policy)
5
6
 
6
7
  # Action Policy
7
8
 
9
+ <img align="right" height="150" width="129"
10
+ title="Action Policy logo" src="./docs/assets/images/logo.svg">
11
+
8
12
  Authorization framework for Ruby and Rails applications.
9
13
 
10
14
  Composable. Extensible. Performant.
@@ -25,6 +29,7 @@ Composable. Extensible. Performant.
25
29
  ## Integrations
26
30
 
27
31
  - GraphQL Ruby ([`action_policy-graphql`](https://github.com/palkan/action_policy-graphql))
32
+ - Graphiti (JSON:API) ([`action_policy-graphiti`](https://github.com/shrimple-tech/action_policy-graphiti))
28
33
 
29
34
  ## Installation
30
35
 
@@ -71,6 +76,8 @@ end
71
76
  ```
72
77
 
73
78
  This may be done with `rails generate action_policy:policy Post` generator.
79
+ You can also use `rails generate action_policy:policy Post --parent=BasePolicy` to make the generated policy inherits
80
+ from `BasePolicy`.
74
81
 
75
82
  Now you can easily add authorization to your Rails\* controller:
76
83
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionPolicy
4
+ module ScopeMatchers
5
+ # Adds `params_filter` method as an alias
6
+ # for `scope_for :action_controller_params`
7
+ module ActionControllerParams
8
+ def params_filter(*__rest__, &__block__)
9
+ scope_for(:action_controller_params, *__rest__, &__block__)
10
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :params_filter)
11
+ end
12
+ end
13
+ end
14
+
15
+ # Register params scope matcher
16
+ ActionPolicy::Base.scope_matcher :action_controller_params, ActionController::Parameters
17
+
18
+ # Add alias to base policy
19
+ ActionPolicy::Base.extend ActionPolicy::ScopeMatchers::ActionControllerParams
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionPolicy
4
+ module ScopeMatchers
5
+ # Adds `relation_scope` method as an alias
6
+ # for `scope_for :active_record_relation`
7
+ module ActiveRecord
8
+ def relation_scope(*__rest__, &__block__)
9
+ scope_for(:active_record_relation, *__rest__, &__block__)
10
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :relation_scope)
11
+ end
12
+ end
13
+ end
14
+
15
+ # Register relation scope matcher
16
+ ActionPolicy::Base.scope_matcher :active_record_relation, ActiveRecord::Relation
17
+
18
+ # Add alias to base policy
19
+ ActionPolicy::Base.extend ActionPolicy::ScopeMatchers::ActiveRecord
20
+
21
+ ActiveRecord::Relation.include(Module.new do
22
+ def policy_name
23
+ if model.respond_to?(:policy_name)
24
+ model.policy_name.to_s
25
+ else
26
+ "#{model}Policy"
27
+ end
28
+ end
29
+ end)
@@ -6,7 +6,7 @@ module ActionPolicy
6
6
  module StringUnderscore
7
7
  refine String do
8
8
  def underscore
9
- word = gsub(/::/, "/")
9
+ word = gsub("::", "/")
10
10
  word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
11
11
  word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
12
12
  word.downcase!
@@ -5,8 +5,8 @@ module ActionPolicy
5
5
  # Adds `params_filter` method as an alias
6
6
  # for `scope_for :action_controller_params`
7
7
  module ActionControllerParams
8
- def params_filter(*args, &block)
9
- scope_for :action_controller_params, *args, &block
8
+ def params_filter(...)
9
+ scope_for(:action_controller_params, ...)
10
10
  end
11
11
  end
12
12
  end
@@ -5,8 +5,8 @@ module ActionPolicy
5
5
  # Adds `relation_scope` method as an alias
6
6
  # for `scope_for :active_record_relation`
7
7
  module ActiveRecord
8
- def relation_scope(*args, &block)
9
- scope_for :active_record_relation, *args, &block
8
+ def relation_scope(...)
9
+ scope_for(:active_record_relation, ...)
10
10
  end
11
11
  end
12
12
  end
@@ -4,14 +4,6 @@ module ActionPolicy # :nodoc:
4
4
  require "action_policy/rails/controller"
5
5
  require "action_policy/rails/channel"
6
6
 
7
- if defined?(::ActionController)
8
- require "action_policy/rails/scope_matchers/action_controller_params"
9
- end
10
-
11
- if defined?(::ActiveRecord)
12
- require "action_policy/rails/scope_matchers/active_record"
13
- end
14
-
15
7
  class Railtie < ::Rails::Railtie # :nodoc:
16
8
  # Provides Rails-specific configuration,
17
9
  # accessible through `Rails.application.config.action_policy`
@@ -65,51 +57,59 @@ module ActionPolicy # :nodoc:
65
57
  config.action_policy = Config
66
58
 
67
59
  initializer "action_policy.clear_per_thread_cache" do |app|
68
- if ::Rails::VERSION::MAJOR >= 5
69
- app.executor.to_run { ActionPolicy::PerThreadCache.clear_all }
70
- app.executor.to_complete { ActionPolicy::PerThreadCache.clear_all }
71
- else
72
- require "action_policy/cache_middleware"
73
- app.middleware.use ActionPolicy::CacheMiddleware
74
- end
60
+ app.executor.to_run { ActionPolicy::PerThreadCache.clear_all }
61
+ app.executor.to_complete { ActionPolicy::PerThreadCache.clear_all }
75
62
  end
76
63
 
77
- config.after_initialize do
78
- next unless ::Rails.application.config.action_policy.instrumentation_enabled
79
-
80
- require "action_policy/rails/policy/instrumentation"
81
- require "action_policy/rails/authorizer"
64
+ initializer "action_policy.extensions" do |app|
65
+ if app.config.action_policy.instrumentation_enabled
66
+ require "action_policy/rails/policy/instrumentation"
67
+ require "action_policy/rails/authorizer"
82
68
 
83
- ActionPolicy::Base.prepend ActionPolicy::Policy::Rails::Instrumentation
84
- ActionPolicy::Authorizer.singleton_class.prepend ActionPolicy::Rails::Authorizer
85
- end
69
+ ActionPolicy::Base.prepend ActionPolicy::Policy::Rails::Instrumentation
70
+ ActionPolicy::Authorizer.singleton_class.prepend ActionPolicy::Rails::Authorizer
71
+ end
86
72
 
87
- config.to_prepare do |_app|
88
73
  ActionPolicy::LookupChain.namespace_cache_enabled =
89
- ::Rails.application.config.action_policy.namespace_cache_enabled
74
+ app.config.action_policy.namespace_cache_enabled
90
75
 
91
76
  ActiveSupport.on_load(:action_controller) do
92
- next unless ::Rails.application.config.action_policy.auto_inject_into_controller
77
+ require "action_policy/rails/scope_matchers/action_controller_params"
78
+
79
+ next unless app.config.action_policy.auto_inject_into_controller
93
80
 
94
81
  ActionController::Base.include ActionPolicy::Controller
95
82
 
96
- next unless ::Rails.application.config.action_policy.controller_authorize_current_user
83
+ next unless app.config.action_policy.controller_authorize_current_user
97
84
 
98
85
  ActionController::Base.authorize :user, through: :current_user
99
86
  end
100
87
 
101
88
  ActiveSupport.on_load(:action_cable) do
102
- next unless ::Rails.application.config.action_policy.auto_inject_into_channel
89
+ next unless app.config.action_policy.auto_inject_into_channel
103
90
 
104
91
  ActionCable::Channel::Base.include ActionPolicy::Channel
105
92
 
106
- next unless ::Rails.application.config.action_policy.channel_authorize_current_user
93
+ next unless app.config.action_policy.channel_authorize_current_user
107
94
 
108
95
  ActionCable::Channel::Base.authorize :user, through: :current_user
109
96
  end
110
97
 
111
98
  ActiveSupport.on_load(:active_record) do
112
99
  require "action_policy/rails/ext/active_record"
100
+ require "action_policy/rails/scope_matchers/active_record"
101
+ end
102
+
103
+ # Trigger load hooks of the components that extend ActionPolicy itself
104
+ # (e.g., scope matchers)
105
+ begin
106
+ ::ActionController::Base
107
+ rescue NameError
108
+ end
109
+
110
+ begin
111
+ ::ActiveRecord::Base
112
+ rescue NameError
113
113
  end
114
114
  end
115
115
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionPolicy
4
- VERSION = "0.6.5"
4
+ VERSION = "0.6.7"
5
5
  end
@@ -2,7 +2,14 @@ Description:
2
2
  Generates a policy for a model with the given name.
3
3
 
4
4
  Example:
5
- rails generate action_policy:policy user
5
+ rails generate action_policy:policy user --parent=base_policy
6
6
 
7
7
  This will create:
8
8
  app/policies/user_policy.rb
9
+
10
+ ```ruby
11
+ class UserPolicy < BasePolicy
12
+ # ...
13
+ end
14
+ ```
15
+
@@ -7,6 +7,8 @@ module ActionPolicy
7
7
  class PolicyGenerator < ::Rails::Generators::NamedBase
8
8
  source_root File.expand_path("templates", __dir__)
9
9
 
10
+ class_option :parent, type: :string, desc: "The parent class for the generated policy"
11
+
10
12
  def run_install_if_needed
11
13
  in_root do
12
14
  return if File.exist?("app/policies/application_policy.rb")
@@ -20,6 +22,16 @@ module ActionPolicy
20
22
  end
21
23
 
22
24
  hook_for :test_framework
25
+
26
+ private
27
+
28
+ def parent_class_name
29
+ parent || "ApplicationPolicy"
30
+ end
31
+
32
+ def parent
33
+ options[:parent]
34
+ end
23
35
  end
24
36
  end
25
37
  end
@@ -1,5 +1,5 @@
1
1
  <% module_namespacing do -%>
2
- class <%= class_name %>Policy < ApplicationPolicy
2
+ class <%= class_name %>Policy < <%= parent_class_name.classify %>
3
3
  # See https://actionpolicy.evilmartians.io/#/writing_policies
4
4
  #
5
5
  # def index?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_policy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-17 00:00:00.000000000 Z
11
+ date: 2023-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-next-core
@@ -138,6 +138,8 @@ files:
138
138
  - lib/.rbnext/2.7/action_policy/i18n.rb
139
139
  - lib/.rbnext/2.7/action_policy/policy/cache.rb
140
140
  - lib/.rbnext/2.7/action_policy/policy/pre_check.rb
141
+ - lib/.rbnext/2.7/action_policy/rails/scope_matchers/action_controller_params.rb
142
+ - lib/.rbnext/2.7/action_policy/rails/scope_matchers/active_record.rb
141
143
  - lib/.rbnext/2.7/action_policy/rspec/be_authorized_to.rb
142
144
  - lib/.rbnext/2.7/action_policy/rspec/have_authorized_scope.rb
143
145
  - lib/.rbnext/2.7/action_policy/utils/pretty_print.rb
@@ -169,7 +171,6 @@ files:
169
171
  - lib/action_policy/behaviours/policy_for.rb
170
172
  - lib/action_policy/behaviours/scoping.rb
171
173
  - lib/action_policy/behaviours/thread_memoized.rb
172
- - lib/action_policy/cache_middleware.rb
173
174
  - lib/action_policy/ext/hash_transform_keys.rb
174
175
  - lib/action_policy/ext/module_namespace.rb
175
176
  - lib/action_policy/ext/policy_cache_key.rb
@@ -241,7 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
242
  - !ruby/object:Gem::Version
242
243
  version: '0'
243
244
  requirements: []
244
- rubygems_version: 3.4.6
245
+ rubygems_version: 3.4.8
245
246
  signing_key:
246
247
  specification_version: 4
247
248
  summary: Authorization framework for Ruby/Rails application
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionPolicy # :nodoc:
4
- class CacheMiddleware # :nodoc:
5
- def initialize(app)
6
- @app = app
7
- end
8
-
9
- def call(env)
10
- ActionPolicy::PerThreadCache.clear_all
11
- result = @app.call(env)
12
- ActionPolicy::PerThreadCache.clear_all
13
-
14
- result
15
- end
16
- end
17
- end