pundit 2.3.2 → 2.5.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 +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +26 -0
- data/.github/PULL_REQUEST_TEMPLATE/gem_release_template.md +4 -4
- data/.github/workflows/main.yml +92 -52
- data/.github/workflows/push_gem.yml +4 -4
- data/.rubocop.yml +18 -8
- data/.rubocop_ignore_git.yml +7 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +68 -37
- data/CODE_OF_CONDUCT.md +1 -1
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +22 -2
- data/README.md +88 -15
- data/Rakefile +1 -0
- data/lib/generators/pundit/install/install_generator.rb +3 -1
- data/lib/generators/pundit/policy/policy_generator.rb +3 -1
- data/lib/generators/rspec/policy_generator.rb +4 -1
- data/lib/generators/test_unit/policy_generator.rb +4 -1
- data/lib/pundit/authorization.rb +152 -77
- data/lib/pundit/cache_store/legacy_store.rb +7 -0
- data/lib/pundit/cache_store/null_store.rb +9 -0
- data/lib/pundit/cache_store.rb +22 -0
- data/lib/pundit/context.rb +76 -26
- data/lib/pundit/policy_finder.rb +22 -1
- data/lib/pundit/railtie.rb +19 -0
- data/lib/pundit/rspec.rb +90 -7
- data/lib/pundit/version.rb +2 -1
- data/lib/pundit.rb +43 -15
- data/pundit.gemspec +8 -12
- data/spec/authorization_spec.rb +61 -4
- data/spec/policies/post_policy_spec.rb +27 -0
- data/spec/policy_finder_spec.rb +5 -1
- data/spec/pundit/helper_spec.rb +18 -0
- data/spec/pundit_spec.rb +58 -15
- data/spec/rspec_dsl_spec.rb +81 -0
- data/spec/simple_cov_check_action_formatter.rb +79 -0
- data/spec/spec_helper.rb +22 -339
- data/spec/support/lib/controller.rb +38 -0
- data/spec/support/lib/custom_cache.rb +19 -0
- data/spec/support/lib/instance_tracking.rb +20 -0
- data/spec/support/models/article.rb +4 -0
- data/spec/support/models/article_tag.rb +7 -0
- data/spec/support/models/artificial_blog.rb +7 -0
- data/spec/support/models/blog.rb +4 -0
- data/spec/support/models/comment.rb +5 -0
- data/spec/support/models/comment_four_five_six.rb +5 -0
- data/spec/support/models/comment_scope.rb +13 -0
- data/spec/support/models/comments_relation.rb +15 -0
- data/spec/support/models/customer/post.rb +11 -0
- data/spec/support/models/default_scope_contains_error.rb +5 -0
- data/spec/support/models/dummy_current_user.rb +7 -0
- data/spec/support/models/foo.rb +4 -0
- data/spec/support/models/post.rb +25 -0
- data/spec/support/models/post_four_five_six.rb +9 -0
- data/spec/support/models/project_one_two_three/avatar_four_five_six.rb +7 -0
- data/spec/support/models/project_one_two_three/tag_four_five_six.rb +11 -0
- data/spec/support/models/wiki.rb +4 -0
- data/spec/support/policies/article_tag_other_name_policy.rb +13 -0
- data/spec/support/policies/base_policy.rb +23 -0
- data/spec/support/policies/blog_policy.rb +5 -0
- data/spec/support/policies/comment_policy.rb +11 -0
- data/spec/support/policies/criteria_policy.rb +5 -0
- data/spec/support/policies/default_scope_contains_error_policy.rb +10 -0
- data/spec/support/policies/denier_policy.rb +7 -0
- data/spec/support/policies/dummy_current_user_policy.rb +9 -0
- data/spec/support/policies/nil_class_policy.rb +17 -0
- data/spec/support/policies/post_policy.rb +36 -0
- data/spec/support/policies/project/admin/comment_policy.rb +15 -0
- data/spec/support/policies/project/comment_policy.rb +17 -0
- data/spec/support/policies/project/criteria_policy.rb +7 -0
- data/spec/support/policies/project/post_policy.rb +13 -0
- data/spec/support/policies/project_one_two_three/avatar_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/comment_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/criteria_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/post_four_five_six_policy.rb +6 -0
- data/spec/support/policies/project_one_two_three/tag_four_five_six_policy.rb +6 -0
- data/spec/support/policies/publication_policy.rb +13 -0
- data/spec/support/policies/wiki_policy.rb +8 -0
- metadata +66 -158
- /data/.github/{PULL_REQUEST_TEMPLATE/pull_request_template.md → pull_request_template.md} +0 -0
- /data/lib/generators/pundit/install/templates/{application_policy.rb → application_policy.rb.tt} +0 -0
- /data/lib/generators/pundit/policy/templates/{policy.rb → policy.rb.tt} +0 -0
- /data/lib/generators/rspec/templates/{policy_spec.rb → policy_spec.rb.tt} +0 -0
- /data/lib/generators/test_unit/templates/{policy_test.rb → policy_test.rb.tt} +0 -0
data/spec/policy_finder_spec.rb
CHANGED
@@ -2,13 +2,17 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
class Foo; end
|
6
5
|
RSpec.describe Pundit::PolicyFinder do
|
7
6
|
let(:user) { double }
|
8
7
|
let(:post) { Post.new(user) }
|
9
8
|
let(:comment) { CommentFourFiveSix.new }
|
10
9
|
let(:article) { Article.new }
|
11
10
|
|
11
|
+
describe "SUFFIX" do
|
12
|
+
specify { expect(described_class::SUFFIX).to eq "Policy" }
|
13
|
+
specify { expect(Pundit::SUFFIX).to eq(described_class::SUFFIX) }
|
14
|
+
end
|
15
|
+
|
12
16
|
describe "#scope" do
|
13
17
|
subject { described_class.new(post) }
|
14
18
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe Pundit::Helper do
|
6
|
+
let(:user) { double }
|
7
|
+
let(:controller) { Controller.new(user, "update", double) }
|
8
|
+
let(:view) { Controller::View.new(controller) }
|
9
|
+
|
10
|
+
describe "#policy_scope" do
|
11
|
+
it "doesn't flip pundit_policy_scoped?" do
|
12
|
+
scoped = view.policy_scope(Post)
|
13
|
+
|
14
|
+
expect(scoped).to be(Post.published)
|
15
|
+
expect(controller).not_to be_pundit_policy_scoped
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/pundit_spec.rb
CHANGED
@@ -43,25 +43,16 @@ RSpec.describe Pundit do
|
|
43
43
|
expect(Pundit.authorize(user, Post, :show?)).to eq(Post)
|
44
44
|
end
|
45
45
|
|
46
|
-
it "can be given a different policy class" do
|
47
|
-
expect(Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy)).to be_truthy
|
48
|
-
end
|
49
|
-
|
50
|
-
it "can be given a different policy class using namespaces" do
|
51
|
-
expect(PublicationPolicy).to receive(:new).with(user, comment).and_call_original
|
52
|
-
expect(Pundit.authorize(user, [:project, comment], :create?, policy_class: PublicationPolicy)).to be_truthy
|
53
|
-
end
|
54
|
-
|
55
46
|
it "works with anonymous class policies" do
|
56
47
|
expect(Pundit.authorize(user, article_tag, :show?)).to be_truthy
|
57
48
|
expect { Pundit.authorize(user, article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
|
58
49
|
end
|
59
50
|
|
60
|
-
it "raises an error with
|
51
|
+
it "raises an error with the policy, query and record" do
|
61
52
|
# rubocop:disable Style/MultilineBlockChain
|
62
53
|
expect do
|
63
54
|
Pundit.authorize(user, post, :destroy?)
|
64
|
-
end.to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this Post") do |error|
|
55
|
+
end.to raise_error(Pundit::NotAuthorizedError, "not allowed to PostPolicy#destroy? this Post") do |error|
|
65
56
|
expect(error.query).to eq :destroy?
|
66
57
|
expect(error.record).to eq post
|
67
58
|
expect(error.policy).to have_attributes(
|
@@ -73,11 +64,12 @@ RSpec.describe Pundit do
|
|
73
64
|
# rubocop:enable Style/MultilineBlockChain
|
74
65
|
end
|
75
66
|
|
76
|
-
it "raises an error with
|
67
|
+
it "raises an error with the policy, query and record when the record is namespaced" do
|
77
68
|
# rubocop:disable Style/MultilineBlockChain
|
78
69
|
expect do
|
79
70
|
Pundit.authorize(user, [:project, :admin, comment], :destroy?)
|
80
|
-
end.to raise_error(Pundit::NotAuthorizedError,
|
71
|
+
end.to raise_error(Pundit::NotAuthorizedError,
|
72
|
+
"not allowed to Project::Admin::CommentPolicy#destroy? this Comment") do |error|
|
81
73
|
expect(error.query).to eq :destroy?
|
82
74
|
expect(error.record).to eq comment
|
83
75
|
expect(error.policy).to have_attributes(
|
@@ -89,11 +81,62 @@ RSpec.describe Pundit do
|
|
89
81
|
# rubocop:enable Style/MultilineBlockChain
|
90
82
|
end
|
91
83
|
|
84
|
+
it "raises an error with the policy, query and the class name when a Class is given" do
|
85
|
+
# rubocop:disable Style/MultilineBlockChain
|
86
|
+
expect do
|
87
|
+
Pundit.authorize(user, Post, :destroy?)
|
88
|
+
end.to raise_error(Pundit::NotAuthorizedError, "not allowed to PostPolicy#destroy? Post") do |error|
|
89
|
+
expect(error.query).to eq :destroy?
|
90
|
+
expect(error.record).to eq Post
|
91
|
+
expect(error.policy).to have_attributes(
|
92
|
+
user: user,
|
93
|
+
record: Post
|
94
|
+
)
|
95
|
+
expect(error.policy).to be_a(PostPolicy)
|
96
|
+
end
|
97
|
+
# rubocop:enable Style/MultilineBlockChain
|
98
|
+
end
|
99
|
+
|
92
100
|
it "raises an error with a invalid policy constructor" do
|
93
101
|
expect do
|
94
102
|
Pundit.authorize(user, wiki, :update?)
|
95
103
|
end.to raise_error(Pundit::InvalidConstructorError, "Invalid #<WikiPolicy> constructor is called")
|
96
104
|
end
|
105
|
+
|
106
|
+
context "when passed a policy class" do
|
107
|
+
it "uses the passed policy class" do
|
108
|
+
expect(Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy)).to be_truthy
|
109
|
+
end
|
110
|
+
|
111
|
+
# This is documenting past behaviour.
|
112
|
+
it "doesn't cache the policy class" do
|
113
|
+
cache = {}
|
114
|
+
|
115
|
+
expect do
|
116
|
+
Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy, cache: cache)
|
117
|
+
Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy, cache: cache)
|
118
|
+
end.to change { PublicationPolicy.instances }.by(2)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when passed a policy class while simultaenously passing a namespace" do
|
123
|
+
it "uses the passed policy class" do
|
124
|
+
expect(PublicationPolicy).to receive(:new).with(user, comment).and_call_original
|
125
|
+
expect(Pundit.authorize(user, [:project, comment], :create?, policy_class: PublicationPolicy)).to be_truthy
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when passed an explicit cache" do
|
130
|
+
it "uses the hash assignment interface on the cache" do
|
131
|
+
custom_cache = CustomCache.new
|
132
|
+
|
133
|
+
Pundit.authorize(user, post, :update?, cache: custom_cache)
|
134
|
+
|
135
|
+
expect(custom_cache.to_h).to match({
|
136
|
+
post => kind_of(PostPolicy)
|
137
|
+
})
|
138
|
+
end
|
139
|
+
end
|
97
140
|
end
|
98
141
|
|
99
142
|
describe ".policy_scope" do
|
@@ -137,8 +180,8 @@ RSpec.describe Pundit do
|
|
137
180
|
|
138
181
|
it "raises an original error with a policy scope that contains error" do
|
139
182
|
expect do
|
140
|
-
Pundit.policy_scope(user,
|
141
|
-
end.to raise_error(
|
183
|
+
Pundit.policy_scope(user, DefaultScopeContainsError)
|
184
|
+
end.to raise_error(RuntimeError, "This is an arbitrary error that should bubble up")
|
142
185
|
end
|
143
186
|
end
|
144
187
|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe "Pundit RSpec DSL" do
|
6
|
+
include Pundit::RSpec::PolicyExampleGroup
|
7
|
+
|
8
|
+
let(:fake_rspec) do
|
9
|
+
double = class_double(RSpec::ExampleGroups)
|
10
|
+
double.extend(::Pundit::RSpec::DSL)
|
11
|
+
double
|
12
|
+
end
|
13
|
+
let(:block) { proc { "block content" } }
|
14
|
+
|
15
|
+
let(:user) { double }
|
16
|
+
let(:other_user) { double }
|
17
|
+
let(:post) { Post.new(user) }
|
18
|
+
let(:policy) { PostPolicy }
|
19
|
+
|
20
|
+
it "calls describe with the correct metadata and without :focus" do
|
21
|
+
expected_metadata = { permissions: %i[item1 item2], caller: instance_of(Array) }
|
22
|
+
expect(fake_rspec).to receive(:describe).with("item1 and item2", match(expected_metadata)) do |&block|
|
23
|
+
expect(block.call).to eq("block content")
|
24
|
+
end
|
25
|
+
|
26
|
+
fake_rspec.permissions(:item1, :item2, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "calls describe with the correct metadata and with :focus" do
|
30
|
+
expected_metadata = { permissions: %i[item1 item2], caller: instance_of(Array), focus: true }
|
31
|
+
expect(fake_rspec).to receive(:describe).with("item1 and item2", match(expected_metadata)) do |&block|
|
32
|
+
expect(block.call).to eq("block content")
|
33
|
+
end
|
34
|
+
|
35
|
+
fake_rspec.permissions(:item1, :item2, :focus, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#permit" do
|
39
|
+
context "when not appropriately wrapped in permissions" do
|
40
|
+
it "raises a descriptive error" do
|
41
|
+
expect do
|
42
|
+
expect(policy).to permit(user, post)
|
43
|
+
end.to raise_error(KeyError, <<~MSG.strip)
|
44
|
+
No permissions in example metadata, did you forget to wrap with `permissions :show?, ...`?
|
45
|
+
MSG
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
permissions :edit?, :update? do
|
50
|
+
it "succeeds when action is permitted" do
|
51
|
+
expect(policy).to permit(user, post)
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when it fails" do
|
55
|
+
it "fails with a descriptive error message" do
|
56
|
+
expect do
|
57
|
+
expect(policy).to permit(other_user, post)
|
58
|
+
end.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<~MSG.strip)
|
59
|
+
Expected PostPolicy to grant edit? and update? on Post but edit? and update? were not granted
|
60
|
+
MSG
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when negated" do
|
65
|
+
it "succeeds when action is not permitted" do
|
66
|
+
expect(policy).not_to permit(other_user, post)
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when it fails" do
|
70
|
+
it "fails with a descriptive error message" do
|
71
|
+
expect do
|
72
|
+
expect(policy).not_to permit(user, post)
|
73
|
+
end.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<~MSG.strip)
|
74
|
+
Expected PostPolicy not to grant edit? and update? on Post but edit? and update? were granted
|
75
|
+
MSG
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "simplecov"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
class SimpleCovCheckActionFormatter
|
7
|
+
SourceFile = Data.define(:source_file) do
|
8
|
+
def covered_strength = source_file.covered_strength
|
9
|
+
def covered_percent = source_file.covered_percent
|
10
|
+
|
11
|
+
def to_json(*args)
|
12
|
+
{
|
13
|
+
filename: source_file.filename,
|
14
|
+
covered_percent: covered_percent.nan? ? 0.0 : covered_percent,
|
15
|
+
coverage: source_file.coverage_data,
|
16
|
+
covered_strength: covered_strength.nan? ? 0.0 : covered_strength,
|
17
|
+
covered_lines: source_file.covered_lines.count,
|
18
|
+
lines_of_code: source_file.lines_of_code
|
19
|
+
}.to_json(*args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Result = Data.define(:result) do
|
24
|
+
def included?(source_file) = result.filenames.include?(source_file.filename)
|
25
|
+
|
26
|
+
def files
|
27
|
+
result.files.filter_map do |source_file|
|
28
|
+
next unless result.filenames.include? source_file.filename
|
29
|
+
|
30
|
+
SourceFile.new(source_file)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_json(*args) # rubocop:disable Metrics/AbcSize
|
35
|
+
{
|
36
|
+
timestamp: result.created_at.to_i,
|
37
|
+
command_name: result.command_name,
|
38
|
+
files: files,
|
39
|
+
metrics: {
|
40
|
+
covered_percent: result.covered_percent,
|
41
|
+
covered_strength: result.covered_strength.nan? ? 0.0 : result.covered_strength,
|
42
|
+
covered_lines: result.covered_lines,
|
43
|
+
total_lines: result.total_lines
|
44
|
+
}
|
45
|
+
}.to_json(*args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
FormatterWithOptions = Data.define(:formatter) do
|
50
|
+
def new = formatter
|
51
|
+
end
|
52
|
+
|
53
|
+
class << self
|
54
|
+
def with_options(...)
|
55
|
+
FormatterWithOptions.new(new(...))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(output_filename: "coverage.json", output_directory: SimpleCov.coverage_path)
|
60
|
+
@output_filename = output_filename
|
61
|
+
@output_directory = output_directory
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_reader :output_filename, :output_directory
|
65
|
+
|
66
|
+
def output_filepath = File.join(output_directory, output_filename)
|
67
|
+
|
68
|
+
def format(result_data)
|
69
|
+
result = Result.new(result_data)
|
70
|
+
json = JSON.generate(result)
|
71
|
+
File.write(output_filepath, json)
|
72
|
+
puts output_message(result_data)
|
73
|
+
json
|
74
|
+
end
|
75
|
+
|
76
|
+
def output_message(result)
|
77
|
+
"Coverage report generated for #{result.command_name} to #{output_filepath}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered." # rubocop:disable Layout/LineLength
|
78
|
+
end
|
79
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,351 +2,34 @@
|
|
2
2
|
|
3
3
|
if ENV["COVERAGE"]
|
4
4
|
require "simplecov"
|
5
|
+
require "simplecov_json_formatter"
|
6
|
+
require_relative "simple_cov_check_action_formatter"
|
7
|
+
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
|
8
|
+
SimpleCov::Formatter::HTMLFormatter,
|
9
|
+
SimpleCov::Formatter::JSONFormatter,
|
10
|
+
SimpleCovCheckActionFormatter.with_options(
|
11
|
+
output_filename: "simplecov-check-action.json"
|
12
|
+
)
|
13
|
+
])
|
5
14
|
SimpleCov.start do
|
6
15
|
add_filter "/spec/"
|
16
|
+
enable_coverage :branch
|
17
|
+
primary_coverage :branch
|
7
18
|
end
|
8
19
|
end
|
9
20
|
|
21
|
+
# @see https://github.com/rails/rails/issues/54260
|
22
|
+
require "logger" if RUBY_ENGINE == "jruby" && RUBY_ENGINE_VERSION.start_with?("9.3")
|
23
|
+
|
10
24
|
require "pundit"
|
11
25
|
require "pundit/rspec"
|
12
|
-
|
13
|
-
require "rack"
|
14
|
-
require "rack/test"
|
15
|
-
require "pry"
|
16
|
-
require "active_support"
|
17
|
-
require "active_support/core_ext"
|
18
26
|
require "active_model/naming"
|
19
|
-
require "action_controller/metal/strong_parameters"
|
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
|
64
|
-
def resolve
|
65
|
-
scope.published
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
alias post record
|
70
|
-
|
71
|
-
def update?
|
72
|
-
post.user == user
|
73
|
-
end
|
74
|
-
|
75
|
-
def destroy?
|
76
|
-
false
|
77
|
-
end
|
78
|
-
|
79
|
-
def show?
|
80
|
-
true
|
81
|
-
end
|
82
|
-
|
83
|
-
def permitted_attributes
|
84
|
-
if post.user == user
|
85
|
-
%i[title votes]
|
86
|
-
else
|
87
|
-
[:votes]
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def permitted_attributes_for_revise
|
92
|
-
[:body]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
class Post
|
97
|
-
def initialize(user = nil)
|
98
|
-
@user = user
|
99
|
-
end
|
100
|
-
|
101
|
-
attr_reader :user
|
102
|
-
|
103
|
-
def self.published
|
104
|
-
:published
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.read
|
108
|
-
:read
|
109
|
-
end
|
110
|
-
|
111
|
-
def to_s
|
112
|
-
"Post"
|
113
|
-
end
|
114
|
-
|
115
|
-
def inspect
|
116
|
-
"#<Post>"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
module Customer
|
121
|
-
class Post < ::Post
|
122
|
-
def model_name
|
123
|
-
OpenStruct.new(param_key: "customer_post")
|
124
|
-
end
|
125
|
-
|
126
|
-
def self.policy_class
|
127
|
-
PostPolicy
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
class CommentScope
|
133
|
-
attr_reader :original_object
|
134
|
-
|
135
|
-
def initialize(original_object)
|
136
|
-
@original_object = original_object
|
137
|
-
end
|
138
|
-
|
139
|
-
def ==(other)
|
140
|
-
original_object == other.original_object
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
class CommentPolicy < BasePolicy
|
145
|
-
class Scope < BaseScope
|
146
|
-
def resolve
|
147
|
-
CommentScope.new(scope)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
alias comment record
|
152
|
-
end
|
153
|
-
|
154
|
-
class PublicationPolicy < BasePolicy
|
155
|
-
class Scope < BaseScope
|
156
|
-
def resolve
|
157
|
-
scope.published
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def create?
|
162
|
-
true
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
class Comment
|
167
|
-
extend ActiveModel::Naming
|
168
|
-
end
|
169
|
-
|
170
|
-
class CommentsRelation
|
171
|
-
def initialize(empty: false)
|
172
|
-
@empty = empty
|
173
|
-
end
|
174
|
-
|
175
|
-
def blank?
|
176
|
-
@empty
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.model_name
|
180
|
-
Comment.model_name
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
class Article; end
|
185
|
-
|
186
|
-
class BlogPolicy < BasePolicy
|
187
|
-
alias blog record
|
188
|
-
end
|
189
|
-
|
190
|
-
class Blog; end
|
191
|
-
|
192
|
-
class ArtificialBlog < Blog
|
193
|
-
def self.policy_class
|
194
|
-
BlogPolicy
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
class ArticleTagOtherNamePolicy < BasePolicy
|
199
|
-
def show?
|
200
|
-
true
|
201
|
-
end
|
202
|
-
|
203
|
-
def destroy?
|
204
|
-
false
|
205
|
-
end
|
206
|
-
|
207
|
-
alias tag record
|
208
|
-
end
|
209
|
-
|
210
|
-
class ArticleTag
|
211
|
-
def self.policy_class
|
212
|
-
ArticleTagOtherNamePolicy
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
class CriteriaPolicy < BasePolicy
|
217
|
-
alias criteria record
|
218
|
-
end
|
219
|
-
|
220
|
-
module Project
|
221
|
-
class CommentPolicy < BasePolicy
|
222
|
-
class Scope < BaseScope
|
223
|
-
def resolve
|
224
|
-
scope
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def update?
|
229
|
-
true
|
230
|
-
end
|
231
|
-
|
232
|
-
alias comment record
|
233
|
-
end
|
234
|
-
|
235
|
-
class CriteriaPolicy < BasePolicy
|
236
|
-
alias criteria record
|
237
|
-
end
|
238
|
-
|
239
|
-
class PostPolicy < BasePolicy
|
240
|
-
class Scope < BaseScope
|
241
|
-
def resolve
|
242
|
-
scope.read
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
alias post record
|
247
|
-
end
|
248
|
-
|
249
|
-
module Admin
|
250
|
-
class CommentPolicy < BasePolicy
|
251
|
-
def update?
|
252
|
-
true
|
253
|
-
end
|
254
|
-
|
255
|
-
def destroy?
|
256
|
-
false
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
class DenierPolicy < BasePolicy
|
263
|
-
def update?
|
264
|
-
false
|
265
|
-
end
|
266
|
-
end
|
267
27
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
def initialize(current_user, action_name, params)
|
278
|
-
@current_user = current_user
|
279
|
-
@action_name = action_name
|
280
|
-
@params = params
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
class NilClassPolicy < BasePolicy
|
285
|
-
class Scope
|
286
|
-
def initialize(*)
|
287
|
-
raise Pundit::NotDefinedError, "Cannot scope NilClass"
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
def show?
|
292
|
-
false
|
293
|
-
end
|
294
|
-
|
295
|
-
def destroy?
|
296
|
-
false
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
class Wiki; end
|
301
|
-
|
302
|
-
class WikiPolicy
|
303
|
-
class Scope
|
304
|
-
# deliberate typo method
|
305
|
-
def initalize; end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
class Thread
|
310
|
-
def self.all; end
|
311
|
-
end
|
312
|
-
|
313
|
-
class ThreadPolicy < BasePolicy
|
314
|
-
class Scope < BaseScope
|
315
|
-
def resolve
|
316
|
-
# deliberate wrong useage of the method
|
317
|
-
scope.all(:unvalid, :parameters)
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
class PostFourFiveSix
|
323
|
-
def initialize(user)
|
324
|
-
@user = user
|
325
|
-
end
|
326
|
-
|
327
|
-
attr_reader(:user)
|
328
|
-
end
|
329
|
-
|
330
|
-
class CommentFourFiveSix; extend ActiveModel::Naming; end
|
331
|
-
|
332
|
-
module ProjectOneTwoThree
|
333
|
-
class CommentFourFiveSixPolicy < BasePolicy; end
|
334
|
-
|
335
|
-
class CriteriaFourFiveSixPolicy < BasePolicy; end
|
336
|
-
|
337
|
-
class PostFourFiveSixPolicy < BasePolicy; end
|
338
|
-
|
339
|
-
class TagFourFiveSix
|
340
|
-
def initialize(user)
|
341
|
-
@user = user
|
342
|
-
end
|
343
|
-
|
344
|
-
attr_reader(:user)
|
345
|
-
end
|
346
|
-
|
347
|
-
class TagFourFiveSixPolicy < BasePolicy; end
|
348
|
-
|
349
|
-
class AvatarFourFiveSix; extend ActiveModel::Naming; end
|
350
|
-
|
351
|
-
class AvatarFourFiveSixPolicy < BasePolicy; end
|
352
|
-
end
|
28
|
+
# Load all supporting files: models, policies, etc.
|
29
|
+
require "zeitwerk"
|
30
|
+
loader = Zeitwerk::Loader.new
|
31
|
+
loader.push_dir(File.expand_path("support/models", __dir__))
|
32
|
+
loader.push_dir(File.expand_path("support/policies", __dir__))
|
33
|
+
loader.push_dir(File.expand_path("support/lib", __dir__))
|
34
|
+
loader.setup
|
35
|
+
loader.eager_load
|