action_policy 0.6.4 → 0.6.6

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: '095ceaf3dffeb28e23d1b89a20108ad23e6ddfb48e3fc317cf481151cdf82d66'
4
- data.tar.gz: a1cac52b3641e0e3e9709a42a409324f348b13a037342cc004a4b51b99bc15ab
3
+ metadata.gz: af8c6d335ea62aa35058c7dd1bf14273df990b9dca7daa461ca8df28af10047e
4
+ data.tar.gz: 1ba13e5562e5b26042a956a63e5f79f59e7590ee7da787f217a3eff1f946857b
5
5
  SHA512:
6
- metadata.gz: 3a4b4c4b40036ca59122dfa6c3623b542525b7e663ddfaacec4fe93fdadb0a85fc2c12d73f6a58c89cba8d0e647bf5ff8dbf094f6bc181db93a44a004fd07284
7
- data.tar.gz: 28bbda81d9a149ad339558cc7f6b6d175f8385e3be2f0c8118df5491b8152e271382aed6d60235f3de73d73b92406d6442dcf25b24296e73af74d29054890af4
6
+ metadata.gz: e202eb13aaf0fca9d361ab3be099de48a138e7771aa8978e1e35edf87cc1ae77670b80f11f8972c292cbcf6d85c58ebc32ad426fc25357631dc5ee77ecf1efba
7
+ data.tar.gz: eb4eedf9c06006fe60417eb4cf37a657826bc118cd21f97c734d9372287c81254d98369dd120edf9ddeeab3d2f4df95bf9049ae8927107c1a0b7aefcd33eb5c0
data/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.6.6 (2023-09-11)
6
+
7
+ - Fix loading Active Record and Action Controller scope matchers. ([@palkan][])
8
+
9
+ - Add `--parent` option for policy generator ([@matsales28][])
10
+
11
+ Example:
12
+
13
+ `bin/rails g action_policy:policy user --parent=base_policy` generates:
14
+
15
+ ```ruby
16
+ class UserPolicy < BasePolicy
17
+ # ...
18
+ end
19
+ ```
20
+
21
+ ## 0.6.5 (2023-02-16)
22
+
23
+ - Fix generated policies' outdated Ruby API (to work with Ruby 3.2).
24
+
5
25
  ## 0.6.4 (2022-01-17)
6
26
 
7
27
  - Fix loading of Rails scope matchers. ([@palkan][])
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,30 +57,25 @@ 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
64
  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"
65
+ if ::Rails.application.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
74
  ::Rails.application.config.action_policy.namespace_cache_enabled
90
75
 
91
76
  ActiveSupport.on_load(:action_controller) do
77
+ require "action_policy/rails/scope_matchers/action_controller_params"
78
+
92
79
  next unless ::Rails.application.config.action_policy.auto_inject_into_controller
93
80
 
94
81
  ActionController::Base.include ActionPolicy::Controller
@@ -110,6 +97,19 @@ module ActionPolicy # :nodoc:
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.4"
4
+ VERSION = "0.6.6"
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?
@@ -1,4 +1,4 @@
1
- require "<%= File.exists?('spec/rails_helper.rb') ? 'rails_helper' : 'spec_helper' %>"
1
+ require "<%= File.exist?('spec/rails_helper.rb') ? 'rails_helper' : 'spec_helper' %>"
2
2
 
3
3
  RSpec.describe <%= class_name %>Policy, type: :policy do
4
4
  # See https://actionpolicy.evilmartians.io/#/testing?id=rspec-dsl
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.4
4
+ version: 0.6.6
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-01-18 00:00:00.000000000 Z
11
+ date: 2023-09-12 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.3.11
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