action_policy 0.6.5 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
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