pundit 2.3.1 → 2.3.2
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 +4 -4
- data/.github/PULL_REQUEST_TEMPLATE/gem_release_template.md +8 -0
- data/.github/workflows/main.yml +107 -0
- data/.github/workflows/push_gem.yml +33 -0
- data/.rubocop.yml +7 -16
- data/CHANGELOG.md +12 -1
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +3 -2
- data/README.md +9 -11
- data/lib/generators/pundit/install/templates/application_policy.rb +1 -1
- data/lib/generators/pundit/policy/templates/policy.rb +7 -1
- data/lib/pundit/authorization.rb +12 -4
- data/lib/pundit/cache_store/legacy_store.rb +17 -0
- data/lib/pundit/cache_store/null_store.rb +18 -0
- data/lib/pundit/context.rb +127 -0
- data/lib/pundit/policy_finder.rb +1 -1
- data/lib/pundit/version.rb +1 -1
- data/lib/pundit.rb +21 -87
- data/pundit.gemspec +1 -1
- data/spec/authorization_spec.rb +22 -6
- data/spec/generators_spec.rb +1 -1
- data/spec/pundit_spec.rb +10 -2
- data/spec/spec_helper.rb +112 -35
- metadata +17 -12
- data/.travis.yml +0 -27
- /data/.github/{pull_request_template.md → PULL_REQUEST_TEMPLATE/pull_request_template.md} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa554bffd828649aeac4e79a802070d4e68948beacbc9c991fddab7141a965c9
|
4
|
+
data.tar.gz: edf9be8366e5dfcb541eff929e99a04c2bfb23b800214bc39d68c790b32d7365
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 555ccc09f0cc62c3e1da52a7eafb2c3e4805a303c884da39c2ed1c8fc13583727d3e060381ed761f5dd06fdcc71cc3f98c4c991e64db8ac3ff5ff5a460f64aac
|
7
|
+
data.tar.gz: be290f6d6253367e0911525969fc8bb8972db670626bd9803ccd6e7fc1a1504afd1c921a5aac506ee9cfe559a9863bfb469dca3a656909b7ffa1d74aa4c6ea36
|
@@ -0,0 +1,8 @@
|
|
1
|
+
## To do
|
2
|
+
|
3
|
+
- [ ] Commit changes:
|
4
|
+
- [ ] Bump `Pundit::VERSION` in `lib/pundit/version.rb`.
|
5
|
+
- [ ] Update `CHANGELOG.md`.
|
6
|
+
- [ ] Run `rake release`.
|
7
|
+
- [ ] Open pull request 🚀
|
8
|
+
- [ ] Make an announcement in [Pundit discussions](https://github.com/varvet/pundit/discussions/categories/announcements).
|
@@ -0,0 +1,107 @@
|
|
1
|
+
name: Main
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ "main" ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ "main" ]
|
8
|
+
workflow_dispatch:
|
9
|
+
|
10
|
+
permissions:
|
11
|
+
contents: read
|
12
|
+
|
13
|
+
env:
|
14
|
+
CC_TEST_REPORTER_ID: "ac477089fe20ab4fc7e0d304cab75f72d73d58a7596d366935d18fcc7d51f8f9"
|
15
|
+
|
16
|
+
# `github.ref` points to the *merge commit* when running tests on a pull request, which will be a commit
|
17
|
+
# that doesn't exists in our code base. Since this workflow triggers from a PR, we use the HEAD SHA instead.
|
18
|
+
#
|
19
|
+
# NOTE: These are both used by Code Climate (cc-test-reporter).
|
20
|
+
GIT_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
21
|
+
GIT_BRANCH: ${{ github.head_ref }}
|
22
|
+
|
23
|
+
jobs:
|
24
|
+
matrix-test:
|
25
|
+
runs-on: ubuntu-latest
|
26
|
+
continue-on-error: ${{ matrix.allow-failure || false }}
|
27
|
+
strategy:
|
28
|
+
fail-fast: false
|
29
|
+
matrix:
|
30
|
+
ruby-version:
|
31
|
+
- '3.1'
|
32
|
+
- '3.2'
|
33
|
+
- '3.3'
|
34
|
+
- 'jruby-9.3.10' # oldest supported jruby
|
35
|
+
- 'jruby'
|
36
|
+
include: # HEAD-versions
|
37
|
+
- ruby-version: 'head'
|
38
|
+
allow-failure: true
|
39
|
+
- ruby-version: 'jruby-head'
|
40
|
+
allow-failure: true
|
41
|
+
- ruby-version: 'truffleruby-head'
|
42
|
+
allow-failure: true
|
43
|
+
|
44
|
+
steps:
|
45
|
+
- uses: actions/checkout@v3
|
46
|
+
- name: Set up Ruby
|
47
|
+
uses: ruby/setup-ruby@v1
|
48
|
+
with:
|
49
|
+
rubygems: latest
|
50
|
+
ruby-version: ${{ matrix.ruby-version }}
|
51
|
+
bundler-cache: true
|
52
|
+
- name: Run tests
|
53
|
+
run: bundle exec rspec
|
54
|
+
|
55
|
+
test:
|
56
|
+
runs-on: ubuntu-latest
|
57
|
+
steps:
|
58
|
+
- uses: actions/checkout@v3
|
59
|
+
- name: Set up Ruby
|
60
|
+
uses: ruby/setup-ruby@v1
|
61
|
+
with:
|
62
|
+
rubygems: latest
|
63
|
+
ruby-version: 'ruby'
|
64
|
+
bundler-cache: true
|
65
|
+
- name: "Download cc-test-reporter from codeclimate.com"
|
66
|
+
run: |
|
67
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
68
|
+
chmod +x ./cc-test-reporter
|
69
|
+
- name: "Report to Code Climate that we will send a coverage report."
|
70
|
+
run: ./cc-test-reporter before-build
|
71
|
+
- name: Run tests
|
72
|
+
run: bundle exec rspec
|
73
|
+
env:
|
74
|
+
COVERAGE: 1
|
75
|
+
- name: Upload code coverage to Code Climate
|
76
|
+
run: |
|
77
|
+
./cc-test-reporter after-build \
|
78
|
+
--coverage-input-type simplecov \
|
79
|
+
./coverage/.resultset.json
|
80
|
+
|
81
|
+
rubocop:
|
82
|
+
runs-on: ubuntu-latest
|
83
|
+
steps:
|
84
|
+
- uses: actions/checkout@v3
|
85
|
+
- name: Set up Ruby
|
86
|
+
uses: ruby/setup-ruby@v1
|
87
|
+
with:
|
88
|
+
rubygems: default
|
89
|
+
ruby-version: 'ruby'
|
90
|
+
bundler-cache: false
|
91
|
+
- run: bundle install
|
92
|
+
- name: Run RuboCop
|
93
|
+
run: bundle exec rubocop
|
94
|
+
|
95
|
+
required-checks:
|
96
|
+
runs-on: ubuntu-latest
|
97
|
+
if: ${{ always() }}
|
98
|
+
needs:
|
99
|
+
- test
|
100
|
+
- matrix-test
|
101
|
+
- rubocop
|
102
|
+
steps:
|
103
|
+
- name: failure
|
104
|
+
if: ${{ failure() || contains(needs.*.result, 'failure') }}
|
105
|
+
run: exit 1
|
106
|
+
- name: success
|
107
|
+
run: exit 0
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: Push Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
workflow_dispatch:
|
5
|
+
|
6
|
+
permissions:
|
7
|
+
contents: read
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
push:
|
11
|
+
if: github.repository == 'varvet/pundit'
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
permissions:
|
15
|
+
contents: write
|
16
|
+
id-token: write
|
17
|
+
|
18
|
+
steps:
|
19
|
+
# Set up
|
20
|
+
- name: Harden Runner
|
21
|
+
uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
|
22
|
+
with:
|
23
|
+
egress-policy: audit
|
24
|
+
|
25
|
+
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: ruby/setup-ruby@cacc9f1c0b3f4eb8a16a6bb0ed10897b43b9de49 # v1.176.0
|
28
|
+
with:
|
29
|
+
bundler-cache: true
|
30
|
+
ruby-version: ruby
|
31
|
+
|
32
|
+
# Release
|
33
|
+
- uses: rubygems/release-gem@612653d273a73bdae1df8453e090060bb4db5f31 # v1
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion:
|
2
|
+
TargetRubyVersion: 3.1
|
3
3
|
Exclude:
|
4
4
|
- "lib/generators/**/templates/**/*"
|
5
|
+
<% `git status --ignored --porcelain`.lines.grep(/^!! /).each do |path| %>
|
6
|
+
- <%= path.sub(/^!! /, '').sub(/\/$/, '/**/*') %>
|
7
|
+
<% end %>
|
5
8
|
SuggestExtensions: false
|
6
9
|
NewCops: disable
|
7
10
|
|
@@ -20,15 +23,6 @@ Metrics/ModuleLength:
|
|
20
23
|
Layout/LineLength:
|
21
24
|
Max: 120
|
22
25
|
|
23
|
-
Metrics/AbcSize:
|
24
|
-
Enabled: false
|
25
|
-
|
26
|
-
Metrics/CyclomaticComplexity:
|
27
|
-
Enabled: false
|
28
|
-
|
29
|
-
Metrics/PerceivedComplexity:
|
30
|
-
Enabled: false
|
31
|
-
|
32
26
|
Gemspec/RequiredRubyVersion:
|
33
27
|
Enabled: false
|
34
28
|
|
@@ -59,14 +53,11 @@ Style/StringLiteralsInInterpolation:
|
|
59
53
|
Style/StructInheritance:
|
60
54
|
Enabled: false
|
61
55
|
|
62
|
-
Style/AndOr:
|
63
|
-
Enabled: false
|
64
|
-
|
65
|
-
Style/Not:
|
66
|
-
Enabled: false
|
67
|
-
|
68
56
|
Style/DoubleNegation:
|
69
57
|
Enabled: false
|
70
58
|
|
71
59
|
Style/Documentation:
|
72
60
|
Enabled: false # TODO: Enable again once we have more docs
|
61
|
+
|
62
|
+
Style/HashSyntax:
|
63
|
+
EnforcedShorthandSyntax: never
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,18 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
-
|
5
|
+
## 2.3.2 (2024-05-08)
|
6
|
+
|
7
|
+
- Refactor: First pass of Pundit::Context (#797)
|
8
|
+
|
9
|
+
## Changed
|
10
|
+
|
11
|
+
- Update `ApplicationPolicy` generator to qualify the `Scope` class name (#792)
|
12
|
+
- Policy generator uses `NoMethodError` to indicate `#resolve` is not implemented (#776)
|
13
|
+
|
14
|
+
## Deprecated
|
15
|
+
|
16
|
+
- Dropped support for Ruby 3.0 (#796)
|
6
17
|
|
7
18
|
## 2.3.1 (2023-07-17)
|
8
19
|
|
data/CONTRIBUTING.md
CHANGED
@@ -20,7 +20,7 @@ Pundit version, OS version and any stack traces you have are very valuable.
|
|
20
20
|
- **Document any change in behaviour**. Make sure the README and any other
|
21
21
|
relevant documentation are kept up-to-date.
|
22
22
|
|
23
|
-
- **Create topic branches**. Please don't ask us to pull from your
|
23
|
+
- **Create topic branches**. Please don't ask us to pull from your main branch.
|
24
24
|
|
25
25
|
- **One pull request per feature**. If you want to do more than one thing, send
|
26
26
|
multiple pull requests.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
# Pundit
|
2
2
|
|
3
|
-
[](https://github.com/varvet/pundit/actions/workflows/main.yml)
|
4
|
+
[](https://codeclimate.com/github/varvet/pundit/maintainability)
|
5
|
+
[](http://inch-ci.org/github/varvet/pundit)
|
6
6
|
[](http://badge.fury.io/rb/pundit)
|
7
7
|
|
8
8
|
Pundit provides a set of helpers which guide you in leveraging regular Ruby
|
9
9
|
classes and object oriented design patterns to build a straightforward, robust, and
|
10
10
|
scalable authorization system.
|
11
11
|
|
12
|
-
Links:
|
12
|
+
## Links:
|
13
13
|
|
14
14
|
- [API documentation for the most recent version](http://www.rubydoc.info/gems/pundit)
|
15
15
|
- [Source Code](https://github.com/varvet/pundit)
|
16
|
-
- [Contributing](https://github.com/varvet/pundit/blob/
|
17
|
-
- [Code of Conduct](https://github.com/varvet/pundit/blob/
|
16
|
+
- [Contributing](https://github.com/varvet/pundit/blob/main/CONTRIBUTING.md)
|
17
|
+
- [Code of Conduct](https://github.com/varvet/pundit/blob/main/CODE_OF_CONDUCT.md)
|
18
18
|
|
19
|
-
Sponsored by
|
20
|
-
|
21
|
-
[<img src="https://www.varvet.com/images/wordmark-red.svg" alt="Varvet" height="50px"/>](https://www.varvet.com)
|
19
|
+
<strong>Sponsored by:</strong> <a href="https://www.varvet.com">Varvet<br><br><img src="https://github.com/varvet/pundit/assets/99166/aa9efa0a-6903-4037-abee-1824edc57f1a" alt="Varvet logo" height="120"></div>
|
22
20
|
|
23
21
|
## Installation
|
24
22
|
|
@@ -279,7 +277,7 @@ generator, or create your own base class to inherit from:
|
|
279
277
|
|
280
278
|
``` ruby
|
281
279
|
class PostPolicy < ApplicationPolicy
|
282
|
-
class Scope < Scope
|
280
|
+
class Scope < ApplicationPolicy::Scope
|
283
281
|
def resolve
|
284
282
|
if user.admin?
|
285
283
|
scope.all
|
@@ -476,7 +474,7 @@ example, associations which might be `nil`.
|
|
476
474
|
|
477
475
|
```ruby
|
478
476
|
class NilClassPolicy < ApplicationPolicy
|
479
|
-
class Scope < Scope
|
477
|
+
class Scope < ApplicationPolicy::Scope
|
480
478
|
def resolve
|
481
479
|
raise Pundit::NotDefinedError, "Cannot scope NilClass"
|
482
480
|
end
|
@@ -1,6 +1,12 @@
|
|
1
1
|
<% module_namespacing do -%>
|
2
2
|
class <%= class_name %>Policy < ApplicationPolicy
|
3
|
-
|
3
|
+
# NOTE: Up to Pundit v2.3.1, the inheritance was declared as
|
4
|
+
# `Scope < Scope` rather than `Scope < ApplicationPolicy::Scope`.
|
5
|
+
# In most cases the behavior will be identical, but if updating existing
|
6
|
+
# code, beware of possible changes to the ancestors:
|
7
|
+
# https://gist.github.com/Burgestrand/4b4bc22f31c8a95c425fc0e30d7ef1f5
|
8
|
+
|
9
|
+
class Scope < ApplicationPolicy::Scope
|
4
10
|
# NOTE: Be explicit about which records you allow access to!
|
5
11
|
# def resolve
|
6
12
|
# scope.all
|
data/lib/pundit/authorization.rb
CHANGED
@@ -15,6 +15,14 @@ module Pundit
|
|
15
15
|
|
16
16
|
protected
|
17
17
|
|
18
|
+
# @return [Pundit::Context] a new instance of {Pundit::Context} with the current user
|
19
|
+
def pundit
|
20
|
+
@pundit ||= Pundit::Context.new(
|
21
|
+
user: pundit_user,
|
22
|
+
policy_cache: Pundit::CacheStore::LegacyStore.new(policies)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
18
26
|
# @return [Boolean] whether authorization has been performed, i.e. whether
|
19
27
|
# one {#authorize} or {#skip_authorization} has been called
|
20
28
|
def pundit_policy_authorized?
|
@@ -64,7 +72,7 @@ module Pundit
|
|
64
72
|
|
65
73
|
@_pundit_policy_authorized = true
|
66
74
|
|
67
|
-
|
75
|
+
pundit.authorize(record, query: query, policy_class: policy_class)
|
68
76
|
end
|
69
77
|
|
70
78
|
# Allow this action not to perform authorization.
|
@@ -98,9 +106,9 @@ module Pundit
|
|
98
106
|
#
|
99
107
|
# @see https://github.com/varvet/pundit#policies
|
100
108
|
# @param record [Object] the object we're retrieving the policy for
|
101
|
-
# @return [Object
|
109
|
+
# @return [Object] instance of policy class with query methods
|
102
110
|
def policy(record)
|
103
|
-
|
111
|
+
pundit.policy!(record)
|
104
112
|
end
|
105
113
|
|
106
114
|
# Retrieves a set of permitted attributes from the policy by instantiating
|
@@ -162,7 +170,7 @@ module Pundit
|
|
162
170
|
private
|
163
171
|
|
164
172
|
def pundit_policy_scope(scope)
|
165
|
-
policy_scopes[scope] ||=
|
173
|
+
policy_scopes[scope] ||= pundit.policy_scope!(scope)
|
166
174
|
end
|
167
175
|
end
|
168
176
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pundit
|
4
|
+
module CacheStore
|
5
|
+
# @api private
|
6
|
+
class LegacyStore
|
7
|
+
def initialize(hash = {})
|
8
|
+
@store = hash
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(user:, record:)
|
12
|
+
_ = user
|
13
|
+
@store[record] ||= yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pundit
|
4
|
+
class Context
|
5
|
+
def initialize(user:, policy_cache: CacheStore::NullStore.instance)
|
6
|
+
@user = user
|
7
|
+
@policy_cache = policy_cache
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :user
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
attr_reader :policy_cache
|
14
|
+
|
15
|
+
# Retrieves the policy for the given record, initializing it with the
|
16
|
+
# record and user and finally throwing an error if the user is not
|
17
|
+
# authorized to perform the given action.
|
18
|
+
#
|
19
|
+
# @param user [Object] the user that initiated the action
|
20
|
+
# @param possibly_namespaced_record [Object, Array] the object we're checking permissions of
|
21
|
+
# @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`)
|
22
|
+
# @param policy_class [Class] the policy class we want to force use of
|
23
|
+
# @raise [NotAuthorizedError] if the given query method returned false
|
24
|
+
# @return [Object] Always returns the passed object record
|
25
|
+
def authorize(possibly_namespaced_record, query:, policy_class:)
|
26
|
+
record = pundit_model(possibly_namespaced_record)
|
27
|
+
policy = if policy_class
|
28
|
+
policy_class.new(user, record)
|
29
|
+
else
|
30
|
+
policy!(possibly_namespaced_record)
|
31
|
+
end
|
32
|
+
|
33
|
+
raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
|
34
|
+
|
35
|
+
record
|
36
|
+
end
|
37
|
+
|
38
|
+
# Retrieves the policy scope for the given record.
|
39
|
+
#
|
40
|
+
# @see https://github.com/varvet/pundit#scopes
|
41
|
+
# @param user [Object] the user that initiated the action
|
42
|
+
# @param scope [Object] the object we're retrieving the policy scope for
|
43
|
+
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
44
|
+
# @return [Scope{#resolve}, nil] instance of scope class which can resolve to a scope
|
45
|
+
def policy_scope(scope)
|
46
|
+
policy_scope_class = policy_finder(scope).scope
|
47
|
+
return unless policy_scope_class
|
48
|
+
|
49
|
+
begin
|
50
|
+
policy_scope = policy_scope_class.new(user, pundit_model(scope))
|
51
|
+
rescue ArgumentError
|
52
|
+
raise InvalidConstructorError, "Invalid #<#{policy_scope_class}> constructor is called"
|
53
|
+
end
|
54
|
+
|
55
|
+
policy_scope.resolve
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retrieves the policy scope for the given record. Raises if not found.
|
59
|
+
#
|
60
|
+
# @see https://github.com/varvet/pundit#scopes
|
61
|
+
# @param user [Object] the user that initiated the action
|
62
|
+
# @param scope [Object] the object we're retrieving the policy scope for
|
63
|
+
# @raise [NotDefinedError] if the policy scope cannot be found
|
64
|
+
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
65
|
+
# @return [Scope{#resolve}] instance of scope class which can resolve to a scope
|
66
|
+
def policy_scope!(scope)
|
67
|
+
policy_scope_class = policy_finder(scope).scope!
|
68
|
+
return unless policy_scope_class
|
69
|
+
|
70
|
+
begin
|
71
|
+
policy_scope = policy_scope_class.new(user, pundit_model(scope))
|
72
|
+
rescue ArgumentError
|
73
|
+
raise InvalidConstructorError, "Invalid #<#{policy_scope_class}> constructor is called"
|
74
|
+
end
|
75
|
+
|
76
|
+
policy_scope.resolve
|
77
|
+
end
|
78
|
+
|
79
|
+
# Retrieves the policy for the given record.
|
80
|
+
#
|
81
|
+
# @see https://github.com/varvet/pundit#policies
|
82
|
+
# @param user [Object] the user that initiated the action
|
83
|
+
# @param record [Object] the object we're retrieving the policy for
|
84
|
+
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
85
|
+
# @return [Object, nil] instance of policy class with query methods
|
86
|
+
def policy(record)
|
87
|
+
cached_find(record, &:policy)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Retrieves the policy for the given record. Raises if not found.
|
91
|
+
#
|
92
|
+
# @see https://github.com/varvet/pundit#policies
|
93
|
+
# @param user [Object] the user that initiated the action
|
94
|
+
# @param record [Object] the object we're retrieving the policy for
|
95
|
+
# @raise [NotDefinedError] if the policy cannot be found
|
96
|
+
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
97
|
+
# @return [Object] instance of policy class with query methods
|
98
|
+
def policy!(record)
|
99
|
+
cached_find(record, &:policy!)
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def cached_find(record)
|
105
|
+
policy_cache.fetch(user: user, record: record) do
|
106
|
+
klass = yield policy_finder(record)
|
107
|
+
next unless klass
|
108
|
+
|
109
|
+
model = pundit_model(record)
|
110
|
+
|
111
|
+
begin
|
112
|
+
klass.new(user, model)
|
113
|
+
rescue ArgumentError
|
114
|
+
raise InvalidConstructorError, "Invalid #<#{klass}> constructor is called"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def policy_finder(record)
|
120
|
+
PolicyFinder.new(record)
|
121
|
+
end
|
122
|
+
|
123
|
+
def pundit_model(record)
|
124
|
+
record.is_a?(Array) ? record.last : record
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/pundit/policy_finder.rb
CHANGED
@@ -56,7 +56,7 @@ module Pundit
|
|
56
56
|
|
57
57
|
# @return [String] the name of the key this object would have in a params hash
|
58
58
|
#
|
59
|
-
def param_key
|
59
|
+
def param_key # rubocop:disable Metrics/AbcSize
|
60
60
|
model = object.is_a?(Array) ? object.last : object
|
61
61
|
|
62
62
|
if model.respond_to?(:model_name)
|
data/lib/pundit/version.rb
CHANGED
data/lib/pundit.rb
CHANGED
@@ -8,6 +8,9 @@ require "active_support/core_ext/object/blank"
|
|
8
8
|
require "active_support/core_ext/module/introspection"
|
9
9
|
require "active_support/dependencies/autoload"
|
10
10
|
require "pundit/authorization"
|
11
|
+
require "pundit/context"
|
12
|
+
require "pundit/cache_store/null_store"
|
13
|
+
require "pundit/cache_store/legacy_store"
|
11
14
|
|
12
15
|
# @api private
|
13
16
|
# To avoid name clashes with common Error naming when mixing in Pundit,
|
@@ -64,104 +67,35 @@ module Pundit
|
|
64
67
|
end
|
65
68
|
|
66
69
|
class << self
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# @param user [Object] the user that initiated the action
|
72
|
-
# @param possibly_namespaced_record [Object, Array] the object we're checking permissions of
|
73
|
-
# @param query [Symbol, String] the predicate method to check on the policy (e.g. `:show?`)
|
74
|
-
# @param policy_class [Class] the policy class we want to force use of
|
75
|
-
# @param cache [#[], #[]=] a Hash-like object to cache the found policy instance in
|
76
|
-
# @raise [NotAuthorizedError] if the given query method returned false
|
77
|
-
# @return [Object] Always returns the passed object record
|
78
|
-
def authorize(user, possibly_namespaced_record, query, policy_class: nil, cache: {})
|
79
|
-
record = pundit_model(possibly_namespaced_record)
|
80
|
-
policy = if policy_class
|
81
|
-
policy_class.new(user, record)
|
70
|
+
# @see [Pundit::Context#authorize]
|
71
|
+
def authorize(user, record, query, policy_class: nil, cache: nil)
|
72
|
+
context = if cache
|
73
|
+
Context.new(user: user, policy_cache: cache)
|
82
74
|
else
|
83
|
-
|
75
|
+
Context.new(user: user)
|
84
76
|
end
|
85
77
|
|
86
|
-
|
87
|
-
|
88
|
-
record
|
89
|
-
end
|
90
|
-
|
91
|
-
# Retrieves the policy scope for the given record.
|
92
|
-
#
|
93
|
-
# @see https://github.com/varvet/pundit#scopes
|
94
|
-
# @param user [Object] the user that initiated the action
|
95
|
-
# @param scope [Object] the object we're retrieving the policy scope for
|
96
|
-
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
97
|
-
# @return [Scope{#resolve}, nil] instance of scope class which can resolve to a scope
|
98
|
-
def policy_scope(user, scope)
|
99
|
-
policy_scope_class = PolicyFinder.new(scope).scope
|
100
|
-
return unless policy_scope_class
|
101
|
-
|
102
|
-
begin
|
103
|
-
policy_scope = policy_scope_class.new(user, pundit_model(scope))
|
104
|
-
rescue ArgumentError
|
105
|
-
raise InvalidConstructorError, "Invalid #<#{policy_scope_class}> constructor is called"
|
106
|
-
end
|
107
|
-
|
108
|
-
policy_scope.resolve
|
78
|
+
context.authorize(record, query: query, policy_class: policy_class)
|
109
79
|
end
|
110
80
|
|
111
|
-
#
|
112
|
-
|
113
|
-
|
114
|
-
# @param user [Object] the user that initiated the action
|
115
|
-
# @param scope [Object] the object we're retrieving the policy scope for
|
116
|
-
# @raise [NotDefinedError] if the policy scope cannot be found
|
117
|
-
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
118
|
-
# @return [Scope{#resolve}] instance of scope class which can resolve to a scope
|
119
|
-
def policy_scope!(user, scope)
|
120
|
-
policy_scope_class = PolicyFinder.new(scope).scope!
|
121
|
-
return unless policy_scope_class
|
122
|
-
|
123
|
-
begin
|
124
|
-
policy_scope = policy_scope_class.new(user, pundit_model(scope))
|
125
|
-
rescue ArgumentError
|
126
|
-
raise InvalidConstructorError, "Invalid #<#{policy_scope_class}> constructor is called"
|
127
|
-
end
|
128
|
-
|
129
|
-
policy_scope.resolve
|
81
|
+
# @see [Pundit::Context#policy_scope]
|
82
|
+
def policy_scope(user, *args, **kwargs, &block)
|
83
|
+
Context.new(user: user).policy_scope(*args, **kwargs, &block)
|
130
84
|
end
|
131
85
|
|
132
|
-
#
|
133
|
-
|
134
|
-
|
135
|
-
# @param user [Object] the user that initiated the action
|
136
|
-
# @param record [Object] the object we're retrieving the policy for
|
137
|
-
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
138
|
-
# @return [Object, nil] instance of policy class with query methods
|
139
|
-
def policy(user, record)
|
140
|
-
policy = PolicyFinder.new(record).policy
|
141
|
-
policy&.new(user, pundit_model(record))
|
142
|
-
rescue ArgumentError
|
143
|
-
raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
|
86
|
+
# @see [Pundit::Context#policy_scope!]
|
87
|
+
def policy_scope!(user, *args, **kwargs, &block)
|
88
|
+
Context.new(user: user).policy_scope!(*args, **kwargs, &block)
|
144
89
|
end
|
145
90
|
|
146
|
-
#
|
147
|
-
|
148
|
-
|
149
|
-
# @param user [Object] the user that initiated the action
|
150
|
-
# @param record [Object] the object we're retrieving the policy for
|
151
|
-
# @raise [NotDefinedError] if the policy cannot be found
|
152
|
-
# @raise [InvalidConstructorError] if the policy constructor called incorrectly
|
153
|
-
# @return [Object] instance of policy class with query methods
|
154
|
-
def policy!(user, record)
|
155
|
-
policy = PolicyFinder.new(record).policy!
|
156
|
-
policy.new(user, pundit_model(record))
|
157
|
-
rescue ArgumentError
|
158
|
-
raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
|
91
|
+
# @see [Pundit::Context#policy]
|
92
|
+
def policy(user, *args, **kwargs, &block)
|
93
|
+
Context.new(user: user).policy(*args, **kwargs, &block)
|
159
94
|
end
|
160
95
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
record.is_a?(Array) ? record.last : record
|
96
|
+
# @see [Pundit::Context#policy!]
|
97
|
+
def policy!(user, *args, **kwargs, &block)
|
98
|
+
Context.new(user: user).policy!(*args, **kwargs, &block)
|
165
99
|
end
|
166
100
|
end
|
167
101
|
|
data/pundit.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |gem|
|
|
29
29
|
gem.add_development_dependency "railties", ">= 3.0.0"
|
30
30
|
gem.add_development_dependency "rake"
|
31
31
|
gem.add_development_dependency "rspec", ">= 3.0.0"
|
32
|
-
gem.add_development_dependency "rubocop"
|
32
|
+
gem.add_development_dependency "rubocop"
|
33
33
|
gem.add_development_dependency "simplecov", ">= 0.17.0"
|
34
34
|
gem.add_development_dependency "yard"
|
35
35
|
end
|
data/spec/authorization_spec.rb
CHANGED
@@ -3,10 +3,13 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
describe Pundit::Authorization do
|
6
|
-
|
6
|
+
def to_params(*args, **kwargs, &block)
|
7
|
+
ActionController::Parameters.new(*args, **kwargs, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:controller) { Controller.new(user, "update", to_params({})) }
|
7
11
|
let(:user) { double }
|
8
12
|
let(:post) { Post.new(user) }
|
9
|
-
let(:customer_post) { Customer::Post.new(user) }
|
10
13
|
let(:comment) { Comment.new }
|
11
14
|
let(:article) { Article.new }
|
12
15
|
let(:article_tag) { ArticleTag.new }
|
@@ -188,7 +191,7 @@ describe Pundit::Authorization do
|
|
188
191
|
|
189
192
|
describe "#permitted_attributes" do
|
190
193
|
it "checks policy for permitted attributes" do
|
191
|
-
params =
|
194
|
+
params = to_params(
|
192
195
|
post: {
|
193
196
|
title: "Hello",
|
194
197
|
votes: 5,
|
@@ -206,7 +209,8 @@ describe Pundit::Authorization do
|
|
206
209
|
end
|
207
210
|
|
208
211
|
it "checks policy for permitted attributes for record of a ActiveModel type" do
|
209
|
-
|
212
|
+
customer_post = Customer::Post.new(user)
|
213
|
+
params = to_params(
|
210
214
|
customer_post: {
|
211
215
|
title: "Hello",
|
212
216
|
votes: 5,
|
@@ -224,11 +228,23 @@ describe Pundit::Authorization do
|
|
224
228
|
"votes" => 5
|
225
229
|
)
|
226
230
|
end
|
231
|
+
|
232
|
+
it "goes through the policy cache" do
|
233
|
+
params = to_params(post: { title: "Hello" })
|
234
|
+
user = double
|
235
|
+
post = Post.new(user)
|
236
|
+
controller = Controller.new(user, "update", params)
|
237
|
+
|
238
|
+
expect do
|
239
|
+
expect(controller.permitted_attributes(post)).to be_truthy
|
240
|
+
expect(controller.permitted_attributes(post)).to be_truthy
|
241
|
+
end.to change { PostPolicy.instances }.by(1)
|
242
|
+
end
|
227
243
|
end
|
228
244
|
|
229
245
|
describe "#permitted_attributes_for_action" do
|
230
246
|
it "is checked if it is defined in the policy" do
|
231
|
-
params =
|
247
|
+
params = to_params(
|
232
248
|
post: {
|
233
249
|
title: "Hello",
|
234
250
|
body: "blah",
|
@@ -242,7 +258,7 @@ describe Pundit::Authorization do
|
|
242
258
|
end
|
243
259
|
|
244
260
|
it "can be explicitly set" do
|
245
|
-
params =
|
261
|
+
params = to_params(
|
246
262
|
post: {
|
247
263
|
title: "Hello",
|
248
264
|
body: "blah",
|
data/spec/generators_spec.rb
CHANGED
@@ -35,7 +35,7 @@ RSpec.describe "generators" do
|
|
35
35
|
describe "#resolve" do
|
36
36
|
it "raises a descriptive error" do
|
37
37
|
scope = WidgetPolicy::Scope.new(double("User"), double("User.all"))
|
38
|
-
expect { scope.resolve }.to raise_error(
|
38
|
+
expect { scope.resolve }.to raise_error(NoMethodError, /WidgetPolicy::Scope/)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/spec/pundit_spec.rb
CHANGED
@@ -64,7 +64,11 @@ RSpec.describe Pundit do
|
|
64
64
|
end.to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this Post") do |error|
|
65
65
|
expect(error.query).to eq :destroy?
|
66
66
|
expect(error.record).to eq post
|
67
|
-
expect(error.policy).to
|
67
|
+
expect(error.policy).to have_attributes(
|
68
|
+
user: user,
|
69
|
+
record: post
|
70
|
+
)
|
71
|
+
expect(error.policy).to be_a(PostPolicy)
|
68
72
|
end
|
69
73
|
# rubocop:enable Style/MultilineBlockChain
|
70
74
|
end
|
@@ -76,7 +80,11 @@ RSpec.describe Pundit do
|
|
76
80
|
end.to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this Comment") do |error|
|
77
81
|
expect(error.query).to eq :destroy?
|
78
82
|
expect(error.record).to eq comment
|
79
|
-
expect(error.policy).to
|
83
|
+
expect(error.policy).to have_attributes(
|
84
|
+
user: user,
|
85
|
+
record: comment
|
86
|
+
)
|
87
|
+
expect(error.policy).to be_a(Project::Admin::CommentPolicy)
|
80
88
|
end
|
81
89
|
# rubocop:enable Style/MultilineBlockChain
|
82
90
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
if ENV["COVERAGE"]
|
4
|
+
require "simplecov"
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter "/spec/"
|
7
|
+
end
|
6
8
|
end
|
7
9
|
|
8
10
|
require "pundit"
|
@@ -16,13 +18,56 @@ require "active_support/core_ext"
|
|
16
18
|
require "active_model/naming"
|
17
19
|
require "action_controller/metal/strong_parameters"
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
module InstanceTracking
|
22
|
+
module ClassMethods
|
23
|
+
def instances
|
24
|
+
@instances || 0
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_writer :instances
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.prepended(other)
|
31
|
+
other.extend(ClassMethods)
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(*args, **kwargs, &block)
|
35
|
+
self.class.instances += 1
|
36
|
+
super(*args, **kwargs, &block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class BasePolicy
|
41
|
+
prepend InstanceTracking
|
42
|
+
|
43
|
+
class BaseScope
|
44
|
+
prepend InstanceTracking
|
45
|
+
|
46
|
+
def initialize(user, scope)
|
47
|
+
@user = user
|
48
|
+
@scope = scope
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_reader :user, :scope
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(user, record)
|
55
|
+
@user = user
|
56
|
+
@record = record
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_reader :user, :record
|
60
|
+
end
|
61
|
+
|
62
|
+
class PostPolicy < BasePolicy
|
63
|
+
class Scope < BaseScope
|
21
64
|
def resolve
|
22
65
|
scope.published
|
23
66
|
end
|
24
67
|
end
|
25
68
|
|
69
|
+
alias post record
|
70
|
+
|
26
71
|
def update?
|
27
72
|
post.user == user
|
28
73
|
end
|
@@ -48,7 +93,13 @@ class PostPolicy < Struct.new(:user, :post)
|
|
48
93
|
end
|
49
94
|
end
|
50
95
|
|
51
|
-
class Post
|
96
|
+
class Post
|
97
|
+
def initialize(user = nil)
|
98
|
+
@user = user
|
99
|
+
end
|
100
|
+
|
101
|
+
attr_reader :user
|
102
|
+
|
52
103
|
def self.published
|
53
104
|
:published
|
54
105
|
end
|
@@ -67,7 +118,7 @@ class Post < Struct.new(:user)
|
|
67
118
|
end
|
68
119
|
|
69
120
|
module Customer
|
70
|
-
class Post < Post
|
121
|
+
class Post < ::Post
|
71
122
|
def model_name
|
72
123
|
OpenStruct.new(param_key: "customer_post")
|
73
124
|
end
|
@@ -90,16 +141,18 @@ class CommentScope
|
|
90
141
|
end
|
91
142
|
end
|
92
143
|
|
93
|
-
class CommentPolicy <
|
94
|
-
class Scope <
|
144
|
+
class CommentPolicy < BasePolicy
|
145
|
+
class Scope < BaseScope
|
95
146
|
def resolve
|
96
147
|
CommentScope.new(scope)
|
97
148
|
end
|
98
149
|
end
|
150
|
+
|
151
|
+
alias comment record
|
99
152
|
end
|
100
153
|
|
101
|
-
class PublicationPolicy <
|
102
|
-
class Scope <
|
154
|
+
class PublicationPolicy < BasePolicy
|
155
|
+
class Scope < BaseScope
|
103
156
|
def resolve
|
104
157
|
scope.published
|
105
158
|
end
|
@@ -130,7 +183,9 @@ end
|
|
130
183
|
|
131
184
|
class Article; end
|
132
185
|
|
133
|
-
class BlogPolicy <
|
186
|
+
class BlogPolicy < BasePolicy
|
187
|
+
alias blog record
|
188
|
+
end
|
134
189
|
|
135
190
|
class Blog; end
|
136
191
|
|
@@ -140,7 +195,7 @@ class ArtificialBlog < Blog
|
|
140
195
|
end
|
141
196
|
end
|
142
197
|
|
143
|
-
class ArticleTagOtherNamePolicy <
|
198
|
+
class ArticleTagOtherNamePolicy < BasePolicy
|
144
199
|
def show?
|
145
200
|
true
|
146
201
|
end
|
@@ -148,6 +203,8 @@ class ArticleTagOtherNamePolicy < Struct.new(:user, :tag)
|
|
148
203
|
def destroy?
|
149
204
|
false
|
150
205
|
end
|
206
|
+
|
207
|
+
alias tag record
|
151
208
|
end
|
152
209
|
|
153
210
|
class ArticleTag
|
@@ -156,33 +213,41 @@ class ArticleTag
|
|
156
213
|
end
|
157
214
|
end
|
158
215
|
|
159
|
-
class CriteriaPolicy <
|
216
|
+
class CriteriaPolicy < BasePolicy
|
217
|
+
alias criteria record
|
218
|
+
end
|
160
219
|
|
161
220
|
module Project
|
162
|
-
class CommentPolicy <
|
163
|
-
|
164
|
-
true
|
165
|
-
end
|
166
|
-
|
167
|
-
class Scope < Struct.new(:user, :scope)
|
221
|
+
class CommentPolicy < BasePolicy
|
222
|
+
class Scope < BaseScope
|
168
223
|
def resolve
|
169
224
|
scope
|
170
225
|
end
|
171
226
|
end
|
227
|
+
|
228
|
+
def update?
|
229
|
+
true
|
230
|
+
end
|
231
|
+
|
232
|
+
alias comment record
|
172
233
|
end
|
173
234
|
|
174
|
-
class CriteriaPolicy <
|
235
|
+
class CriteriaPolicy < BasePolicy
|
236
|
+
alias criteria record
|
237
|
+
end
|
175
238
|
|
176
|
-
class PostPolicy <
|
177
|
-
class Scope <
|
239
|
+
class PostPolicy < BasePolicy
|
240
|
+
class Scope < BaseScope
|
178
241
|
def resolve
|
179
242
|
scope.read
|
180
243
|
end
|
181
244
|
end
|
245
|
+
|
246
|
+
alias post record
|
182
247
|
end
|
183
248
|
|
184
249
|
module Admin
|
185
|
-
class CommentPolicy <
|
250
|
+
class CommentPolicy < BasePolicy
|
186
251
|
def update?
|
187
252
|
true
|
188
253
|
end
|
@@ -194,7 +259,7 @@ module Project
|
|
194
259
|
end
|
195
260
|
end
|
196
261
|
|
197
|
-
class DenierPolicy <
|
262
|
+
class DenierPolicy < BasePolicy
|
198
263
|
def update?
|
199
264
|
false
|
200
265
|
end
|
@@ -216,7 +281,7 @@ class Controller
|
|
216
281
|
end
|
217
282
|
end
|
218
283
|
|
219
|
-
class NilClassPolicy <
|
284
|
+
class NilClassPolicy < BasePolicy
|
220
285
|
class Scope
|
221
286
|
def initialize(*)
|
222
287
|
raise Pundit::NotDefinedError, "Cannot scope NilClass"
|
@@ -245,8 +310,8 @@ class Thread
|
|
245
310
|
def self.all; end
|
246
311
|
end
|
247
312
|
|
248
|
-
class ThreadPolicy <
|
249
|
-
class Scope <
|
313
|
+
class ThreadPolicy < BasePolicy
|
314
|
+
class Scope < BaseScope
|
250
315
|
def resolve
|
251
316
|
# deliberate wrong useage of the method
|
252
317
|
scope.all(:unvalid, :parameters)
|
@@ -254,22 +319,34 @@ class ThreadPolicy < Struct.new(:user, :thread)
|
|
254
319
|
end
|
255
320
|
end
|
256
321
|
|
257
|
-
class PostFourFiveSix
|
322
|
+
class PostFourFiveSix
|
323
|
+
def initialize(user)
|
324
|
+
@user = user
|
325
|
+
end
|
326
|
+
|
327
|
+
attr_reader(:user)
|
328
|
+
end
|
258
329
|
|
259
330
|
class CommentFourFiveSix; extend ActiveModel::Naming; end
|
260
331
|
|
261
332
|
module ProjectOneTwoThree
|
262
|
-
class CommentFourFiveSixPolicy <
|
333
|
+
class CommentFourFiveSixPolicy < BasePolicy; end
|
263
334
|
|
264
|
-
class CriteriaFourFiveSixPolicy <
|
335
|
+
class CriteriaFourFiveSixPolicy < BasePolicy; end
|
265
336
|
|
266
|
-
class PostFourFiveSixPolicy <
|
337
|
+
class PostFourFiveSixPolicy < BasePolicy; end
|
267
338
|
|
268
|
-
class TagFourFiveSix
|
339
|
+
class TagFourFiveSix
|
340
|
+
def initialize(user)
|
341
|
+
@user = user
|
342
|
+
end
|
343
|
+
|
344
|
+
attr_reader(:user)
|
345
|
+
end
|
269
346
|
|
270
|
-
class TagFourFiveSixPolicy <
|
347
|
+
class TagFourFiveSixPolicy < BasePolicy; end
|
271
348
|
|
272
349
|
class AvatarFourFiveSix; extend ActiveModel::Naming; end
|
273
350
|
|
274
|
-
class AvatarFourFiveSixPolicy <
|
351
|
+
class AvatarFourFiveSixPolicy < BasePolicy; end
|
275
352
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pundit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
8
8
|
- Varvet AB
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-05-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -127,16 +127,16 @@ dependencies:
|
|
127
127
|
name: rubocop
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
|
-
- -
|
130
|
+
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
132
|
+
version: '0'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- -
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
139
|
+
version: '0'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: simplecov
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,10 +173,12 @@ executables: []
|
|
173
173
|
extensions: []
|
174
174
|
extra_rdoc_files: []
|
175
175
|
files:
|
176
|
-
- ".github/
|
176
|
+
- ".github/PULL_REQUEST_TEMPLATE/gem_release_template.md"
|
177
|
+
- ".github/PULL_REQUEST_TEMPLATE/pull_request_template.md"
|
178
|
+
- ".github/workflows/main.yml"
|
179
|
+
- ".github/workflows/push_gem.yml"
|
177
180
|
- ".gitignore"
|
178
181
|
- ".rubocop.yml"
|
179
|
-
- ".travis.yml"
|
180
182
|
- ".yardopts"
|
181
183
|
- CHANGELOG.md
|
182
184
|
- CODE_OF_CONDUCT.md
|
@@ -199,6 +201,9 @@ files:
|
|
199
201
|
- lib/generators/test_unit/templates/policy_test.rb
|
200
202
|
- lib/pundit.rb
|
201
203
|
- lib/pundit/authorization.rb
|
204
|
+
- lib/pundit/cache_store/legacy_store.rb
|
205
|
+
- lib/pundit/cache_store/null_store.rb
|
206
|
+
- lib/pundit/context.rb
|
202
207
|
- lib/pundit/policy_finder.rb
|
203
208
|
- lib/pundit/rspec.rb
|
204
209
|
- lib/pundit/version.rb
|
@@ -214,7 +219,7 @@ licenses:
|
|
214
219
|
- MIT
|
215
220
|
metadata:
|
216
221
|
rubygems_mfa_required: 'true'
|
217
|
-
post_install_message:
|
222
|
+
post_install_message:
|
218
223
|
rdoc_options: []
|
219
224
|
require_paths:
|
220
225
|
- lib
|
@@ -229,8 +234,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
234
|
- !ruby/object:Gem::Version
|
230
235
|
version: '0'
|
231
236
|
requirements: []
|
232
|
-
rubygems_version: 3.
|
233
|
-
signing_key:
|
237
|
+
rubygems_version: 3.5.9
|
238
|
+
signing_key:
|
234
239
|
specification_version: 4
|
235
240
|
summary: OO authorization for Rails
|
236
241
|
test_files:
|
data/.travis.yml
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
dist: focal
|
3
|
-
|
4
|
-
matrix:
|
5
|
-
include:
|
6
|
-
- name: "RuboCop lint on pre-installed Ruby version"
|
7
|
-
rvm: 2.7.1 # Pre-installed Ruby version
|
8
|
-
before_install:
|
9
|
-
- gem install bundler
|
10
|
-
script: bundle exec rake rubocop # ONLY lint once, first
|
11
|
-
- rvm: 2.6.7
|
12
|
-
before_script:
|
13
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
14
|
-
- chmod +x ./cc-test-reporter
|
15
|
-
- ./cc-test-reporter before-build
|
16
|
-
after_script:
|
17
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
18
|
-
- rvm: 2.7.3
|
19
|
-
- rvm: 3.0.1
|
20
|
-
- rvm: 3.1.0
|
21
|
-
- rvm: 3.2.0
|
22
|
-
- rvm: jruby-9.3.10.0
|
23
|
-
env:
|
24
|
-
- JRUBY_OPTS="--debug"
|
25
|
-
- rvm: truffleruby-head
|
26
|
-
allow_failures:
|
27
|
-
- rvm: truffleruby-head
|
File without changes
|